/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
// }
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
;
/*
declare class console {
    static log(...args : any[]) : void;
    static info(...args : any[]) : void;
    static warn(...args : any[]) : void;
    static error(...args : any[]) : void;
};
 */
var lib_plankton;
(function (lib_plankton) {
    var base;
    (function (base) {
        /**
         * @author fenris
         */
        function environment() {
            return "web";
        }
        base.environment = environment;
    })(base = lib_plankton.base || (lib_plankton.base = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
/*export*/ function pseudopointer_null() {
    return {
        "value": null
    };
}
/**
 * @author fenris
 */
/*export*/ function pseudopointer_make(value) {
    return {
        "value": value
    };
}
/**
 * @author fenris
 */
/*export*/ function pseudopointer_isset(pseudopointer) {
    return (pseudopointer.value != null);
}
/**
 * @author fenris
 */
/*export*/ function pseudopointer_read(pseudopointer) {
    if (pseudopointer.value != null) {
        return pseudopointer.value;
    }
    else {
        let message = `nullpointer dereferencation`;
        throw (new Error(message));
    }
}
/**
 * @author fenris
 */
/*export*/ function pseudopointer_write(pseudopointer, value) {
    pseudopointer.value = value;
}
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var instance_verbosity = 0;
/**
 * @author fenris
 */
function instance_collate(value1, value2) {
    if (typeof (value1) === "object") {
        if (value1 == null) {
            return (value2 == null);
        }
        else {
            if ("_collate" in value1) {
                return value1["_collate"](value2);
            }
            else {
                throw (new Error("[collate]" + " " + "object has no such method"));
            }
        }
    }
    else {
        if (instance_verbosity >= 1) {
            // lib_plankton.log.warn("[collate]" + " " + "primitive value; using default implementation");
        }
        return (value1 === value2);
    }
}
/**
 * @author fenris
 */
function instance_compare(value1, value2) {
    if (typeof (value1) === "object") {
        if ("_compare" in value1) {
            return value1["_compare"](value2);
        }
        else {
            throw (new Error("[compare]" + " " + "object has no such method"));
        }
    }
    else {
        if (instance_verbosity >= 1) {
            // lib_plankton.log.warn("[compare]" + " " + "primitive value; using default implementation");
        }
        return (value1 <= value2);
    }
}
/**
 * @author fenris
 */
function instance_clone(value) {
    if (typeof (value) === "object") {
        if ("_clone" in value) {
            return value["_clone"]();
        }
        else {
            throw (new Error("[clone]" + " " + "object has no such method"));
        }
    }
    else {
        if (instance_verbosity >= 1) {
            // lib_plankton.log.warn("[clone]" + " " + "primitive value; using default implementation");
        }
        return value;
    }
}
/**
 * @desc the ability to generate a string out of the element, which identifies it to a high degree
 * @author fenris
 */
function instance_hash(value) {
    if (typeof (value) === "object") {
        if ("_hash" in value) {
            return value["_hash"]();
        }
        else {
            throw (new Error("[hash]" + " " + "object has no such method"));
        }
    }
    else {
        if (instance_verbosity >= 1) {
            // lib_plankton.log.warn("[hash]" + " " + "primitive value; using default implementation");
        }
        return String(value);
    }
}
/**
 * @desc the ability to map the element to a textual representation (most likely not injective)
 * @author fenris
 */
function instance_show(value) {
    if (typeof (value) === "object") {
        if (value == null) {
            return "NULL";
        }
        else {
            if ("_show" in value) {
                return value["_show"]();
            }
            else {
                // throw (new Error("[show]" + " " + "object has no such method"));
                return JSON.stringify(value);
            }
        }
    }
    else {
        if (instance_verbosity >= 1) {
            // lib_plankton.log.warn("[show]" + " " + "primitive value; using default implementation");
        }
        return String(value);
    }
}
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author frac
 */
class class_observer {
    /**
     * @author frac
     */
    constructor() {
        this.counter = 0;
        this.actions = {};
        this.buffer = [];
    }
    /**
     * @author frac
     */
    empty() {
        return (Object.keys(this.actions).length == 0);
    }
    /**
     * @author frac
     */
    flush() {
        this.actions = {};
    }
    /**
     * @author frac
     */
    set(id, action) {
        this.actions[id] = action;
    }
    /**
     * @author frac
     */
    del(id) {
        delete this.actions[id];
    }
    /**
     * @author frac
     */
    add(action) {
        this.set((this.counter++).toString(), action);
    }
    /**
     * @author frac
     */
    notify(information = {}, delayed = false) {
        if (delayed) {
            this.buffer.push(information);
        }
        else {
            Object.keys(this.actions).forEach(id => this.actions[id](information));
        }
    }
    /**
     * @author frac
     */
    rollout() {
        this.buffer.forEach(information => this.notify(information, false));
        this.buffer = [];
    }
}
/**
 * @author frac
 */
/*
export interface interface_readable<type_value> {

    |**
     * @author frac
     *|
    read() : type_executor<type_value, Error>;

}
 */
/**
 * @author frac
 */
/*
export interface interface_writeable<type_value> {

    |**
     * @author frac
     *|
    write(value : type_value) : type_executor<void, Error>;

}
 */
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author frac
 */
class class_error extends Error {
    /**
     * @author frac
     */
    constructor(message, suberrors = []) {
        super(message);
        this.suberrors = suberrors;
        this.mess = message;
    }
    /**
     * @override
     * @author frac
     */
    toString() {
        return ( /*super.toString()*/this.mess + " " + ("[" + this.suberrors.map(x => x.toString()).join(",") + "]"));
    }
}
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:base«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var base;
    (function (base) {
        /**
         * returns the current UNIX timestamp
         *
         * @author fenris
         */
        function get_current_timestamp(rounded = false) {
            const x = (Date.now() / 1000);
            return (rounded ? Math.round(x) : x);
            ;
        }
        base.get_current_timestamp = get_current_timestamp;
        /**
         */
        function object_merge(core, mantle) {
            return Object.assign(core, mantle);
        }
        base.object_merge = object_merge;
        /**
         */
        function buffer_show(buffer, { "block_size": option_block_size = 20, "break_char": option_break_char = "\n", "render_readable_characters": render_readable_characters = true, } = {}) {
            function is_readable(code) {
                return ((code > 0x20)
                    &&
                        (code <= 0x7E));
            }
            let output = "";
            let count = 0;
            // @ts-ignore
            for (const entry of buffer) {
                count = ((count + 1) % option_block_size);
                /*
                 */
                const code = ((typeof (entry) === "string")
                    ?
                        entry.charCodeAt(0)
                    :
                        entry);
                output += ((render_readable_characters
                    &&
                        is_readable(code))
                    ?
                        String.fromCharCode(code)
                    :
                        ("[" + code.toString(16).toUpperCase().padStart(2, "0") + "]"));
                output += ((count === 0) ? option_break_char : "");
            }
            return output;
        }
        base.buffer_show = buffer_show;
    })(base = lib_plankton.base || (lib_plankton.base = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pod«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pod« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pod« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pod«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var pod;
    (function (pod_1) {
        /**
         * @author fenris
         */
        function make_empty() {
            return {
                "kind": "empty"
            };
        }
        pod_1.make_empty = make_empty;
        /**
         * @author fenris
         */
        function make_filled(value) {
            return {
                "kind": "filled",
                "value": value
            };
        }
        pod_1.make_filled = make_filled;
        /**
         * whether the pod is filled
         *
         * @author fenris
         */
        function is_filled(pod) {
            return (pod.kind === "filled");
        }
        pod_1.is_filled = is_filled;
        /**
         * return the value, stored in the pod-wrapper
         *
         * @author fenris
         */
        function cull(pod) {
            if (!is_filled(pod)) {
                throw (new Error("cull from empty"));
            }
            else {
                return pod.value;
            }
        }
        pod_1.cull = cull;
        /**
         * to pass on a empty-pod or to use a filled-pod
         *
         * @author fenris
         */
        function propagate(pod, function_) {
            if (!is_filled(pod)) {
                return make_empty();
            }
            else {
                return make_filled(function_(pod.value));
            }
        }
        pod_1.propagate = propagate;
        /**
         * @author fenris
         */
        function distinguish(pod, function_empty, function_filled) {
            return ((!is_filled(pod))
                ? function_empty()
                : function_filled(pod.value));
        }
        pod_1.distinguish = distinguish;
        /**
         */
        function show(pod, options = {}) {
            options = Object.assign({
                "show_value": value => String(value),
            }, options);
            if (!is_filled(pod)) {
                return "<·>";
            }
            else {
                return ("<- " + options.show_value(pod.value) + " ->");
            }
        }
        pod_1.show = show;
    })(pod = lib_plankton.pod || (lib_plankton.pod = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pod«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pod« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pod« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pod«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var pod;
    (function (pod) {
        /**
         */
        class class_pod {
            constructor(subject) { this.subject = subject; }
            tear() { return this.subject; }
            static empty() { return (new class_pod(pod.make_empty())); }
            static filled(value) { return (new class_pod(pod.make_filled(value))); }
            is_empty() { return (!pod.is_filled(this.subject)); }
            is_filled() { return pod.is_filled(this.subject); }
            cull() { return pod.cull(this.subject); }
            show(show_value = undefined) { return pod.show(this.subject, show_value); }
            toString() { return this.show(); }
            propagate(function_) { return new class_pod(pod.propagate(this.subject, function_)); }
            distinguish(function_empty, function_filled) { return pod.distinguish(this.subject, function_empty, function_filled); }
        }
        pod.class_pod = class_pod;
    })(pod = lib_plankton.pod || (lib_plankton.pod = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        function inverse_encode(decode, to) {
            return decode(to);
        }
        code.inverse_encode = inverse_encode;
        /**
         * @author fenris
         */
        function inverse_decode(encode, from) {
            return encode(from);
        }
        code.inverse_decode = inverse_decode;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        var class_code_inverse = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_code_inverse(subject) {
                this.subject = subject;
            }
            /**
             * @implementation
             * @author fenris
             */
            class_code_inverse.prototype.encode = function (to) {
                var _this = this;
                return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to);
            };
            /**
             * @implementation
             * @author fenris
             */
            class_code_inverse.prototype.decode = function (from) {
                var _this = this;
                return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from);
            };
            return class_code_inverse;
        }());
        code.class_code_inverse = class_code_inverse;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        function pair_encode(encode_first, encode_second, from) {
            var between = encode_first(from);
            var to = encode_second(between);
            return to;
        }
        code.pair_encode = pair_encode;
        /**
         * @author fenris
         */
        function pair_decode(decode_first, decode_second, to) {
            var between = decode_second(to);
            var from = decode_first(between);
            return from;
        }
        code.pair_decode = pair_decode;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        var class_code_pair = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_code_pair(first, second) {
                this.first = first;
                this.second = second;
            }
            /**
             * @implementation
             * @author fenris
             */
            class_code_pair.prototype.encode = function (from) {
                var _this = this;
                return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from);
            };
            /**
             * @implementation
             * @author fenris
             */
            class_code_pair.prototype.decode = function (to) {
                var _this = this;
                return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to);
            };
            return class_code_pair;
        }());
        code.class_code_pair = class_code_pair;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        function chain_encode(encode_links, from) {
            var value = from;
            encode_links
                .forEach(function (link) {
                value = link(value);
            });
            return value;
        }
        code.chain_encode = chain_encode;
        /**
         * @author fenris
         */
        function chain_decode(decode_links, to) {
            var value = to;
            decode_links
                .reverse()
                .forEach(function (link) {
                value = link(value);
            });
            return value;
        }
        code.chain_decode = chain_decode;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        var class_code_chain = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_code_chain(links) {
                this.links = links;
            }
            /**
             * @implementation
             * @author fenris
             */
            class_code_chain.prototype.encode = function (from) {
                return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from);
            };
            /**
             * @implementation
             * @author fenris
             */
            class_code_chain.prototype.decode = function (to) {
                return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to);
            };
            return class_code_chain;
        }());
        code.class_code_chain = class_code_chain;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author Christian Fraß <frass@greenscale.de>
         */
        function flatten_encode(from, keys) {
            if (keys === void 0) { keys = null; }
            if (keys === null) {
                if (from.length > 0) {
                    keys = Object.keys(from[0]);
                }
                else {
                    throw (new Error("encoding impossible"));
                }
            }
            return {
                "keys": keys,
                "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); })
            };
        }
        code.flatten_encode = flatten_encode;
        /**
         * @author Christian Fraß <frass@greenscale.de>
         */
        function flatten_decode(to) {
            return (to.data
                .map(function (dataset) {
                var dataset_ = {};
                dataset
                    .forEach(function (value, index) {
                    var name = to.keys[index];
                    dataset_[name] = value;
                });
                return dataset_;
            }));
        }
        code.flatten_decode = flatten_decode;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:code« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:code« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:code«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var code;
    (function (code) {
        /**
         * @author fenris
         */
        var class_code_flatten = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_code_flatten() {
            }
            /**
             * @implementation
             * @author fenris
             */
            class_code_flatten.prototype.encode = function (x) {
                return code.flatten_encode(x);
            };
            /**
             * @implementation
             * @author fenris
             */
            class_code_flatten.prototype.decode = function (x) {
                return code.flatten_decode(x);
            };
            return class_code_flatten;
        }());
        code.class_code_flatten = class_code_flatten;
    })(code = lib_plankton.code || (lib_plankton.code = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:json«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:json« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:json« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:json«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var json;
    (function (json) {
        /**
         * @author fenris
         */
        function encode(source, options = {}) {
            options = Object.assign({
                "formatted": false,
            }, options);
            return JSON.stringify(source, undefined, (options.formatted ? "\t" : undefined));
        }
        json.encode = encode;
        /**
         * @author fenris
         */
        function decode(target) {
            return JSON.parse(target);
        }
        json.decode = decode;
        /**
         * @author fenris
         */
        function implementation_code() {
            return {
                "encode": x => encode(x),
                "decode": decode,
            };
        }
        json.implementation_code = implementation_code;
    })(json = lib_plankton.json || (lib_plankton.json = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:json«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:json« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:json« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:json«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var json;
    (function (json) {
        /**
         * @author fenris
         */
        class class_json {
            /**
             * @author fenris
             */
            constructor() {
            }
            /**
             * @implementation
             * @author fenris
             */
            encode(x) {
                return json.encode(x);
            }
            /**
             * @implementation
             * @author fenris
             */
            decode(x) {
                return json.decode(x);
            }
        }
        json.class_json = class_json;
    })(json = lib_plankton.json || (lib_plankton.json = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * might be completely obsolete
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /**
         * @author fenris
         */
        function promise_reject(reason) {
            return Promise.reject(reason);
        }
        call.promise_reject = promise_reject;
        /**
         * @author fenris
         */
        function promise_resolve(result) {
            return Promise.resolve(result);
        }
        call.promise_resolve = promise_resolve;
        /**
         * @author fenris
         */
        function promise_make(executor) {
            return (new Promise(executor));
        }
        call.promise_make = promise_make;
        /**
         * @author fenris
         */
        function promise_then_close(promise, resolver, rejector) {
            promise.then(resolver, rejector);
        }
        call.promise_then_close = promise_then_close;
        /**
         * @author fenris
         */
        function promise_then_append(promise, resolver, rejector = null) {
            if (rejector == null) {
                rejector = (reason) => promise_reject(reason);
            }
            return (promise.then(resolver, rejector));
        }
        call.promise_then_append = promise_then_append;
        /**
         * @author fenris
         */
        function promise_all(promises) {
            return Promise.all(promises);
        }
        call.promise_all = promise_all;
        /**
         * @author fenris
         */
        function promise_chain(promises, start = undefined) {
            return (promises.reduce((chain, promise) => promise_then_append(chain, promise), promise_resolve(start)));
        }
        call.promise_chain = promise_chain;
        /**
         * @author fenris
         */
        function promise_condense(promises) {
            return (promise_chain(promises.map(promise => result => promise_then_append(promise(), element => promise_resolve(result.concat([element])))), []));
        }
        call.promise_condense = promise_condense;
        /**
         * @author fenris
         */
        function promise_group(promises, options = {
            "serial": false,
        }) {
            const decorate = function (promise, name) {
                return (() => promise_then_append(promise(), value => promise_resolve({ "key": name, "value": value })));
            };
            if (options.serial) {
                return (promise_then_append(promise_condense(Object.keys(promises)
                    .map(name => decorate(promises[name], name))), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value]))))));
            }
            else {
                return (promise_then_append(promise_all(Object.keys(promises)
                    .map(name => decorate(promises[name], name))
                    .map(promise => promise())), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value]))))));
            }
        }
        call.promise_group = promise_group;
        /**
         * @author fenris
         */
        function promise_wrap(promise, transformator_result, transformator_reason = lib_plankton.call.id) {
            return (promise_make((resolve, reject) => {
                promise_then_close(promise, result => resolve(transformator_result(result)), reason => reject(transformator_reason(reason)));
            }));
        }
        call.promise_wrap = promise_wrap;
        /**
         * @author fenris
         */
        /*
        export function promise_show<type_result, type_reason>(label : string) : (result : type_result)=>type_promise<type_result, type_reason> {
            return (
                result => promise_make<type_result, type_reason>(
                    (resolve, reject) => {
                        // lib_plankton.log.info(label + ": " + instance_show(result));
                        process.stdout.write(label + ": " + instance_show(result));
                        resolve(result);
                    }
                )
            );
        }
         */
        /**
         * @author fenris
         */
        /*
        export function promise_log<type_result, type_reason>(result : type_result) : (result : type_result)=>type_promise<type_result, type_reason> {
            return promise_show<type_result, type_reason>("log");
        }
         */
        /**
         * @author fenris
         */
        function promise_attach(state, promise, name) {
            return (promise_wrap(promise, result => {
                state[name] = result;
                return state;
            }));
        }
        call.promise_attach = promise_attach;
        /**
         * @author fenris
         */
        function promise_delay(promise, delay) {
            return promise_make((resolve, reject) => {
                call.timeout(() => {
                    promise_then_close(promise, resolve, reject);
                    return null;
                }, delay);
            });
        }
        call.promise_delay = promise_delay;
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * initializer might be obsolete, since promises are reusable after having been resolved or rejected
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /**
         * @author fenris
         */
        let enum_initializer_state;
        (function (enum_initializer_state) {
            enum_initializer_state[enum_initializer_state["initial"] = 0] = "initial";
            enum_initializer_state[enum_initializer_state["waiting"] = 1] = "waiting";
            enum_initializer_state[enum_initializer_state["successful"] = 2] = "successful";
            enum_initializer_state[enum_initializer_state["failed"] = 3] = "failed";
        })(enum_initializer_state = call.enum_initializer_state || (call.enum_initializer_state = {}));
        /**
         * @author fenris
         */
        function initializer_make(fetcher) {
            let subject = {
                "fetcher": fetcher,
                "state": enum_initializer_state.initial,
                "queue": [],
                "result": undefined,
                "reason": undefined,
            };
            return subject;
        }
        call.initializer_make = initializer_make;
        /**
         * @author fenris
         */
        function initializer_actuate(subject) {
            switch (subject.state) {
                case enum_initializer_state.successful: {
                    subject.queue.forEach(entry => entry.resolve(subject.result));
                    break;
                }
                case enum_initializer_state.failed: {
                    subject.queue.forEach(entry => entry.reject(subject.reason));
                    break;
                }
                default: {
                    throw (new Error(`unhandled state ${subject.state}`));
                    break;
                }
            }
        }
        /**
         * @author fenris
         */
        function initializer_reset(subject) {
            subject.state = enum_initializer_state.initial;
            subject.queue = [];
        }
        call.initializer_reset = initializer_reset;
        /**
         * @author fenris
         */
        function initializer_state(subject) {
            return subject.state;
        }
        call.initializer_state = initializer_state;
        /**
         * @author fenris
         */
        function initializer_get(subject) {
            switch (subject.state) {
                case enum_initializer_state.initial: {
                    subject.state = enum_initializer_state.waiting;
                    return (call.promise_make((resolve, reject) => {
                        subject.queue.push({ "resolve": resolve, "reject": reject });
                        subject.fetcher().then(result => {
                            subject.state = enum_initializer_state.successful;
                            subject.result = result;
                            initializer_actuate(subject);
                        }, reason => {
                            subject.state = enum_initializer_state.failed;
                            subject.reason = reason;
                            initializer_actuate(subject);
                        });
                    }));
                    break;
                }
                case enum_initializer_state.waiting: {
                    return (call.promise_make((resolve, reject) => {
                        subject.queue.push({ "resolve": resolve, "reject": reject });
                    }));
                    break;
                }
                case enum_initializer_state.successful: {
                    return (call.promise_resolve(subject.result));
                    break;
                }
                case enum_initializer_state.failed: {
                    return (call.promise_reject(subject.reason));
                    break;
                }
                default: {
                    throw (new Error(`unhandled state ${subject.state}`));
                    break;
                }
            }
        }
        call.initializer_get = initializer_get;
        /**
         * @author fenris
         */
        function initializer_get_sync(subject) {
            switch (subject.state) {
                case enum_initializer_state.successful: {
                    return subject.result;
                    break;
                }
                case enum_initializer_state.failed: {
                    throw subject.reason;
                    break;
                }
                default: {
                    throw (new Error(`unhandled state ${subject.state}`));
                    break;
                }
            }
        }
        /**
         * @author fenris
         */
        function initializer_set_sync(subject, result) {
            switch (subject.state) {
                case enum_initializer_state.successful: {
                    subject.result = result;
                    break;
                }
                case enum_initializer_state.failed: {
                    subject.state = enum_initializer_state.successful;
                    subject.result = result;
                    break;
                }
                default: {
                    throw (new Error(`unhandled state ${subject.state}`));
                    break;
                }
            }
        }
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /*
            The core idea of this library is to provide means for asynchronous program flow. The old-school way to do is,
            is to use callbacks. While this approach is simple and easy to understand, it has some disadvantages. As an
            attempt to relief and improve this, the promise-system was introduced. In principle it solves most of the
            problems found in the callback-approach; however it has some downsides as well:
                
            - Convolution of multiple principles
                Promises unite the ideas of asynchronous program flow and error handling.
            
            - Instant execution
                Creating a promise results in the instant execution of the given executor prodecure. While this might be
                convenient in some cases, it can be quite disturbing and counter-intuitive in others.
            
            - Broken typing
                The Promise system doesn't distinguish between an appending "then" (i.e. passing a function, which returns a
                new promise) and a closing "then" (i.e. passing a function, which has no return value). On top of that it
                allows returning simple values in an appending "then", which results in an implicit call of the executors
                "resolve"-function. The price for these "pragmatic" features is that the whole system can't be typed well.
                And even though JavaScript is not a strictly typed language, it was a quite questionable decision to design
                the promise system in a way, which breaks typing from the start.
            
            The deferral-system forseeks to solve these issues while retaining the advantages of the promise-system.
         */
        /**
         * @author fenris
         * @desc activates the deferral and handles its output according to a given procedure
         * @param {(value : type_value)=>void} procedure a function which receives the output of the deferral as argument
         */
        function deferral_use(deferral, input, procedure) {
            deferral.representation(input).then(value => {
                procedure(value);
            }, reason => {
                throw reason;
            });
        }
        call.deferral_use = deferral_use;
        /**
         * @author fenris
         * @desc creates a deferral-subject (similar to "new Promise", where "convey" reflects "resolve"/"reject")
         */
        function deferral_make(handler) {
            return ({
                "representation": ((input) => (new Promise((resolve, reject) => {
                    handler(input, resolve);
                })))
            });
        }
        call.deferral_make = deferral_make;
        /**
         * @author fenris
         * @desc wraps a simple function into a deferral (similar to "Promise.resolve"/"Promise.reject")
         */
        function deferral_wrap(function_) {
            return (deferral_make((input, convey) => convey(function_(input))));
        }
        call.deferral_wrap = deferral_wrap;
        /**
         * @author fenris
         */
        function deferral_id() {
            return (deferral_make((input, convey) => convey(input)));
        }
        call.deferral_id = deferral_id;
        /**
         * @author fenris
         */
        function deferral_const(value) {
            return (deferral_make((input, convey) => convey(value)));
        }
        call.deferral_const = deferral_const;
        /**
         * @author fenris
         */
        function deferral_delay(output, delay) {
            return (deferral_make((input, convey) => {
                setTimeout(() => convey(output), delay);
            }));
        }
        call.deferral_delay = deferral_delay;
        /**
         * @author fenris
         * @desc connects two deferrals to form a new one; the output of the first is taken as input for the second
         *     (similar to "Promise.then" when passing a function which returns a new promise)
         * @param {type_deferral<type_value1>} first a simple deferral
         * @param {(value1 : type_value1)=>type_deferral<type_value2>} second a function depending from a value returning a deferral
         */
        function deferral_compose_serial(first, second) {
            return {
                "representation": ((input) => first.representation(input).then((between) => second.representation(between)))
            };
        }
        call.deferral_compose_serial = deferral_compose_serial;
        /**
         * @author fenris
         */
        function deferral_compose_parallel({ "left": deferral_left, "right": deferral_right, }) {
            return (deferral_make((input, convey) => {
                let object = {
                    "left": lib_plankton.pod.make_empty(),
                    "right": lib_plankton.pod.make_empty(),
                };
                let finish = function () {
                    if (lib_plankton.pod.is_filled(object.left)
                        &&
                            lib_plankton.pod.is_filled(object.right)) {
                        let result = {
                            "left": lib_plankton.pod.cull(object.left),
                            "right": lib_plankton.pod.cull(object.right),
                        };
                        convey(result);
                    }
                    else {
                        // do nothing
                    }
                };
                deferral_use(deferral_left, input, output_left => {
                    object.left = lib_plankton.pod.make_filled(output_left);
                    finish();
                });
                deferral_use(deferral_right, input, output_right => {
                    object.right = lib_plankton.pod.make_filled(output_right);
                    finish();
                });
            }));
        }
        call.deferral_compose_parallel = deferral_compose_parallel;
        /**
         * @author fenris
         * @desc repeatedly applied serial composition
         */
        function deferral_chain(members) {
            return (members.reduce(
            // (result, current) => deferral_compose_serial<type_value, type_value, type_value>(result, current),
            deferral_compose_serial, deferral_id()));
        }
        call.deferral_chain = deferral_chain;
        /**
         * @author fenris
         */
        /*
        export function deferral_bunch<type_input, type_output>(
            members : {[name : string] : type_deferral<type_input, type_output>}
        ) : type_deferral<type_input, {[name : string] : type_output}> {
            
        }
         */
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /**
         * @author fenris
         */
        class class_deferral {
            /**
             * @author fenris
             */
            constructor(subject) {
                this.subject = subject;
            }
            /**
             * @author fenris
             */
            static _cram(subject) {
                return (new class_deferral(subject));
            }
            /**
             * @author fenris
             */
            static _tear(instance) {
                return instance.subject;
            }
            /**
             * @author fenris
             */
            static make(handler) {
                return (class_deferral._cram(call.deferral_make(handler)));
            }
            /**
             * @author fenris
             */
            use(input, procedure) {
                return (call.deferral_use(class_deferral._tear(this), input, procedure));
            }
            /**
             * @author fenris
             */
            compose_serial(second) {
                return (class_deferral._cram(call.deferral_compose_serial(class_deferral._tear(this), class_deferral._tear(second))));
            }
            /**
             * @author fenris
             */
            static chain(members) {
                return (class_deferral._cram(call.deferral_chain(members.map(member => class_deferral._tear(member)))));
            }
            /**
             * @author fenris
             */
            static wrap(function_) {
                return (class_deferral._cram(call.deferral_wrap(function_)));
            }
            /**
             * @author fenris
             */
            static const_(value) {
                return (class_deferral._cram(call.deferral_const(value)));
            }
            /**
             * @author fenris
             */
            static delay(output, delay) {
                return (class_deferral._cram(call.deferral_delay(output, delay)));
            }
        }
        call.class_deferral = class_deferral;
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /**
         * converts the "arguments"-map into an array
         *
         * @param {Object} args
         * @author fenris
         */
        function args2list(args) {
            return Object.keys(args).map(key => args[key]);
        }
        call.args2list = args2list;
        /**
         * just the empty function; useful for some callbacks etc.
         *
         * @author fenris
         */
        function nothing() {
        }
        call.nothing = nothing;
        /**
         * just the identity; useful for some callbacks etc.; defined as function instead of const for using type parameters
         *
         * @author fenris
         */
        function id(x) {
            return x;
        }
        call.id = id;
        /**
         * just the identity; useful for some callbacks etc.
         *
         * @author fenris
         */
        function const_(x) {
            return (y => x);
        }
        call.const_ = const_;
        /**
         * composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions)
         *
         * @param {function} function_f
         * @param {function} function_g
         * @author fenris
         */
        function compose(function_f, function_g) {
            return (function (x) {
                // return function_g(function_f(x));
                return function_g(function_f.apply(function_f, args2list(arguments)));
            });
        }
        call.compose = compose;
        /**
         * @author fenris
         */
        function curryfy_real(f, n) {
            switch (n) {
                case 0: {
                    throw (new Error("[curryfy] impossible"));
                    // break;
                }
                case 1: {
                    return f;
                    // break;
                }
                default: {
                    return (function (x) {
                        return (curryfy_real(function () { return f.apply(f, [x].concat(args2list(arguments))); }, n - 1));
                    });
                    // break;
                }
            }
        }
        /**
         * transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
         *
         * @param {function} f
         * @return {function} the currified version of the in put function
         * @author fenris
         */
        function curryfy(f) {
            return curryfy_real(f, f.length);
        }
        call.curryfy = curryfy;
        /**
         * @author fenris
         */
        function convey(value, functions) {
            let result = value;
            functions.forEach(function_ => {
                result = function_(result);
            });
            return result;
        }
        call.convey = convey;
        /**
         */
        class class_value_wrapper {
            /**
             */
            constructor(value) {
                this.value = value;
            }
            /**
             */
            convey(function_) {
                return (new class_value_wrapper(function_(this.value)));
            }
            /**
             */
            cull() {
                return this.value;
            }
        }
        /**
         */
        function wrap(value) {
            return (new class_value_wrapper(value));
        }
        call.wrap = wrap;
        /**
         * @author fenris
         */
        function timeout(procedure, delay_in_seconds) {
            return (
            /*window.*/ setTimeout(procedure, Math.floor(delay_in_seconds * 1000)));
        }
        call.timeout = timeout;
        /**
         * @author fenris
         */
        function loop(procedure, delay_in_seconds) {
            return (
            /*window.*/ setInterval(procedure, Math.floor(delay_in_seconds * 1000)));
        }
        call.loop = loop;
        /**
         * Promise version of "setTimeout"
         *
         * @author fenris
         */
        function defer(seconds, action) {
            return (new Promise((resolve, reject) => {
                setTimeout(() => resolve(action()), Math.floor(seconds * 1000));
            }));
        }
        call.defer = defer;
        /**
         * a definition for a value being "defined"
         *
         * @author neuc
         */
        function is_def(obj, options = {}) {
            options = Object.assign({
                "null_is_valid": false,
            }, options);
            return (!((typeof (obj) === "undefined")
                ||
                    (!options.null_is_valid && (obj === null))));
        }
        call.is_def = is_def;
        /**
         * returns the value if set and, when a type is specified, if the type is correct, if not return default_value
         *
         * @author neuc
         */
        function def_val(value, default_value, options = {}) {
            options = Object.assign({
                "type": null,
                "null_is_valid": false,
            }, options);
            if (is_def(value, { "null_is_valid": options.null_is_valid })
                &&
                    (is_def(options.type)
                        ? ((typeof (value) === options.type)
                            ||
                                ((value === null)
                                    &&
                                        options.null_is_valid))
                        : true)) {
                return value;
            }
            else {
                return default_value;
            }
        }
        call.def_val = def_val;
        ;
        /**
         * provides the call for an attribute of a class as a regular function; useful for processing lists of objects
         *
         * @param {string} name the name of the attribute
         * @return {function}
         * @author fenris
         */
        function attribute(name) {
            return (object => object[name]);
        }
        call.attribute = attribute;
        /**
         * provides a method of a class as a regular function; useful for processing lists of objects
         *
         * @param {string} name the name of the method
         * @return {function}
         * @author fenris
         */
        function method(name) {
            return (function (object) { return object[name].apply(object, args2list(arguments).slice(1)); });
        }
        call.method = method;
        /**
         * @author fenris
         */
        function distinguish(coproduct, handlers, options = {}) {
            options = Object.assign({
                "fallback": null,
            }, options);
            if (coproduct.kind in handlers) {
                const handler = handlers[coproduct.kind];
                return handler(coproduct.data);
            }
            else {
                const message = ("unhandled kind '" + coproduct.kind + "'");
                if (options.fallback !== null) {
                    console.warn(message);
                    return options.fallback(coproduct);
                }
                else {
                    throw (new Error(message));
                }
            }
        }
        call.distinguish = distinguish;
        /**
         */
        function try_catch_wrap(get_value) {
            try {
                return {
                    "value": get_value(),
                    "error": null,
                };
            }
            catch (error) {
                return {
                    "value": null,
                    "error": error,
                };
            }
        }
        call.try_catch_wrap = try_catch_wrap;
        /**
         */
        function try_catch_wrap_async(get_value) {
            return (get_value()
                .then((value) => Promise.resolve({
                "value": value,
                "error": null,
            }))
                .catch((reason) => Promise.resolve({
                "value": null,
                "error": reason,
            })));
        }
        call.try_catch_wrap_async = try_catch_wrap_async;
        /**
         */
        function sleep(seconds) {
            return (new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(undefined);
                }, Math.floor(seconds * 1000));
            }));
        }
        call.sleep = sleep;
        /**
         */
        function null_prop(value_from, function_) {
            return ((value_from === null)
                ?
                    null
                :
                    function_(value_from));
        }
        call.null_prop = null_prop;
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:call« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:call« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:call«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var call;
    (function (call) {
        /**
         */
        function queue_make(handler) {
            return {
                "handler": handler,
                "items": [],
                "busy": false,
                "paused": false,
            };
        }
        call.queue_make = queue_make;
        /**
         */
        function queue_toggle_paused(queue_subject, { "mode": mode = null, } = {}) {
            queue_subject.paused = (mode ?? (!queue_subject.paused));
            if (queue_subject.paused) {
                // do nothing
            }
            else {
                queue_process(queue_subject);
            }
        }
        call.queue_toggle_paused = queue_toggle_paused;
        /**
         */
        async function queue_process(queue_subject) {
            if (queue_subject.paused || queue_subject.busy) {
                // do nothing
            }
            else {
                if (queue_subject.items.length <= 0) {
                    // do nothing
                }
                else {
                    queue_subject.busy = true;
                    const item = queue_subject.items.shift();
                    let successful;
                    let result;
                    let reason;
                    try {
                        result = await queue_subject.handler(item.data);
                        successful = true;
                    }
                    catch (error) {
                        reason = error;
                        successful = false;
                    }
                    if (successful) {
                        item.resolve(result);
                    }
                    else {
                        item.reject(reason);
                    }
                    queue_subject.busy = false;
                    queue_process(queue_subject);
                }
            }
        }
        /**
         */
        function queue_add(queue_subject, data, resolve, reject) {
            queue_subject.items.push({
                "data": data,
                "resolve": resolve,
                "reject": reject,
            });
            queue_process(queue_subject);
        }
        call.queue_add = queue_add;
    })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:file«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:file« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:file« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:file«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var file;
    (function (file) {
        /**
         * @author fenris
         */
        function read(path) {
            return (fetch("/" + path)
                .then(function (result) { return result.text(); }));
        }
        file.read = read;
        /**
         * @author fenris
         */
        function write(path, content) {
            return Promise.reject(new Error("not implemented / not possible"));
        }
        file.write = write;
        /**
         * @author fenris
         */
        function blob_read_text(blob) {
            return (lib_plankton.call.promise_make(function (resolve, reject) {
                var reader = (new FileReader());
                reader.addEventListener("load", function (event) {
                    resolve((reader.result));
                });
                reader.addEventListener("error", function (event) {
                    reject(new Error("reading file failed"));
                });
                reader.addEventListener("abort", function (event) {
                    reject(new Error("reading file aborted"));
                });
                reader.readAsText(blob);
            }));
        }
        file.blob_read_text = blob_read_text;
        /**
         * @author fenris
         */
        function blob_read_arraybuffer(blob) {
            return (lib_plankton.call.promise_make(function (resolve, reject) {
                var reader = (new FileReader());
                reader.addEventListener("load", function (event) {
                    resolve((reader.result));
                });
                reader.addEventListener("error", function (event) {
                    reject(new Error("reading file failed"));
                });
                reader.addEventListener("abort", function (event) {
                    reject(new Error("reading file aborted"));
                });
                reader.readAsArrayBuffer(blob);
            }));
        }
        file.blob_read_arraybuffer = blob_read_arraybuffer;
        /**
         * @author fenris
         */
        function blob_read_dataurl(blob) {
            return (lib_plankton.call.promise_make(function (resolve, reject) {
                var reader = new FileReader();
                reader.addEventListener("load", function (event) {
                    resolve((reader.result));
                });
                reader.addEventListener("error", function (event) {
                    reject(new Error("reading file failed"));
                });
                reader.addEventListener("abort", function (event) {
                    reject(new Error("reading file aborted"));
                });
                reader.readAsDataURL(blob);
            }));
        }
        file.blob_read_dataurl = blob_read_dataurl;
        /**
         * @author fenris
         */
        function blob_write_text(text) {
            var blob = (new Blob([text], { "type": "text/plain" }));
            return lib_plankton.call.promise_resolve(blob);
        }
        file.blob_write_text = blob_write_text;
    })(file = lib_plankton.file || (lib_plankton.file = {}));
})(lib_plankton || (lib_plankton = {}));
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
/*
This file is part of »bacterio-plankton:email«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:email« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:email«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var email;
    (function (email) {
        /**
         */
        function send(smtp_credentials, sender, receivers, subject, content) {
            return __awaiter(this, void 0, void 0, function () {
                return __generator(this, function (_a) {
                    return [2 /*return*/, Promise.reject(new Error("not implemented"))];
                });
            });
        }
        email.send = send;
    })(email = lib_plankton.email || (lib_plankton.email = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         */
        var enum_level;
        (function (enum_level) {
            enum_level[enum_level["debug"] = 0] = "debug";
            enum_level[enum_level["info"] = 1] = "info";
            enum_level[enum_level["notice"] = 2] = "notice";
            enum_level[enum_level["warning"] = 3] = "warning";
            enum_level[enum_level["error"] = 4] = "error";
        })(enum_level = log.enum_level || (log.enum_level = {}));
        ;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         */
        function level_order(level1, level2) {
            return (level1 <= level2);
        }
        log.level_order = level_order;
        /**
         */
        function level_show(level, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["abbreviated"], option_abbreviated = _c === void 0 ? false : _c;
            if (option_abbreviated) {
                switch (level) {
                    case log.enum_level.debug: return "DBG";
                    case log.enum_level.info: return "INF";
                    case log.enum_level.notice: return "NTC";
                    case log.enum_level.warning: return "WRN";
                    case log.enum_level.error: return "ERR";
                    default: return "(unknown)";
                }
            }
            else {
                switch (level) {
                    case log.enum_level.debug: return "debug";
                    case log.enum_level.info: return "info";
                    case log.enum_level.notice: return "notice";
                    case log.enum_level.warning: return "warning";
                    case log.enum_level.error: return "error";
                    default: return "(unknown)";
                }
            }
        }
        log.level_show = level_show;
        /**
         */
        function level_decode(level_string) {
            return {
                "debug": log.enum_level.debug,
                "info": log.enum_level.info,
                "notice": log.enum_level.notice,
                "warning": log.enum_level.warning,
                "error": log.enum_level.error
            }[level_string];
        }
        log.level_decode = level_decode;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         * @todo use label
         */
        function get_logger_logic(logger_data) {
            return logger_data.map(function (channel_description) { return lib_plankton.log.get_channel_logic(channel_description); });
        }
        log.get_logger_logic = get_logger_logic;
        /**
         */
        function format_entry(format_definition, entry) {
            switch (format_definition.kind) {
                case "jsonl": {
                    var now = Date.now();
                    var timestamp = (now / 1000);
                    var datetime = (new Date(now)).toISOString();
                    return (JSON.stringify({
                        "datetime_timestamp": Math.round(timestamp),
                        "datetime_string": datetime /*.slice(0, 19)*/,
                        "level_numeric": entry.level,
                        "level_name": log.level_show(entry.level, { "abbreviated": false }),
                        "tags": entry.tags,
                        "incident": entry.incident,
                        "details": entry.details
                    }, undefined, (format_definition.data.structured
                        ?
                            "\t"
                        :
                            undefined)));
                    break;
                }
                case "human_readable": {
                    var parts = [];
                    parts.push(("<" + (new Date(Date.now())).toISOString() /*.slice(0, 19)*/ + ">"));
                    parts.push(("[" + log.level_show(entry.level, { "abbreviated": true }) + "]"));
                    for (var _i = 0, _a = entry.tags; _i < _a.length; _i++) {
                        var tag = _a[_i];
                        parts.push(("{" + tag + "}"));
                    }
                    parts.push(entry.incident);
                    (entry.details !== null) && parts.push((": " + JSON.stringify(entry.details, undefined, undefined)));
                    return (parts.join(" "));
                    break;
                }
                default: {
                    throw (new Error("unhandled format kind: " + format_definition["kind"]));
                    break;
                }
            }
        }
        log.format_entry = format_entry;
        /**
         */
        function parse_format_definition(format_definition_raw) {
            return lib_plankton.call.distinguish((format_definition_raw !== null && format_definition_raw !== void 0 ? format_definition_raw : {
                "kind": "human_readable",
                "data": {}
            }), {
                "jsonl": function (_a) {
                    var structured = _a["structured"];
                    return ({
                        "kind": "jsonl",
                        "data": {
                            "structured": (structured !== null && structured !== void 0 ? structured : false)
                        }
                    });
                },
                "human_readable": function (data_) { return ({
                    "kind": "human_readable",
                    "data": {}
                }); }
            });
        }
        log.parse_format_definition = parse_format_definition;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        var channel;
        (function (channel) {
            var filtered;
            (function (filtered) {
                /**
                 */
                function predicate_incident(substring) {
                    return (function (entry) { return entry.incident.includes(substring); });
                }
                filtered.predicate_incident = predicate_incident;
                /**
                 */
                function predicate_level(threshold) {
                    return (function (entry) { return log.level_order(threshold, entry.level); });
                }
                filtered.predicate_level = predicate_level;
                /**
                 */
                function predicate_tag(tag) {
                    return (function (entry) { return entry.tags.includes(tag); });
                }
                filtered.predicate_tag = predicate_tag;
                /**
                 * combines other predicates in disjunctive normal form
                 */
                function predicate_complex(definition) {
                    return (function (entry) { return definition.some(function (clause) { return clause.every(function (literal) { return (literal.item(entry)
                        ===
                            literal.mode); }); }); });
                }
                filtered.predicate_complex = predicate_complex;
                /**
                 */
                function send(subject, entry) {
                    if (!subject.predicate(entry)) {
                        // do nothing
                    }
                    else {
                        subject.core.send(entry);
                    }
                }
                filtered.send = send;
                /**
                 */
                function logic(subject) {
                    return {
                        "send": function (entry) { return send(subject, entry); }
                    };
                }
                filtered.logic = logic;
            })(filtered = channel.filtered || (channel.filtered = {}));
        })(channel = log.channel || (log.channel = {}));
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        var channel;
        (function (channel) {
            var minlevel;
            (function (minlevel) {
                /**
                 */
                function to_filter_subject(subject) {
                    return {
                        "core": subject.core,
                        "predicate": lib_plankton.log.channel.filtered.predicate_level(subject.threshold)
                    };
                }
                /**
                 */
                function send(subject, entry) {
                    lib_plankton.log.channel.filtered.send(to_filter_subject(subject), entry);
                }
                minlevel.send = send;
                /**
                 */
                function logic(subject) {
                    return {
                        "send": function (entry) { return send(subject, entry); }
                    };
                }
                minlevel.logic = logic;
            })(minlevel = channel.minlevel || (channel.minlevel = {}));
        })(channel = log.channel || (log.channel = {}));
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * output for writing log entries to web console
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        var channel;
        (function (channel) {
            var console_;
            (function (console_) {
                /**
                 * @todo tags
                 */
                function send(subject, entry) {
                    var _a;
                    var renderers = (_a = {},
                        _a[log.enum_level.debug] = {
                            "renderer": function (i, d) { return console.log(i, d); },
                            "show_level": true
                        },
                        _a[log.enum_level.info] = {
                            "renderer": function (i, d) { return console.info(i, d); },
                            "show_level": true
                        },
                        _a[log.enum_level.notice] = {
                            "renderer": function (i, d) { return console.warn(i, d); },
                            "show_level": true
                        },
                        _a[log.enum_level.warning] = {
                            "renderer": function (i, d) { return console.warn(i, d); },
                            "show_level": true
                        },
                        _a[log.enum_level.error] = {
                            "renderer": function (i, d) { return console.error(i, d); },
                            "show_level": true
                        },
                        _a);
                    var setting = renderers[entry.level];
                    setting.renderer(((setting.show_level
                        ? ("[" + log.level_show(entry.level) + "]" + " ")
                        : "")
                        +
                            ("" + entry.incident + "")), entry.details);
                }
                console_.send = send;
                /**
                 */
                function logic(subject) {
                    return {
                        "send": function (entry) { return send(subject, entry); }
                    };
                }
                console_.logic = logic;
            })(console_ = channel.console_ || (channel.console_ = {}));
        })(channel = log.channel || (log.channel = {}));
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         */
        function get_channel_logic(channel_description) {
            switch (channel_description.kind) {
                default: {
                    throw (new Error("unhandled log channel kind: " + channel_description.kind));
                    break;
                }
                case "filtered": {
                    return lib_plankton.log.channel.filtered.logic({
                        "core": get_channel_logic(channel_description.data.core),
                        "predicate": lib_plankton.log.channel.filtered.predicate_complex(channel_description.data.predicate.map(function (clause_raw) { return clause_raw.map(function (literal_raw) {
                            var _a;
                            return ({
                                "mode": ((_a = literal_raw["mode"]) !== null && _a !== void 0 ? _a : true),
                                "item": lib_plankton.call.distinguish(literal_raw["item"], {
                                    "incident": function (_a) {
                                        var substring = _a["substring"];
                                        if (substring === undefined) {
                                            throw (new Error("required parameter missing: substring"));
                                        }
                                        else {
                                            return lib_plankton.log.channel.filtered.predicate_incident(substring);
                                        }
                                    },
                                    "level": function (_a) {
                                        var threshold = _a["threshold"];
                                        if (threshold === undefined) {
                                            throw (new Error("required parameter missing: threshold"));
                                        }
                                        else {
                                            return lib_plankton.log.channel.filtered.predicate_level(log.level_decode(threshold));
                                        }
                                    },
                                    "tag": function (_a) {
                                        var value = _a["value"];
                                        if (value === undefined) {
                                            throw (new Error("required parameter missing: value"));
                                        }
                                        else {
                                            return lib_plankton.log.channel.filtered.predicate_tag(value);
                                        }
                                    }
                                }, {
                                    "fallback": function () { return function (entry) { return true; }; }
                                })
                            });
                        }); }))
                    });
                    break;
                }
                case "minlevel": {
                    return lib_plankton.log.channel.minlevel.logic({
                        "core": get_channel_logic(channel_description.data.core),
                        "threshold": log.level_decode(channel_description.data.threshold)
                    });
                    break;
                }
                case "console": {
                    return lib_plankton.log.channel.console_.logic({});
                    break;
                }
            }
        }
        log.get_channel_logic = get_channel_logic;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         */
        function default_logger() {
            return [
                {
                    "kind": "minlevel",
                    "data": {
                        "core": {
                            "kind": "console",
                            "data": {}
                        },
                        "threshold": "info"
                    }
                },
            ];
        }
        log.default_logger = default_logger;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:log«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:log« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:lang« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:log«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var log;
    (function (log) {
        /**
         */
        var _main_logger_data = null;
        /**
         */
        function set_main_logger(logger_data) {
            _main_logger_data = logger_data;
        }
        log.set_main_logger = set_main_logger;
        /**
         */
        function get_main_logger() {
            return (_main_logger_data !== null && _main_logger_data !== void 0 ? _main_logger_data : log.default_logger());
        }
        /**
         */
        function get_main_logger_logic() {
            return lib_plankton.log.get_logger_logic(get_main_logger());
        }
        /**
         * consumes a log entry, i.e. sends it to all channels
         */
        function send_(logger, entry) {
            logger.forEach(function (channel) { return channel.send(entry); });
        }
        log.send_ = send_;
        /**
         * [convenience]
         *
         * @todo rename to "send"
         */
        function debug_(logger, incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            send_(logger, {
                "level": log.enum_level.debug,
                "incident": incident,
                "tags": option_tags,
                "details": option_details
            });
        }
        log.debug_ = debug_;
        /**
         * [convenience]
         *
         * @todo rename to "info"
         */
        function info_(logger, incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            send_(logger, {
                "level": log.enum_level.info,
                "incident": incident,
                "tags": option_tags,
                "details": option_details
            });
        }
        log.info_ = info_;
        /**
         * [convenience]
         *
         * @todo rename to "notice"
         */
        function notice_(logger, incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            send_(logger, {
                "level": log.enum_level.notice,
                "incident": incident,
                "tags": option_tags,
                "details": option_details
            });
        }
        log.notice_ = notice_;
        /**
         * [convenience]
         *
         * @todo rename to "warning"
         */
        function warning_(logger, incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            send_(logger, {
                "level": log.enum_level.warning,
                "incident": incident,
                "tags": option_tags,
                "details": option_details
            });
        }
        log.warning_ = warning_;
        /**
         * [convenience]
         *
         * @todo rename to "error"
         */
        function error_(logger, incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            send_(logger, {
                "level": log.enum_level.error,
                "incident": incident,
                "tags": option_tags,
                "details": option_details
            });
        }
        log.error_ = error_;
        /**
         * [convenience]
         */
        function _send(entry) {
            send_(get_main_logger_logic(), entry);
        }
        log._send = _send;
        /**
         * [convenience]
         */
        function _debug(incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            debug_(get_main_logger_logic(), incident, {
                "tags": option_tags,
                "details": option_details
            });
        }
        log._debug = _debug;
        /**
         * [convenience]
         */
        function _info(incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            info_(get_main_logger_logic(), incident, {
                "tags": option_tags,
                "details": option_details
            });
        }
        log._info = _info;
        /**
         * [convenience]
         */
        function _notice(incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            notice_(get_main_logger_logic(), incident, {
                "tags": option_tags,
                "details": option_details
            });
        }
        log._notice = _notice;
        /**
         * [convenience]
         */
        function _warning(incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            warning_(get_main_logger_logic(), incident, {
                "tags": option_tags,
                "details": option_details
            });
        }
        log._warning = _warning;
        /**
         * [convenience]
         */
        function _error(incident, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["tags"], option_tags = _c === void 0 ? [] : _c, _d = _b["details"], option_details = _d === void 0 ? null : _d;
            error_(get_main_logger_logic(), incident, {
                "tags": option_tags,
                "details": option_details
            });
        }
        log._error = _error;
        /**
         * [convenience]
         *
         * @deprecated use ._debug instead!
         */
        function debug(incident, details, tags) {
            if (details === void 0) { details = null; }
            if (tags === void 0) { tags = []; }
            _debug(incident, {
                "details": details,
                "tags": tags
            });
        }
        log.debug = debug;
        /**
         * [convenience]
         *
         * @deprecated use ._info instead!
         */
        function info(incident, details, tags) {
            if (details === void 0) { details = null; }
            if (tags === void 0) { tags = []; }
            _info(incident, {
                "details": details,
                "tags": tags
            });
        }
        log.info = info;
        /**
         * [convenience]
         *
         * @deprecated use ._notice instead!
         */
        function notice(incident, details, tags) {
            if (details === void 0) { details = null; }
            if (tags === void 0) { tags = []; }
            _notice(incident, {
                "details": details,
                "tags": tags
            });
        }
        log.notice = notice;
        /**
         * [convenience]
         *
         * @deprecated use ._warning instead!
         */
        function warning(incident, details, tags) {
            if (details === void 0) { details = null; }
            if (tags === void 0) { tags = []; }
            _warning(incident, {
                "details": details,
                "tags": tags
            });
        }
        log.warning = warning;
        /**
         * [convenience]
         *
         * @deprecated use ._error instead!
         */
        function error(incident, details, tags) {
            if (details === void 0) { details = null; }
            if (tags === void 0) { tags = []; }
            _error(incident, {
                "details": details,
                "tags": tags
            });
        }
        log.error = error;
    })(log = lib_plankton.log || (lib_plankton.log = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:object«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:object« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:object« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:object«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var object;
    (function (object_1) {
        /**
         * @author fenris
         * @deprecated use the "??" operator instead
         */
        function fetch(object, fieldname, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "fallback": null,
                "escalation": 1
            }, options);
            if ((fieldname in object)
                &&
                    (object[fieldname] !== undefined)) {
                return object[fieldname];
            }
            else {
                if (!options.escalate) {
                    return options.fallback;
                }
                else {
                    throw (new Error("field '" + fieldname + "' not in structure"));
                }
            }
        }
        object_1.fetch = fetch;
        /**
         */
        function map(object_from, transformator) {
            return (Object.fromEntries(Object.entries(object_from)
                .map(function (_a) {
                var key = _a[0], value = _a[1];
                return ([key, transformator(value, key)]);
            })));
        }
        object_1.map = map;
        /**
         * gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück
         */
        function filter(object_from, predicate) {
            return (Object.fromEntries(Object.entries(object_from)
                .filter(function (_a) {
                var key = _a[0], value = _a[1];
                return predicate(value, key);
            })));
        }
        object_1.filter = filter;
        /**
         * wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um
         *
         * @deprecated use Object.fromEntries instead!
         */
        function from_array(array) {
            return (Object.fromEntries(array
                .map(function (_a) {
                var key = _a["key"], value = _a["value"];
                return ([key, value]);
            })));
        }
        object_1.from_array = from_array;
        /**
         * wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um
         *
         * @deprecated use Object.entries insetad!
         */
        function to_array(object) {
            return (Object.entries(object)
                .map(function (_a) {
                var key = _a[0], value = _a[1];
                return ({ "key": key, "value": value });
            }));
        }
        object_1.to_array = to_array;
        /**
         * gibt eine Liste von Schlüsseln eines Objekts zurück
         *
         * @deprecated use Object.keys instead!
         */
        function keys(object) {
            return Object.keys(object);
        }
        object_1.keys = keys;
        /**
         * gibt eine Liste von Werten eines Objekts zurück
         *
         * @deprecated use Object.values instead!
         */
        function values(object) {
            return Object.values(object);
        }
        object_1.values = values;
        /**
         * liest ein Baum-artiges Objekt an einer bestimmten Stelle aus
         */
        function path_read(object, path, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "fallback": null,
                "escalate": false
            }, options);
            var steps = ((path.length == 0) ? [] : path.split("."));
            if (steps.length == 0) {
                throw (new Error("empty path"));
            }
            else {
                var position_1 = object;
                var reachable = ((position_1 != null)
                    &&
                        (steps.slice(0, steps.length - 1)
                            .every(function (step) {
                            position_1 = lib_plankton.object.fetch(position_1, step, {
                                "fallback": null,
                                "escalate": false
                            });
                            return (position_1 != null);
                        })));
                if (reachable) {
                    return lib_plankton.object.fetch(position_1, steps[steps.length - 1], {
                        "fallback": options.fallback,
                        "escalate": options.escalate
                    });
                }
                else {
                    return lib_plankton.object.fetch({}, "_dummy_", {
                        "fallback": options.fallback,
                        "escalate": options.escalate
                    });
                }
            }
        }
        object_1.path_read = path_read;
        /**
         * schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt
         */
        function path_write(object, path, value, construct) {
            if (construct === void 0) { construct = true; }
            var steps = ((path.length == 0) ? [] : path.split("."));
            if (steps.length == 0) {
                throw (new Error("empty path"));
            }
            else {
                var position_2 = object;
                var reachable = steps.slice(0, steps.length - 1).every(function (step) {
                    var position_ = lib_plankton.object.fetch(position_2, step, {
                        "fallback": null,
                        "escalate": false
                    });
                    if (position_ == null) {
                        if (construct) {
                            position_2[step] = {};
                            position_2 = position_2[step];
                            return true;
                        }
                        else {
                            return false;
                        }
                    }
                    else {
                        position_2 = position_;
                        return true;
                    }
                });
                if (reachable) {
                    position_2[steps[steps.length - 1]] = value;
                }
                else {
                    throw (new Error("path '" + path + "' does not exist and may not be constructed"));
                }
            }
        }
        object_1.path_write = path_write;
        /**
         * prüft ob ein Objekt einem bestimmten Muster entspricht
         *
         * @deprecated not very useful
         */
        function matches(object, pattern, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "collate": instance_collate
            }, options);
            return (Object.entries(pattern)
                .every(function (_a) {
                var key = _a[0], value = _a[1];
                return options.collate(value, object[key]);
            }));
        }
        object_1.matches = matches;
        /**
         * erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt
         */
        function flatten(value, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "separator": ".",
                "key_for_array_element": (function (index) { return ("element_" + index.toFixed(0)); })
            }, options);
            var integrate = function (result, key, value) {
                if (value == null) {
                    result[key] = value;
                }
                else {
                    // primitive Werte direkt übernehmen
                    if (typeof (value) != "object") {
                        result[key] = value;
                    }
                    // sonst durch rekursiven Aufruf die flache Variante des Wertes ermitteln und einarbeiten
                    else {
                        var result_ = flatten(value, {
                            "separator": options.separator,
                            "key_for_array_element": options.key_for_array_element
                        });
                        Object.entries(result_).forEach(function (_a) {
                            var key_ = _a[0], value_ = _a[1];
                            result[(key + options.separator + key_)] = value_;
                        });
                    }
                }
            };
            if ((value === null)
                ||
                    (value === undefined)) {
                return null;
            }
            else {
                var result_1 = {};
                if (typeof (value) != "object") {
                    result_1["value"] = value;
                }
                else {
                    if (value instanceof Array) {
                        value.forEach(function (element, index) {
                            integrate(result_1, options.key_for_array_element(index), element);
                        });
                    }
                    else {
                        Object.entries(value).forEach(function (_a) {
                            var key = _a[0], value = _a[1];
                            integrate(result_1, key, value);
                        });
                    }
                }
                return result_1;
            }
        }
        object_1.flatten = flatten;
        /**
         * @deprecated use Object.assign instead!
         */
        function clash(x, y, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "overwrite": true,
                "hooks": {
                    "existing": function (key, value_old, value_new) {
                        lib_plankton.log.warning("object_clash_field_already_defined", {
                            "key": key
                        });
                    }
                }
            }, options);
            var z = {};
            Object.keys(x).forEach(function (key) {
                z[key] = x[key];
            });
            Object.keys(y).forEach(function (key) {
                if (key in z) {
                    if (options.hooks.existing != null) {
                        options.hooks.existing(key, z[key], y[key]);
                    }
                    if (options.overwrite) {
                        z[key] = y[key];
                    }
                }
                else {
                    z[key] = y[key];
                }
            });
            return z;
        }
        object_1.clash = clash;
        /**
         * @deprecated use Object.assign instead!
         */
        function patch(core, mantle, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "deep": true,
                "path": null
            }, options);
            if (mantle == null) {
                lib_plankton.log.warning("object_patch_mantle_is_null", {
                    "core": core
                });
            }
            else {
                Object.keys(mantle).forEach(function (key) {
                    var path_ = ((options.path == null)
                        ?
                            key
                        :
                            (options.path + "." + key));
                    var value_mantle = mantle[key];
                    if (!(key in core)) {
                        if ((typeof (value_mantle) == "object")
                            &&
                                (value_mantle != null)
                            &&
                                options.deep) {
                            if (value_mantle instanceof Array) {
                                core[key] = [];
                                value_mantle.forEach(function (element) {
                                    if ((typeof (element) == "object")
                                        &&
                                            (element != null)) {
                                        var element_ = {};
                                        patch(element_, element);
                                        core[key].push(element_);
                                    }
                                    else {
                                        core[key].push(element);
                                    }
                                });
                            }
                            else {
                                core[key] = {};
                                patch(core[key], value_mantle, {
                                    "deep": options.deep,
                                    "path": path_
                                });
                            }
                        }
                        else {
                            core[key] = value_mantle;
                        }
                    }
                    else {
                        var value_core = core[key];
                        if (typeof (value_core) == typeof (value_mantle)) {
                            if ((typeof (value_mantle) == "object")
                                &&
                                    (value_mantle != null)
                                &&
                                    options.deep) {
                                patch(core[key], value_mantle, {
                                    "deep": options.deep,
                                    "path": path_
                                });
                            }
                            else {
                                core[key] = value_mantle;
                            }
                        }
                        else {
                            if ((value_core != null)
                                &&
                                    (value_mantle != null)) {
                                lib_plankton.log.warning("object_path_different_shapes", {
                                    "path": path_,
                                    "core_type": typeof (value_core),
                                    "mantle_type": typeof (value_mantle)
                                });
                            }
                            core[key] = value_mantle;
                            // throw (new Error(message));
                        }
                    }
                });
            }
        }
        object_1.patch = patch;
        /**
         * @deprecated use Object.assign instead!
         */
        function patched(core, mantle, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "deep": true
            }, options);
            var result = {};
            patch(result, core, { "deep": options.deep });
            patch(result, mantle, { "deep": options.deep });
            return result;
        }
        object_1.patched = patched;
        /**
         * @deprecated use Object.assign instead!
         */
        function attached(object, key, value) {
            var mantle = {};
            mantle[key] = value;
            return patched(object, mantle, { "deep": false });
        }
        object_1.attached = attached;
        /**
         * @author fenris
         */
        function copy(object) {
            return patched({}, object);
        }
        object_1.copy = copy;
    })(object = lib_plankton.object || (lib_plankton.object = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pair«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pair« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pair« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pair«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:pair«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pair« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pair« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pair«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var pair;
    (function (pair_1) {
        /**
         */
        function swap(pair) {
            return {
                "first": pair.second,
                "second": pair.first
            };
        }
        pair_1.swap = swap;
        /**
         */
        function show(pair, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "show_first": instance_show,
                "show_second": instance_show
            }, options);
            return ("("
                +
                    options.show_first(pair.first)
                +
                    ","
                +
                    options.show_second(pair.second)
                +
                    ")");
        }
        pair_1.show = show;
    })(pair = lib_plankton.pair || (lib_plankton.pair = {}));
})(lib_plankton || (lib_plankton = {}));
"use strict";
/*
This file is part of »bacterio-plankton:list«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:list« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:list« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:list«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:list«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:list« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:list« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:list«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var list;
    (function (list_1) {
        /**
         * returns a certain list of integer numbers
         */
        function range(from, to, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "step": 1
            }, options);
            var list = [];
            for (var value = from; value <= to; value += options.step) {
                list.push(value);
            }
            return list;
        }
        list_1.range = range;
        /**
         * returns a certain list of consecutiv integer numbers, beginning with 0
         */
        function sequence(length) {
            return range(0, length - 1);
        }
        list_1.sequence = sequence;
        /**
         */
        function from_iterator(iterator) {
            var list = [];
            // @ts-ignore
            for (var _i = 0, iterator_1 = iterator; _i < iterator_1.length; _i++) {
                var element = iterator_1[_i];
                list.push(element);
            }
            return list;
        }
        list_1.from_iterator = from_iterator;
        /**
         */
        function is_empty(list) {
            return (list.length <= 0);
        }
        list_1.is_empty = is_empty;
        /**
         * combines two lists into one
         *
         * @param {boolean} [options.cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true
         */
        function zip(list_first, list_second, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "cut": true
            }, options);
            var empty_first = is_empty(list_first);
            var empty_second = is_empty(list_second);
            if (empty_first || empty_second) {
                if (options.cut || (empty_first && empty_second)) {
                    return [];
                }
                else {
                    throw (new Error("lists have different lengths"));
                }
            }
            else {
                return ([{ "first": list_first[0], "second": list_second[0] }]
                    .concat(zip(list_first.slice(1), list_second.slice(1), {
                    "cut": options.cut
                })));
            }
        }
        list_1.zip = zip;
        /**
         * checks whether two lists are equal
         *
         * @todo define common function "equals" and default predicate to
         */
        function equals(list1, list2, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "collate_element": instance_collate
            }, options);
            if (list1.length == list2.length) {
                return (zip(list1, list2, { "cut": true })
                    .every(function (pair) { return options.collate_element(pair.first, pair.second); }));
            }
            else {
                return false;
            }
        }
        list_1.equals = equals;
        /**
         * creates a list with the elements from the input list, which fulfil a certain predicate (~ filter)
         */
        function keep(list, predicate) {
            return (list
                .filter(function (element, index) { return predicate(element); }));
        }
        list_1.keep = keep;
        /**
         * creates a list with the elements from the input list, which do not fulfil a certain predicate (~ dual filter)
         */
        function drop(list, predicate) {
            return (list
                .filter(function (element, index) { return (!predicate(element)); }));
        }
        list_1.drop = drop;
        /**
         */
        function filter_inplace(list, predicate) {
            var index = 0;
            while (index < list.length) {
                var element = list[index];
                if (predicate(element)) {
                    index += 1;
                }
                else {
                    list.splice(index, 1);
                }
            }
        }
        list_1.filter_inplace = filter_inplace;
        /**
         * returns a list with no duplicates (like unix' "unique")
         */
        function cleaned(list, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "collate_element": instance_collate
            }, options);
            var list_ = [];
            list.forEach(function (element) {
                if (!list_.some(function (element_) { return options.collate_element(element, element_); })) {
                    list_.push(element);
                }
                else {
                    // do nothing
                }
            });
            return list_;
        }
        list_1.cleaned = cleaned;
        /**
         * creates a binary partition of the list according to a given predicate
         */
        function separate(list, predicate) {
            return (list
                .reduce(function (seperation, element) {
                return (predicate(element)
                    ? { "yes": seperation.yes.concat([element]), "no": seperation["no"] }
                    : { "yes": seperation.yes, "no": seperation["no"].concat([element]) });
            }, { "yes": [], "no": [] }));
        }
        list_1.separate = separate;
        ;
        /**
         */
        function clone(list) {
            return keep(list, function (x) { return true; });
        }
        list_1.clone = clone;
        /**
         */
        function reversed(list) {
            var list_ = clone(list);
            list_.reverse();
            return list_;
        }
        list_1.reversed = reversed;
        /**
         * @todo use Array.toSorted?
         */
        function sorted(list, options) {
            options = Object.assign({
                "compare_element": instance_compare
            }, options);
            var list_ = clone(list);
            list_.sort(function (x, y) { return (options.compare_element(x, y) ? -1 : +1); });
            return list_;
        }
        list_1.sorted = sorted;
        /**
         * die Liste in gleich große Blöcke zerlegen
         */
        function chop(list, chunk_size) {
            var chunks = [];
            var index = 0;
            while (index < list.length) {
                var chunk = list.slice(index, Math.min(list.length, index + chunk_size));
                index += chunk_size;
                chunks.push(chunk);
            }
            return chunks;
        }
        list_1.chop = chop;
        /**
         */
        function group(list, collate_element) {
            var result = [];
            list.forEach(function (element) {
                var target = result.find(
                // @ts-ignore
                function (group) { return collate_element(group[0], element); });
                if (target === undefined) {
                    target = [];
                    result.push(target);
                }
                target.push(element);
            });
            return result;
        }
        list_1.group = group;
        /**
         */
        function has(list, predicate) {
            return (list.find(predicate) !== undefined);
        }
        list_1.has = has;
        /**
         * @deprecate use Array.includes or Array.some
         */
        function contains(list, element, options) {
            options = Object.assign({
                "collate": instance_collate
            }, options);
            return has(list, function (element_) { return options.collate_element(element_, element); });
        }
        list_1.contains = contains;
        /**
         * retrieves the element and its index of the list, which has the maximum value
         */
        function max(list, target_function, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["compare_value"], compare_value = _c === void 0 ? (function (x, y) { return (x <= y); }) : _c;
            /*if (is_empty<type_element>(list)) {
                throw (new Error("the max-arg of an empty list is not defined"));
            }
            else */ {
                return (list
                    .reduce(function (result, element, index) {
                    var value = target_function(element);
                    if ((result == null)
                        ||
                            (!compare_value(value, result.value))) {
                        return { "index": index, "element": element, "value": value };
                    }
                    else {
                        return result;
                    }
                }, null));
            }
        }
        list_1.max = max;
        /**
         * retrieves the element and its index of the list, which has the mininum value
         */
        function min(list, target_function, options) {
            options = Object.assign({
                "compare_value": instance_compare
            }, options);
            return max(list, target_function, {
                "compare_value": function (x, y) { return options.compare_value(y, x); }
            });
        }
        list_1.min = min;
        /**
         * implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)"
         * 		example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]]
         */
        function distribute(lists) {
            if (is_empty(lists)) {
                return [[]];
            }
            else {
                var subresult_1 = distribute(lists.slice(1));
                return (lists[0]
                    .map(function (element) { return subresult_1.map(function (list) { return [element].concat(list); }); })
                    .reduce(function (x, y) { return x.concat(y); }, []));
            }
        }
        list_1.distribute = distribute;
        /**
         */
        function contrast(list_left, extract_key_left, list_right, extract_key_right) {
            var gathering = {};
            list_left.forEach(function (source_left) {
                var _a;
                var key = extract_key_left(source_left);
                gathering[key] = Object.assign(((_a = gathering[key]) !== null && _a !== void 0 ? _a : {}), { "left": source_left });
            });
            list_right.forEach(function (source_right) {
                var _a;
                var key = extract_key_right(source_right);
                gathering[key] = Object.assign(((_a = gathering[key]) !== null && _a !== void 0 ? _a : {}), { "right": source_right });
            });
            var result = {
                "both": [],
                "only_left": [],
                "only_right": []
            };
            Object.entries(gathering).forEach(function (_a) {
                var key = _a[0], value = _a[1];
                if ("left" in value) {
                    if ("right" in value) {
                        result.both.push({ "key": key, "left": value.left, "right": value.right });
                    }
                    else {
                        result.only_left.push({ "key": key, "left": value.left });
                    }
                }
                else {
                    if ("right" in value) {
                        result.only_right.push({ "key": key, "right": value.right });
                    }
                    else {
                        // impossible
                        // do nothing
                    }
                }
            });
            return result;
        }
        list_1.contrast = contrast;
    })(list = lib_plankton.list || (lib_plankton.list = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:conf«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:conf« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:conf« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:conf«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:conf«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:conf« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:conf« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:conf«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var conf;
    (function (conf) {
        /**
         */
        function adapt_primitive(schema, value) {
            if (value === undefined) {
                if (!("default" in schema)) {
                    return {
                        "reports": [
                            {
                                "incident": "neither explicit value provided nor default value specified",
                                "details": {}
                            }
                        ],
                        "result": lib_plankton.pod.make_empty(),
                    };
                }
                else {
                    return {
                        "reports": [],
                        "result": lib_plankton.pod.make_filled(schema.default),
                    };
                }
            }
            else {
                if (value === null) {
                    if (("nullable" in schema)
                        &&
                            (!schema.nullable)) {
                        return {
                            "reports": [
                                {
                                    "incident": "null not allowed",
                                    "details": {}
                                }
                            ],
                            "result": lib_plankton.pod.make_empty(),
                        };
                    }
                    else {
                        return {
                            "reports": [],
                            "result": lib_plankton.pod.make_filled(null),
                        };
                    }
                }
                else {
                    if (("enum" in schema)
                        &&
                            (!schema.enum.includes(value))) {
                        return {
                            "reports": [
                                {
                                    "incident": "provided value not in enumeration of valid values",
                                    "details": {
                                        "enumerated_values": schema.enum,
                                        "provided_value": value,
                                    }
                                }
                            ],
                            "result": lib_plankton.pod.make_empty(),
                        };
                    }
                    else {
                        const type_map = {
                            "boolean": "boolean",
                            "integer": "number",
                            "number": "number",
                            "string": "string",
                        };
                        // @ts-ignore
                        if (!(typeof (value) === type_map[schema.type])) {
                            return {
                                "reports": [
                                    {
                                        // @ts-ignore
                                        "incident": ("value should be " + type_map[schema.type]),
                                        "details": {
                                            "provided_value": value,
                                            "type": typeof (value),
                                        }
                                    }
                                ],
                                "result": lib_plankton.pod.make_empty(),
                            };
                        }
                        else {
                            return {
                                "reports": [],
                                "result": lib_plankton.pod.make_filled(value)
                            };
                        }
                    }
                }
            }
        }
        /**
         * @todo anyOf
         * @todo allOf
         * @todo oneOf
         * @todo not
         * @todo tests
         */
        function adapt(schema, value_raw) {
            let value = value_raw;
            if (!("type" in schema)) {
                if ("anyOf" in schema) {
                    if (value === undefined) {
                        if (!("default" in schema)) {
                            return {
                                "reports": [
                                    {
                                        "incident": "neither explicit value provided nor default value specified",
                                        "details": {}
                                    }
                                ],
                                "result": lib_plankton.pod.make_empty(),
                            };
                        }
                        else {
                            value = schema.default;
                        }
                    }
                    else {
                        // do nothing
                    }
                    const sub_adaptions = (schema.anyOf
                        .map((sub_schema) => adapt(sub_schema, value)));
                    const valid_sub_adaptions = (sub_adaptions
                        .filter((sub_adaption) => lib_plankton.pod.is_filled(sub_adaption.result)));
                    if (valid_sub_adaptions.length <= 0) {
                        return {
                            "reports": [
                                {
                                    "incident": "no valid adaptions",
                                    "details": {
                                        "sub_adaptions": sub_adaptions,
                                    }
                                }
                            ],
                            "result": lib_plankton.pod.make_empty(),
                        };
                    }
                    else {
                        if (valid_sub_adaptions.length > 1) {
                            return {
                                "reports": [
                                    {
                                        "incident": "multiple valid apaptions",
                                        "details": {
                                            "valid_sub_adaptions": valid_sub_adaptions,
                                        }
                                    }
                                ],
                                "result": lib_plankton.pod.make_empty(),
                            };
                        }
                        else {
                            return valid_sub_adaptions[0];
                        }
                    }
                }
                else {
                    throw (new Error("not implemented"));
                }
            }
            else {
                switch (schema.type) {
                    case "boolean":
                        return adapt_primitive(schema, value);
                        break;
                    case "integer":
                        return adapt_primitive(schema, value);
                        break;
                    case "number":
                        return adapt_primitive(schema, value);
                        break;
                    case "string": {
                        return adapt_primitive(schema, value);
                        break;
                    }
                    case "array": {
                        if (value === undefined) {
                            if (!("default" in schema)) {
                                return {
                                    "reports": [
                                        {
                                            "incident": "neither explicit value provided nor default value specified",
                                            "details": {}
                                        }
                                    ],
                                    "result": lib_plankton.pod.make_empty(),
                                };
                            }
                            else {
                                value = schema.default;
                            }
                        }
                        /*else*/ {
                            if (value === null) {
                                if (("nullable" in schema)
                                    &&
                                        (!schema.nullable)) {
                                    return {
                                        "reports": [
                                            {
                                                "incident": "null not allowed",
                                                "details": {}
                                            }
                                        ],
                                        "result": lib_plankton.pod.make_empty(),
                                    };
                                }
                                else {
                                    return {
                                        "reports": [],
                                        "result": lib_plankton.pod.make_filled(null),
                                    };
                                }
                            }
                            else {
                                /*if (
                                    ("enum" in schema)
                                    &&
                                    (! schema.enum.includes(value)) // TODO
                                ) {
                                    return {
                                        "reports": [
                                            {
                                                "incident": "provided value not in enumeration of valid values",
                                                "details": {
                                                    "enumerated_values": schema.enum,
                                                    "provided_value": value,
                                                }
                                            }
                                        ],
                                        "result": lib_plankton.pod.make_empty<any>(),
                                    };
                                }
                                else*/ {
                                    if ((!(typeof (value) === "object"))
                                        &&
                                            (value.constructor.name !== "Array")) {
                                        return {
                                            "reports": [
                                                {
                                                    "incident": "value should be array",
                                                    "details": {
                                                        "provided_value": value,
                                                    }
                                                }
                                            ],
                                            "result": lib_plankton.pod.make_empty(),
                                        };
                                    }
                                    else {
                                        if (!("items" in schema)) {
                                            // do nothing
                                            return {
                                                "reports": [],
                                                "result": lib_plankton.pod.make_filled(value),
                                            };
                                        }
                                        else {
                                            let reports = [];
                                            for (let index = 0; index < value.length; index += 1) {
                                                const adaption = adapt(schema.items, value[index]);
                                                if (!lib_plankton.pod.is_filled(adaption.result)) {
                                                    reports = reports.concat(adaption.reports.map((report_entry) => ({
                                                        "incident": report_entry.incident,
                                                        "details": Object.assign(report_entry.details, {
                                                            "path": (report_entry.details.path ?? []).concat([index])
                                                        }),
                                                    })));
                                                }
                                                else {
                                                    value[index] = lib_plankton.pod.cull(adaption.result);
                                                }
                                            }
                                            return {
                                                "reports": reports,
                                                "result": ((reports.length > 0)
                                                    ?
                                                        lib_plankton.pod.make_empty()
                                                    :
                                                        lib_plankton.pod.make_filled(value)),
                                            };
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                    case "object": {
                        if (value === undefined) {
                            if (!("default" in schema)) {
                                return {
                                    "reports": [
                                        {
                                            "incident": "neither explicit value provided nor default value specified",
                                            "details": {}
                                        }
                                    ],
                                    "result": lib_plankton.pod.make_empty(),
                                };
                            }
                            else {
                                value = schema.default;
                            }
                        }
                        /*else*/ {
                            if (value === null) {
                                if (("nullable" in schema)
                                    &&
                                        (!schema.nullable)) {
                                    return {
                                        "reports": [
                                            {
                                                "incident": "null not allowed",
                                                "details": {}
                                            }
                                        ],
                                        "result": lib_plankton.pod.make_empty(),
                                    };
                                }
                                else {
                                    return {
                                        "reports": [],
                                        "result": lib_plankton.pod.make_filled(null),
                                    };
                                }
                            }
                            else {
                                /*if (
                                    ("enum" in schema)
                                    &&
                                    (! schema.enum.includes(value)) // TODO
                                ) {
                                    return {
                                        "reports": [
                                            {
                                                "incident": "provided value not in enumeration of valid values",
                                                "details": {
                                                    "enumerated_values": schema.enum,
                                                    "provided_value": value,
                                                }
                                            }
                                        ],
                                        "result": lib_plankton.pod.make_empty<any>(),
                                    };
                                }
                                else*/ {
                                    if (!(typeof (value) === "object")) {
                                        return {
                                            "reports": [
                                                {
                                                    "incident": "value should be object",
                                                    "details": {
                                                        "provided_value": value,
                                                    }
                                                }
                                            ],
                                            "result": lib_plankton.pod.make_empty(),
                                        };
                                    }
                                    else {
                                        value = lib_plankton.object.copy(value);
                                        const contrast = lib_plankton.list.contrast(Object.keys(schema.properties), x => x, Object.keys(value), x => x);
                                        let reports = [];
                                        // gratuitous fields
                                        {
                                            if (contrast.only_right.length <= 0) {
                                                // do nothing
                                            }
                                            else {
                                                const additional_properties = (schema.additionalProperties ?? false);
                                                if (additional_properties === false) {
                                                    reports = reports.concat(contrast.only_right
                                                        .map((entry) => ({
                                                        "incident": "gratuitous field",
                                                        "details": {
                                                            "path": [entry.right],
                                                        }
                                                    })));
                                                }
                                                else {
                                                    contrast.only_right.forEach((entry) => {
                                                        const sub_adaption = adapt(additional_properties, value[entry.right]);
                                                        if (!lib_plankton.pod.is_filled(sub_adaption.result)) {
                                                            reports = reports.concat(sub_adaption.reports
                                                                .map((report_entry) => ({
                                                                "incident": report_entry.incident,
                                                                "details": Object.assign(report_entry.details, {
                                                                    "path": [entry.right].concat(report_entry.details.path ?? []),
                                                                }),
                                                            })));
                                                        }
                                                        else {
                                                            value[entry.right] = lib_plankton.pod.cull(sub_adaption.result);
                                                        }
                                                    });
                                                }
                                            }
                                        }
                                        // missing fields
                                        {
                                            contrast.only_left.forEach((entry) => {
                                                if (("required" in schema)
                                                    &&
                                                        schema.required.includes(entry.left)) {
                                                    reports.push({
                                                        "incident": "missing field",
                                                        "details": {
                                                            "path": [entry.left],
                                                        }
                                                    });
                                                }
                                                else {
                                                    const sub_adaption = adapt(schema.properties[entry.left], undefined);
                                                    if (!lib_plankton.pod.is_filled(sub_adaption.result)) {
                                                        reports = reports.concat(sub_adaption.reports
                                                            .map((report_entry) => ({
                                                            "incident": report_entry.incident,
                                                            "details": Object.assign(report_entry.details, {
                                                                "path": [entry.left].concat(report_entry.details.path ?? []),
                                                            }),
                                                        })));
                                                    }
                                                    else {
                                                        value[entry.left] = lib_plankton.pod.cull(sub_adaption.result);
                                                    }
                                                }
                                            });
                                            // regular fields
                                            {
                                                contrast.both.forEach((entry) => {
                                                    const sub_adaption = adapt(schema.properties[entry.left], value[entry.right]);
                                                    if (!lib_plankton.pod.is_filled(sub_adaption.result)) {
                                                        reports = reports.concat(sub_adaption.reports
                                                            .map((report_entry) => ({
                                                            "incident": report_entry.incident,
                                                            "details": Object.assign(report_entry.details, {
                                                                "path": [entry.right].concat(report_entry.details.path ?? []),
                                                            }),
                                                        })));
                                                    }
                                                    else {
                                                        value[entry.right] = lib_plankton.pod.cull(sub_adaption.result);
                                                    }
                                                });
                                            }
                                            return {
                                                "reports": reports,
                                                "result": ((reports.length > 0)
                                                    ?
                                                        lib_plankton.pod.make_empty()
                                                    :
                                                        lib_plankton.pod.make_filled(value)),
                                            };
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    }
                    default: {
                        throw (new Error("unhandled schema type: " + schema.type));
                        break;
                    }
                }
            }
        }
        /**
         */
        function refine(schema, content) {
            const adaption = adapt(schema, content);
            if (!lib_plankton.pod.is_filled(adaption.result)) {
                throw (new Error("conf could not be loaded:\n"
                    +
                        (adaption.reports
                            .map((report) => ("- " + report.incident + " | " + JSON.stringify(report.details, undefined, "\t")))
                            .join("\n"))));
            }
            else {
                return lib_plankton.pod.cull(adaption.result);
            }
        }
        conf.refine = refine;
        /**
         * @deprecated
         */
        function load(schema, path) {
            return (((path === null)
                ?
                    Promise.resolve(undefined)
                :
                    (lib_plankton.file.read(path)
                        .then((content) => Promise.resolve(lib_plankton.json.decode(content)))))
                .then((data_raw) => Promise.resolve(refine(schema, data_raw))));
        }
        conf.load = load;
        /**
         */
        async function load_versioned(path, get_schema, migrations) {
            const file_content = await lib_plankton.file.read(path);
            const sheet_raw = lib_plankton.json.decode(file_content);
            const schema = get_schema(sheet_raw.version);
            let sheet = {
                "version": sheet_raw.version,
                "content": refine(schema, sheet_raw.content),
            };
            while (sheet.version in migrations) {
                const migration = migrations[sheet.version];
                if (!(migration === null)) {
                    lib_plankton.log._info("plankton.conf.load.migration", {
                        "details": {
                            "from": sheet.version,
                            "to": migration.target,
                        }
                    });
                    sheet = {
                        "version": migration.target,
                        "content": migration.function(sheet.content),
                    };
                }
                else {
                    break;
                }
            }
            return sheet;
        }
        conf.load_versioned = load_versioned;
    })(conf = lib_plankton.conf || (lib_plankton.conf = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:string« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:string« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
 */
var plain_text_to_html = function (text) {
    let ret = text;
    ret = ret.replace(/  /g, "&nbsp;&nbsp;"); // convert multiple whitespace to forced ones
    ret = ret.split("\n").join("<br/>");
    return ret;
};
/**
 * @desc makes a valid
 */
var format_sentence = function (str, rtl = false, caseSense = true) {
    if (str === "") {
        return str;
    }
    else {
        let marks = {
            ".": true,
            "?": true,
            "!": true
        };
        let default_mark = ".";
        let ret = str.split("");
        if (!rtl) {
            ret[0] = ret[0].toLocaleUpperCase();
            if (!(ret[ret.length - 1] in marks)) {
                ret.push(default_mark);
            }
        }
        else {
            ret[ret.length - 1] = ret[ret.length - 1].toLocaleUpperCase();
            if (!(ret[0] in marks)) {
                ret.unshift(default_mark);
            }
        }
        return ret.join("");
    }
};
var fill_string_template = function (template_string, object, fabric = function (object, key) { return object[key]; }, delimiter = "%", default_string = null, sloppy) {
    function get_tags(str) {
        let r = new RegExp(delimiter + "[^\\s^" + delimiter + "]+" + delimiter, "gi");
        return ((str.match(r) || []).map(function (e) {
            return e.slice(delimiter.length, e.length - delimiter.length);
        }));
    }
    function replace_tag(str, tag, value) {
        let r = new RegExp(delimiter + tag + delimiter, "gi");
        return str.replace(r, value);
    }
    function replace_tags(str, obj) {
        return (get_tags(str).reduce(function (ret, key) {
            let value = "";
            try {
                value = fabric(obj, key);
                if ((!sloppy && (value === void 0)) || (sloppy && (value == void 0))) {
                    value = default_string;
                }
            }
            catch (e) {
                console.warn("invalid placeholder " + key);
                value = default_string;
            }
            return replace_tag(ret, key, value);
        }, str));
    }
    return replace_tags(template_string, object);
};
var make_string_template = function (_template, _fabrics = {}) {
    function replace_tag(str, tag, value) {
        var r = new RegExp("%" + tag + "%", "gi");
        return str.replace(r, value);
    }
    function replace_tags(str, obj) {
        return (Object.keys(obj).reduce(function (ret, key) {
            return replace_tag(ret, key, _fabrics[key] || obj[key]);
        }, str));
    }
    return (function (tags) {
        return replace_tags(_template, tags);
    });
};
var make_eml_header = (function () {
    let _template = "";
    _template += "From: %from%\n";
    _template += "To: %recipient%\n";
    _template += "Subject: %subject%\n";
    _template += "X-Mailer: greenscale-plankton.emlgen\n";
    return make_string_template(_template);
})();
var make_eml_body = (function () {
    let exports = {};
    exports["simple_body"] = make_string_template("Content-Type: %contenttype%\n\n%body%\n\n");
    // very basic implementation
    // parts = [{contenttype:"text/html; charset=UTF-8", body: "<h1>foo</h1>" }, {...}]
    exports["body_boundrary"] = function (parts, boundrary) {
        let _template = "";
        _template += "--%boundrary%\n";
        _template += "Content-Type: %contenttype%\n\n%body%\n\n";
        //_template += "--%boundrary%--\n\n";
        let maker = make_string_template(_template);
        return (parts.reduce(function (prev, curr) {
            curr.boundrary = boundrary;
            return [prev, maker(curr)].join("");
        }, ""));
    };
    // body must be base64 encoded!
    exports["attachment_boundrary"] = function (parts, boundrary) {
        let _template = "";
        _template += "--%boundrary%\n";
        _template += "Content-Type: %contenttype%\n";
        _template += "Content-Transfer-Encoding: base64\n";
        _template += "Content-Disposition: %disposition%; filename=\"%name%\"\n\n";
        _template += "%body%\n\n";
        //_template += "--%boundrary%--\n\n";
        let maker = make_string_template(_template);
        return (parts.reduce(function (prev, curr) {
            curr.boundrary = boundrary;
            if (curr.disposition === void 0)
                curr.disposition = "inline";
            return [prev, maker(curr)].join("");
        }, ""));
    };
    exports["gen_boundrary"] = function () {
        return ("xxxxxxxxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
            let r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0, v = c == "x" ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }));
    };
    // simple implementation without alternatives (old rfc)
    exports["complete_boundrary"] = function (bodyparts, attachments) {
        let ret = "";
        let boundrary = exports["gen_boundrary"]();
        ret += exports["body_boundrary"](bodyparts, boundrary);
        ret += exports["attachment_boundrary"](attachments, boundrary);
        ret += "--" + boundrary + "--\n\nINVISIBLE!!!!";
        return (exports["simple_body"]({
            "contenttype": sprintf("multipart/mixed; boundary=%s", [boundrary]),
            "body": ret
        }));
    };
    return exports;
})();
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:string« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:string« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var string;
    (function (string) {
        /**
         * @author fenris
         */
        const hexdigits = 4;
        /**
         * @author fenris
         */
        const index_max = (1 << (4 * hexdigits));
        /**
         * @author fenris
         */
        var index_is = 0;
        /**
         * @author neuc,frac
         */
        function empty(str) {
            return (str.trim() === "");
        }
        string.empty = empty;
        /**
         * @desc returns a unique string
         * @param {string} prefix an optional prefix for the generated string
         * @return {string}
         * @author fenris
         */
        function generate(prefix = "string_") {
            if (index_is > index_max) {
                lib_plankton.log.error("plankton.string.generate.out_of_valid_indices", null);
                throw (new Error("[string_generate] out of valid indices"));
            }
            else {
                return string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]);
            }
        }
        string.generate = generate;
        /**
         * @author fenris
         */
        function join(parts, glue = " ") {
            if (parts.length == 0) {
                return "";
            }
            else {
                return parts.join(glue);
            }
        }
        string.join = join;
        /**
         * @desc splits a string, but returns an empty list, if the string is empty
         * @param {string} chain
         * @param {string} separator
         * @return {Array<string>}
         * @author fenris
         */
        function split(chain, separator) {
            if (chain.length == 0) {
                return [];
            }
            else {
                return chain.split(separator);
            }
        }
        string.split = split;
        /**
         * @author neu3no
         */
        function explode(str, needle, max) {
            let temp = str.split(needle);
            const right = temp.splice(max - 1);
            temp.push(right.join(needle));
            return temp;
        }
        string.explode = explode;
        /**
         * @desc concats a given word with itself n times
         * @param {string} word
         * @param {int}
         * @return {string}
         * @author fenris
         */
        function repeat(word, count) {
            // return ((count == 0) ? "" : (word + repeat(word, count-1)));
            let result = "";
            for (let n = 0; n < count; n += 1) {
                result += word;
            }
            return result;
        }
        string.repeat = repeat;
        /**
         * @desc lengthens a string by repeatedly appending or prepending another string
         * @param {string} word the string to pad
         * @param {int} length the length, which the result shall have
         * @param {string} symbol the string, which will be added (multiple times)
         * @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false
         * @return {string} the padded string
         * @author fenris
         */
        function pad(word, length, symbol = " ", mode = "append") {
            switch (mode) {
                case "prepend": {
                    // insert symbols only at the beginning
                    while (word.length < length)
                        word = symbol + word;
                    return word.substring(word.length - length);
                    break;
                }
                case "append": {
                    // insert symbols only at the end
                    while (word.length < length)
                        word = word + symbol;
                    return word.substring(0, length);
                    break;
                }
                case "widen": {
                    // insert symbols at both sides
                    let left = (((length - word.length) & 1) === 0);
                    while (word.length < length) {
                        word = (left
                            ? (symbol + word)
                            : (word + symbol));
                        left = (!left);
                    }
                    return word.substring(0, length);
                    break;
                }
                default: {
                    const message = ("unhandled mode '" + mode + "'");
                    console.warn(message);
                    return word;
                    break;
                }
            }
        }
        string.pad = pad;
        /**
         * @desc checks if a given string conttains a certain substring
         * @param {string} string
         * @param {string} part
         * @return {boolean}
         * @author fenris
         */
        function contains(chain, part) {
            if (typeof (chain) !== "string") {
                return false;
            }
            return (chain.indexOf(part) >= 0);
        }
        string.contains = contains;
        /**
         * @desc checks if a given string starts with a certain substring
         * @param {string} string
         * @param {string} part
         * @return {boolean}
         * @author fenris
         */
        function startsWith(chain, part) {
            if (typeof (chain) !== "string") {
                return false;
            }
            // return (string.indexOf(part) === 0);
            return ((function (m, n) {
                if (n === 0) {
                    return true;
                }
                else {
                    if (m === 0) {
                        return false;
                    }
                    else {
                        return ((chain[0] == part[0])
                            &&
                                startsWith(chain.substring(1), part.substring(1)));
                    }
                }
            })(chain.length, part.length));
        }
        string.startsWith = startsWith;
        /**
         * @desc checks if a given string ends with a certain substring
         * @param {string} string
         * @param {string} part
         * @return {boolean}
         * @author fenris
         */
        function endsWith(chain, part) {
            if (typeof (chain) !== "string") {
                return false;
            }
            // return (string.lastIndexOf(part) === string.length-part.length);
            return ((function (m, n) {
                if (n === 0) {
                    return true;
                }
                else {
                    if (m === 0) {
                        return false;
                    }
                    else {
                        // console.info(("(" + string[m-1] + " == " + part[n-1] + ")") + " = " + String(string[m-1] == part[n-1]));
                        return ((chain[m - 1] === part[n - 1])
                            &&
                                endsWith(chain.substring(0, m - 1), part.substring(0, n - 1)));
                    }
                }
            })(chain.length, part.length));
        }
        string.endsWith = endsWith;
        /**
         * @desc count the occourrences of a string in a string
         * @param string haystack_string the string wich should be examined
         * @param string needle_string the string which should be counted
         * @author neuc
         */
        function count_occourrences(haystack_string, needle_string, check_escape) {
            let cnt = 0;
            let pos = -1;
            do {
                pos = haystack_string.indexOf(needle_string, pos + 1);
                if ((!check_escape) || (haystack_string[pos - 1] != "\\")) {
                    cnt++;
                }
            } while (pos >= 0);
            return (cnt - 1);
        }
        string.count_occourrences = count_occourrences;
        /**
         * @author fenris
         */
        function replace(str, replacements, options = {}) {
            options = Object.assign({}, options);
            let result = str;
            replacements.forEach(replacement => {
                lib_plankton.log.debug("lib_plankton.string.replace", {
                    "from": replacement.from,
                    "to": replacement.to,
                });
                result = result.replace(new RegExp(replacement.from, "g"), replacement.to);
            });
            return result;
        }
        string.replace = replace;
        /**
         * @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object
         * @author fenris
         */
        function coin(str, args, options = {}) {
            options = Object.assign({
                "legacy": false,
                "open": "{{",
                "close": "}}",
            }, options);
            Object.keys(args).forEach((key) => {
                // old syntax
                {
                    if (options.legacy) {
                        const value = args[key];
                        const regexp_argument = new RegExp("\\${" + key + "}", "g");
                        /*
                        lib_plankton.log.debug(
                            "lib_plankton.string.coin",
                            {
                                "key": key,
                                "regex": regexp_argument.toString(),
                                "value": value,
                            }
                        );
                         */
                        str = str.replace(regexp_argument, value);
                    }
                }
                // new syntax
                {
                    const value = args[key];
                    const regexp_argument = new RegExp(options.open + key + options.close, "g");
                    /*
                    lib_plankton.log.debug(
                        "lib_plankton.string.coin",
                        {
                            "key": key,
                            "regex": regexp_argument.toString(),
                            "value": value,
                        }
                    );
                     */
                    str = str.replace(regexp_argument, value);
                }
            });
            return str;
        }
        string.coin = coin;
        /**
         * @author fenris
         * @deprecated use limit
         */
        function cut(str, length, delimiter = "…") {
            if (str.length <= length) {
                return str;
            }
            else {
                return (str.slice(0, length - delimiter.length) + delimiter);
            }
        }
        string.cut = cut;
        /**
         */
        function limit(str, options = {}) {
            options = Object.assign({
                "length": 120,
                "indicator": "…",
            }, options);
            return ((str.length <= options.length)
                ? str
                : (str.slice(0, options.length - options.indicator.length) + options.indicator));
        }
        string.limit = limit;
        /**
         */
        function slice(str, size) {
            let slices = [];
            let rest = str;
            while (rest.length > 0) {
                slices.push(rest.slice(0, size));
                rest = rest.slice(size);
            }
            return slices;
        }
        string.slice = slice;
        /**
         */
        function capitalize(str) {
            return (str[0].toUpperCase() + str.slice(1));
        }
        string.capitalize = capitalize;
    })(string = lib_plankton.string || (lib_plankton.string = {}));
})(lib_plankton || (lib_plankton = {}));
/**
 * @deprecated
 */
var lib_string;
(function (lib_string) {
    lib_string.empty = lib_plankton.string.empty;
    lib_string.generate = lib_plankton.string.generate;
    lib_string.split = lib_plankton.string.split;
    lib_string.explode = lib_plankton.string.repeat;
    lib_string.repeat = lib_plankton.string.repeat;
    lib_string.pad = lib_plankton.string.pad;
    lib_string.contains = lib_plankton.string.contains;
    lib_string.startsWith = lib_plankton.string.startsWith;
    lib_string.endsWith = lib_plankton.string.endsWith;
    lib_string.count_occourrences = lib_plankton.string.count_occourrences;
    lib_string.coin = lib_plankton.string.coin;
    lib_string.stance = lib_plankton.string.coin;
    lib_string.cut = lib_plankton.string.cut;
})(lib_string || (lib_string = {}));
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:string« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:string« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var string;
    (function (string) {
        var pattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/;
        var gpattern = /%([-+#0 ]*)([0-9]*)[\.]{0,1}([0-9]*)([\w]{1})/g;
        function split_format(format) {
            var tmp = format.match(pattern);
            if (tmp === null)
                return null;
            return {
                'flags': tmp[1].split(""),
                'width': Number(tmp[2]),
                'precision': tmp[3] === '' ? null : Number(tmp[3]),
                'specifier': tmp[4],
                'string': format
            };
        }
        function make_err(format, arg, should) {
            return ("[sprintf]" + " " + "argument for '" + format.string + "' has to be '" + should + "' but '" + arg + "' is '" + typeof arg + "'!");
        }
        function test_arg(format, arg, should) {
            if (typeof arg !== should) {
                console.warn(make_err(format, arg, should));
                return false;
            }
            return true;
        }
        function string_fill(str, char, len, left) {
            while (str.length < len) {
                if (left) {
                    str += char;
                }
                else {
                    str = char + str;
                }
            }
            return str;
        }
        /**
         * the known_parameters are used to parse the different identifiers for the welln known syntax:
         *          flag   width   precision   identifier
         *      %{[0#+- ]}{[0-9]*}.{[0-9]*}[fFdiueEgGsoxXaAsn]
         * flags:
         * 0    -   fill with '0' instead of ' ' if the string length < width
         * #    -   not implemented
         * -    -   left-justified -> fill on the right side to reach width
         * +    -   force using '+' on positive numbers
         * ' '  -   add a single space before positive numbers
         *
         * identifiers
         * %f, %F       -   interpret given number as float, width: the minimal total width (fill with ' ' or '0' if the
         *                  resulting string is too short, precision: cut more then given decimal places
         * %d, %i, %u   -   interpret number as integer, decimal places will be cut. width: like float, precision:
         *                  fill with '0' on right side until length given in precision is reached
         * %e           -   interpret as float and write as scientifical number, width & precision like in float
         * %E           -   same es %e but uppercase 'E'
         * %g           -   use the shortest string of %f or %e
         * %G           -   use the shortest string of %E or %E
         * %s           -   simply print a string
         * %o           -   print the given number in octal notation
         * %x           -   print the given number in hex notation
         * %X           -   same as %x but with uppercase characters
         * %a           -   alias to %x
         * %A           -   alias to %X
         * %n           -   just print nothing
         * @type {{}}
         */
        var known_params = {};
        known_params["f"] = function (format, arg) {
            if (!test_arg(format, arg, "number"))
                return "Ø";
            var tmp = Math.abs(arg);
            var sign = (arg < 0) ? -1 : 1;
            var tmp_result = null;
            if (format.precision !== null) {
                tmp = Math.floor(Math.pow(10, format.precision) * tmp) / Math.pow(10, format.precision);
                var tmp_ = (tmp * sign).toString().split(".");
                if (tmp_.length === 1)
                    tmp_.push("");
                tmp_[1] = string_fill(tmp_[1], "0", format.precision, true);
                tmp_result = tmp_.join(".");
            }
            else {
                tmp_result = (sign * tmp).toString();
            }
            if ((format.flags.indexOf(" ") >= 0) && (arg >= 0)) {
                tmp_result = " " + tmp;
            }
            else if ((format.flags.indexOf("+") >= 0) && (arg >= 0)) {
                tmp_result = "+" + tmp;
            }
            tmp_result = string_fill(tmp, (format.flags.indexOf("0") >= 0) ? "0" : " ", format.width, (format.flags.indexOf("-") >= 0));
            return tmp_result;
        };
        known_params["F"] = known_params["f"];
        known_params["d"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            var tmp = (((arg < 0 && format.specifier !== 'u') ? -1 : 1) * Math.floor(Math.abs(arg))).toString();
            if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf(' ') >= 0 && arg >= 0) {
                tmp = ' ' + tmp;
            }
            else if ((format.specifier === 'd' || format.specifier === 'i') && format.flags.indexOf('+') >= 0 && arg >= 0) {
                tmp = '+' + tmp;
            }
            tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
            tmp = string_fill(tmp, '0', format.precision === null ? 0 : format.precision, false);
            return tmp;
        };
        known_params["i"] = known_params["d"];
        known_params["u"] = known_params["d"];
        known_params["e"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            var tmp = arg.toExponential(format.precision === null ? undefined : format.precision).toString();
            if (format.flags.indexOf(' ') >= 0 && arg >= 0) {
                tmp = ' ' + tmp;
            }
            else if (format.flags.indexOf('+') >= 0 && arg >= 0) {
                tmp = '+' + tmp;
            }
            tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
            return tmp;
        };
        known_params["E"] = function (format, arg) {
            return known_params["e"](format, arg).toUpperCase();
        };
        known_params["g"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            var tmpf = known_params["f"](format, arg);
            var tmpe = known_params["e"](format, arg);
            if (tmpf.length < tmpe.length) {
                return tmpf;
            }
            else {
                return tmpe;
            }
        };
        known_params["G"] = function (format, arg) {
            return known_params["g"](format, arg).toUpperCase();
        };
        known_params["s"] = function (format, arg) {
            if (!test_arg(format, arg, 'string'))
                return 'o.O';
            var tmp = format.precision !== null ? arg.substr(0, format.precision) : arg;
            tmp = string_fill(tmp, format.flags.indexOf('0') >= 0 ? '0' : ' ', format.width, format.flags.indexOf('-') >= 0);
            return tmp;
        };
        known_params["o"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
            return known_params["s"](format, tmp.toString(8));
        };
        known_params["x"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            var tmp = Math.floor(Math.round(Math.abs(arg))) * ((arg < 0) ? -1 : 1);
            return known_params["s"](format, tmp.toString(16));
        };
        known_params["a"] = known_params["x"];
        known_params["X"] = function (format, arg) {
            if (!test_arg(format, arg, 'number'))
                return 'Ø';
            return known_params["x"](format, arg).toUpperCase();
        };
        known_params["A"] = known_params["X"];
        known_params["c"] = function (format, arg) {
            var tmp = "";
            if (typeof arg === "number") {
                tmp = String.fromCharCode(arg);
            }
            else if ((typeof arg === "string") && (arg.length === 1)) {
                tmp = arg[0];
            }
            else {
                console.warn(make_err(format, arg, "number|string") + " and if string it needs to have the length of 1!");
            }
            return known_params["s"](format, tmp);
        };
        known_params["n"] = function () {
            return "";
        };
        var decompose = function (chain, regexp) {
            var result = regexp.exec(chain);
            if (result == null) {
                return null;
            }
            else {
                var front = chain.substring(0, result.index);
                var back = chain.substring(result.index + result[0].length);
                return { "front": front, "match": result[0], "back": back };
            }
        };
        /**
         * an implementation of c sprintf
         * @param {string} string format string
         * @param {array} args arguments which should be filled into
         * @returns {string}
         */
        string.sprintf = function (input, args = [], original = null) {
            if (original == null)
                original = input;
            var components = decompose(input, pattern);
            if (components == null) {
                if (args.length > 0) {
                    console.warn("[sprintf] superfluous arguments while formatting '" + original + "': ", args);
                }
                return input;
            }
            else {
                var arg;
                var rest;
                if (args.length > 0) {
                    arg = args[0];
                    rest = args.slice(1);
                }
                else {
                    console.warn("[sprintf] out of arguments while formatting '" + original + "'");
                    arg = null;
                    rest = [];
                    return input;
                }
                var fmt = split_format(components["match"]);
                return (components["front"]
                    + known_params[fmt.specifier](fmt, arg)
                    + string.sprintf(components["back"], rest, original));
            }
        };
        /**
         * an implementation of c printf
         * @param {string} string format string
         * @param {array} args arguments which should be filled into
         * @returns {string}
         */
        function printf(format, args) {
            console.log(string.sprintf(format, args));
        }
        string.printf = printf;
    })(string = lib_plankton.string || (lib_plankton.string = {}));
})(lib_plankton || (lib_plankton = {}));
var sprintf = lib_plankton.string.sprintf;
var printf = lib_plankton.string.printf;
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:string« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:string« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:string«. If not, see <http://www.gnu.org/licenses/>.
 */
var make_logger = (function () {
    var _loggers = {};
    var make_logger = function (prefix, current_loglevel) {
        var log = [];
        var level = [
            "LOG", "INFO", "WARNING", "DEBUG"
        ];
        var logger = function (obj, lvl) {
            var txt = obj.txt || obj;
            if (lvl == void 0)
                lvl = 0;
            var date = new Date();
            log.push({
                "message": sprintf("%s [%s:%s] %s", [date.toString(), level[lvl], prefix, txt]),
                "timeStamp": +(date)
            });
            if (lvl <= current_loglevel) {
                var msg = ["[" + prefix + "]", txt];
                if (obj.arg)
                    msg = ["[" + prefix + "]"].concat(Array.prototype.slice.call(obj.arg));
                if (lvl === 0)
                    console["_log"].apply(console, msg);
                else if (lvl === 1)
                    console["_info"].apply(console, msg);
                else if (lvl === 2)
                    console["_warn"].apply(console, msg);
                else if (lvl >= 3)
                    console["_log"].apply(console, msg);
            }
        };
        _loggers[prefix] = {
            "logger": logger,
            "log": log
        };
        return logger;
    };
    make_logger["loggers"] = _loggers;
    make_logger["complete_log"] = function () {
        var logs = Object.keys(_loggers)
            .reduce(function (p, c) {
            return [].concat(p, _loggers[c].log);
        }, []);
        logs.sort(function (x, y) {
            return ((x.timeStamp > y.timeStamp) ? -1 : +1);
        });
        return logs.map(function (x, i, a) {
            return x.message;
        });
    };
    if ( /*!track_exports*/true) {
        var _log_all = function (log, lvl, next = function () { }) {
            return function () {
                var msg = [];
                for (var i = 0; i < arguments.length; i++) {
                    if (typeof arguments[i] === "string") {
                        msg.push(arguments[i]);
                    }
                    else {
                        msg.push(JSON.stringify(arguments[i]));
                    }
                }
                var obj = {
                    txt: msg.join("\t"),
                    arg: arguments
                };
                log(obj, lvl);
                next();
            };
        };
        {
            var __warn = make_logger("deprecated console.warn", 99);
            var __error = make_logger("deprecated console.error", 99);
            var __log = make_logger("deprecated console.log", 99);
            var __info = make_logger("deprecated console.info", 99);
            // bad ass
            console["_log"] = console.log;
            console["_error"] = console.error;
            console["_warn"] = console.warn;
            console["_info"] = console.info;
            /*
            console["log"] = _log_all(__log, 0);
            console["error"] = _log_all(__error, 2);
            console["warn"] = _log_all(__warn, 2);
            console["info"] = _log_all(__info, 0);
             */
        }
        /*
        {
            make_logger["send_log"] = function(){
                eml_log(
                    function () {
                        alert("fehlerbericht wurde gesendet!");
                    }
                );
            };
            var error_log = make_logger("global.error", 99);
            window.onerror = _log_all(
                error_log,
                1,
                function(){
                    if (global_config == undefined) {
                        return false;
                    }
                    if (global_config.report_error) {
                        make_logger["send_log"]();
                    }
                }
            );
        }
         */
    }
    return make_logger;
})();
/*
This file is part of »bacterio-plankton:database«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:database« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:database« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:database«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var database;
    (function (database) {
        /**
         */
        let enum_type;
        (function (enum_type) {
            enum_type["boolean"] = "boolean";
            enum_type["integer"] = "integer";
            enum_type["string_short"] = "string_short";
            enum_type["string_medium"] = "string_medium";
            enum_type["string_long"] = "string_long";
            enum_type["float"] = "float";
        })(enum_type = database.enum_type || (database.enum_type = {}));
    })(database = lib_plankton.database || (lib_plankton.database = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var storage;
    (function (storage) {
        var memory;
        (function (memory) {
            /**
             * @author fenris
             */
            function make(parameters) {
                return {
                    "data": {}
                };
            }
            memory.make = make;
            /**
             * @author fenris
             */
            function clear(subject) {
                subject.data = {};
            }
            memory.clear = clear;
            /**
             * @author fenris
             */
            function write(subject, key, value) {
                var exists = (key in subject.data);
                subject.data[key] = value;
                return exists;
            }
            memory.write = write;
            /**
             * @author fenris
             */
            function delete_(subject, key) {
                if (!(key in subject.data)) {
                    throw (new Error("no value for key '" + key + "'"));
                }
                else {
                    delete subject.data[key];
                }
            }
            memory.delete_ = delete_;
            /**
             * @author fenris
             */
            function read(subject, key) {
                if (!(key in subject.data)) {
                    throw (new Error("no value for key '" + key + "'"));
                }
                else {
                    return subject.data[key];
                }
            }
            memory.read = read;
            /**
             * @author fenris
             */
            function list(subject) {
                return Object.keys(subject.data);
            }
            memory.list = list;
            /**
             * @author fenris
             */
            function search(subject, term) {
                return (list(subject)
                    .map(function (key) { return ({ "key": key, "preview": key }); }));
            }
            memory.search = search;
            /**
             * @author fenris
             */
            function implementation_chest(parameters) {
                function wrap(core) {
                    return (new Promise(function (resolve, reject) { resolve(core()); }));
                }
                var subject = make(parameters);
                return {
                    "setup": function (input) { return Promise.resolve(undefined); },
                    "clear": function () { return wrap(function () { return clear(subject); }); },
                    "write": function (key, value) { return wrap(function () { return write(subject, key, value); }); },
                    "delete": function (key) { return wrap(function () { return delete_(subject, key); }); },
                    "read": function (key) { return wrap(function () { return read(subject, key); }); },
                    "search": function (term) { return wrap(function () { return search(subject, term); }); }
                };
            }
            memory.implementation_chest = implementation_chest;
        })(memory = storage.memory || (storage.memory = {}));
    })(storage = lib_plankton.storage || (lib_plankton.storage = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var storage;
    (function (storage) {
        var memory;
        (function (memory) {
            /**
             * @author fenris
             */
            var class_chest = /** @class */ (function () {
                function class_chest(parameters) {
                    this.subject = memory.make(parameters);
                }
                class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); };
                class_chest.prototype.clear = function () { memory.clear(this.subject); return Promise.resolve(undefined); };
                class_chest.prototype.write = function (key, value) { return Promise.resolve(memory.write(this.subject, key, value)); };
                class_chest.prototype["delete"] = function (key) { memory.delete_(this.subject, key); return Promise.resolve(undefined); };
                class_chest.prototype.read = function (key) { return Promise.resolve(memory.read(this.subject, key)); };
                class_chest.prototype.search = function (term) { return Promise.resolve(memory.search(this.subject, term)); };
                return class_chest;
            }());
            memory.class_chest = class_chest;
        })(memory = storage.memory || (storage.memory = {}));
    })(storage = lib_plankton.storage || (lib_plankton.storage = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var storage;
    (function (storage) {
        var localstorage;
        (function (localstorage) {
            /**
             * @author fenris
             */
            function make(parameters) {
                parameters = Object.assign({
                    "corner": "plankton"
                }, parameters);
                return {
                    "corner": parameters.corner
                };
            }
            localstorage.make = make;
            /**
             */
            function compose_full_key(subject, key) {
                return (subject.corner + "_" + key);
            }
            /**
             */
            function decompose_full_key(subject, full_key) {
                var parts = full_key.split("_");
                return ((parts[0] === subject.corner)
                    ? parts.slice(1).join("_")
                    : null);
            }
            /**
             * @author fenris
             */
            function has(subject, key) {
                return localStorage.hasOwnProperty(compose_full_key(subject, key));
            }
            /**
             * @author fenris
             */
            function clear(subject) {
                (Object.keys(localStorage)
                    .map(function (x) { return decompose_full_key(subject, x); })
                    .filter(function (x) { return (x !== null); })
                    .forEach(function (x) { return localStorage.removeItem(x); }));
            }
            localstorage.clear = clear;
            /**
             * @author fenris
             */
            function write(subject, key, item) {
                var exists = has(subject, key);
                localStorage.setItem(compose_full_key(subject, key), item);
                return exists;
            }
            localstorage.write = write;
            /**
             * @author fenris
             */
            function delete_(subject, key) {
                localStorage.removeItem(compose_full_key(subject, key));
            }
            localstorage.delete_ = delete_;
            /**
             * @author fenris
             */
            function read(subject, key) {
                var full_key = compose_full_key(subject, key);
                if (!localStorage.hasOwnProperty(full_key)) {
                    throw (new Error("not found"));
                }
                else {
                    return localStorage.getItem(full_key);
                }
            }
            localstorage.read = read;
            /**
             * @author fenris
             */
            function list(subject) {
                return (Object.keys(localStorage)
                    .map(function (x) { return decompose_full_key(subject, x); })
                    .filter(function (x) { return (x !== null); }));
            }
            localstorage.list = list;
            /**
             */
            function implementation_chest(parameters) {
                function wrap(core) {
                    return (new Promise(function (resolve, reject) { resolve(core()); }));
                }
                var subject = make(parameters);
                return {
                    "setup": function (input) { return Promise.resolve(undefined); },
                    "clear": function () { return wrap(function () { return clear(subject); }); },
                    "write": function (key, item) { return wrap(function () { return write(subject, key, item); }); },
                    "delete": function (key) { return wrap(function () { return delete_(subject, key); }); },
                    "read": function (key) { return wrap(function () { return read(subject, key); }); },
                    "search": function (term) { return Promise.resolve(list(subject)
                        .map(function (key) { return ({ "key": key, "preview": key }); })); }
                };
            }
            localstorage.implementation_chest = implementation_chest;
        })(localstorage = storage.localstorage || (storage.localstorage = {}));
    })(storage = lib_plankton.storage || (lib_plankton.storage = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:storage«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:storage« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:storage« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:storage«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var storage;
    (function (storage) {
        var localstorage;
        (function (localstorage) {
            /**
             * uses the browsers localstorage as chest
             *
             * @author fenris
             */
            var class_chest = /** @class */ (function () {
                function class_chest(parameters) {
                    this.subject = localstorage.make(parameters);
                }
                class_chest.prototype.setup = function (input) { return Promise.resolve(undefined); };
                class_chest.prototype.clear = function () { return Promise.resolve(localstorage.clear(this.subject)); };
                class_chest.prototype.write = function (key, value) { return Promise.resolve(localstorage.write(this.subject, key, value)); };
                class_chest.prototype["delete"] = function (key) { return Promise.resolve(localstorage.delete_(this.subject, key)); };
                class_chest.prototype.read = function (key) { return Promise.resolve(localstorage.read(this.subject, key)); };
                class_chest.prototype.search = function (term) {
                    return Promise.resolve(localstorage.list(this.subject)
                        .map(function (key) { return ({ "key": key, "preview": key }); }));
                };
                return class_chest;
            }());
            localstorage.class_chest = class_chest;
        })(localstorage = storage.localstorage || (storage.localstorage = {}));
    })(storage = lib_plankton.storage || (lib_plankton.storage = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_1) {
        /**
         * @author fenris
         */
        function inspection_create() {
            return {
                "flaws": [],
                "sub": []
            };
        }
        shape_1.inspection_create = inspection_create;
        /**
         * @author fenris
         */
        function inspection_add(main, flaw) {
            main.flaws.push(flaw);
        }
        shape_1.inspection_add = inspection_add;
        /**
         * @author fenris
         */
        function inspection_extend(main, prefix, sub) {
            if ((sub.flaws.length <= 0)
                &&
                    (sub.sub.length <= 0)) {
                // do nothing
            }
            else {
                main.sub.push({ "position": prefix, "inspection": sub });
            }
        }
        shape_1.inspection_extend = inspection_extend;
        /**
         */
        function inspection_flatten(inspection) {
            return (inspection.flaws
                .concat(inspection.sub
                .map((entry) => (inspection_flatten(entry.inspection)
                .map(rest => lib_plankton.string.coin("[{{position}}] {{rest}}", {
                "position": entry.position,
                "rest": rest
            }))))
                .reduce((x, y) => x.concat(y), [])));
        }
        /**
         */
        var _pool = {};
        /**
         * @todo cache
         */
        function construct(shape) {
            return _pool[shape.kind].construct(shape.parameters);
        }
        /**
         */
        function get_logic(shape) {
            if (!(shape.kind in _pool)) {
                throw (new Error("missing shape: " + shape.kind));
            }
            else {
                return _pool[shape.kind].logic(construct(shape));
            }
        }
        /**
         */
        function inspect(shape, value) {
            return get_logic(shape).inspect(inspect, value);
        }
        shape_1.inspect = inspect;
        /**
         */
        function inspect_flat(shape, value) {
            return inspection_flatten(inspect(shape, value));
        }
        shape_1.inspect_flat = inspect_flat;
        /**
         */
        function show(shape) {
            return get_logic(shape).show(show);
        }
        shape_1.show = show;
        /**
         */
        function to_typescript_type(shape) {
            return get_logic(shape).to_typescript_type(to_typescript_type);
        }
        shape_1.to_typescript_type = to_typescript_type;
        /**
         */
        function to_jsonschema(shape) {
            return get_logic(shape).to_jsonschema(to_jsonschema);
        }
        shape_1.to_jsonschema = to_jsonschema;
        /**
         */
        function to_oas_schema(shape) {
            return get_logic(shape).to_oas_schema(to_oas_schema);
        }
        shape_1.to_oas_schema = to_oas_schema;
        /**
         */
        function example(shape) {
            return get_logic(shape).example(example);
        }
        shape_1.example = example;
        /**
         */
        function register(name, construct, logic) {
            _pool[name] = {
                "construct": construct,
                "logic": logic,
            };
        }
        shape_1.register = register;
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_2) {
        var any;
        (function (any) {
            /**
             */
            function make(options = {}) {
                return {};
            }
            any.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_2.inspection_create();
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                return "any";
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                return "any";
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                return {};
            }
            /**
             */
            function example(sub_example, subject) {
                return null;
            }
            shape_2.register("any", (parameters) => make({}), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(any = shape_2.any || (shape_2.any = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_3) {
        var null_;
        (function (null_) {
            /**
             */
            function make(options = {}) {
                return {};
            }
            null_.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_3.inspection_create();
                if (!(value === null)) {
                    shape_3.inspection_add(inspection, "null expected");
                }
                else {
                    // all good
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                return "null";
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                return "null";
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                return {
                    "type": "null",
                };
            }
            /**
             */
            function example(sub_example, subject) {
                return null;
            }
            shape_3.register("null", (parameters) => make({}), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(null_ = shape_3.null_ || (shape_3.null_ = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_4) {
        var boolean;
        (function (boolean) {
            /**
             */
            function make(options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": undefined,
                    "description": undefined,
                }, options);
                return {
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                };
            }
            boolean.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_4.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_4.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "boolean";
                    if (jstype_actual === jstype_expected) {
                        // all good
                    }
                    else {
                        shape_4.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        }));
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = "boolean";
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = "boolean";
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "boolean",
                };
                return (subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ],
                    }
                    : core);
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft ? null : false);
            }
            shape_4.register("boolean", (parameters) => make({
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(boolean = shape_4.boolean || (shape_4.boolean = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_5) {
        var integer;
        (function (integer) {
            /**
             */
            function make(options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": undefined,
                    "description": undefined,
                    "minimum": undefined,
                    "maximum": undefined,
                }, options);
                return {
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                    "minimum": ((options.minimum === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.minimum)),
                    "maximum": ((options.minimum === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.maximum)),
                };
            }
            integer.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_5.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_5.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "number";
                    if (!(jstype_actual === jstype_expected)) {
                        shape_5.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        }));
                    }
                    else {
                        if (isNaN(parseInt(value))) {
                            shape_5.inspection_add(inspection, "value is not parsable to a valid int");
                        }
                        else {
                            // minimum
                            {
                                if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) {
                                    shape_5.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", {
                                        "minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0),
                                    }));
                                }
                                else {
                                    // do nothing
                                }
                            }
                            // maximum
                            {
                                if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) {
                                    shape_5.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", {
                                        "maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0),
                                    }));
                                }
                                else {
                                    // do nothing
                                }
                            }
                        }
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = "integer";
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = "number";
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "integer",
                    "minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x),
                    "maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x),
                };
                return (subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ],
                    }
                    : core);
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft ? null : 0);
            }
            shape_5.register("integer", (parameters) => make({
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
                "minimum": parameters.minimum,
                "maximum": parameters.maximum,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(integer = shape_5.integer || (shape_5.integer = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_6) {
        var float;
        (function (float) {
            /**
             */
            function make(options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": undefined,
                    "description": undefined,
                    "minimum": undefined,
                    "maximum": undefined,
                }, options);
                return {
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                    "minimum": ((options.minimum === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.minimum)),
                    "maximum": ((options.minimum === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.maximum)),
                };
            }
            float.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_6.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_6.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "number";
                    if (!(jstype_actual === jstype_expected)) {
                        shape_6.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        }));
                    }
                    else {
                        if (isNaN(parseInt(value))) {
                            shape_6.inspection_add(inspection, "value is not parsable to a valid float");
                        }
                        else {
                            // minimum
                            {
                                if (!lib_plankton.pod.distinguish(subject.minimum, () => true, x => (value >= x))) {
                                    shape_6.inspection_add(inspection, lib_plankton.string.coin("value is below the minimum of '{{minimum}}'", {
                                        "minimum": lib_plankton.pod.cull(subject.minimum).toFixed(0),
                                    }));
                                }
                                else {
                                    // do nothing
                                }
                            }
                            // maximum
                            {
                                if (!lib_plankton.pod.distinguish(subject.maximum, () => true, x => (value <= x))) {
                                    shape_6.inspection_add(inspection, lib_plankton.string.coin("value is beyond the maximum of '{{maximum}}'", {
                                        "maximum": lib_plankton.pod.cull(subject.maximum).toFixed(0),
                                    }));
                                }
                                else {
                                    // do nothing
                                }
                            }
                        }
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = "float";
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = "number";
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "float",
                    "minimum": lib_plankton.pod.distinguish(subject.minimum, () => undefined, x => x),
                    "maximum": lib_plankton.pod.distinguish(subject.maximum, () => undefined, x => x),
                };
                return (subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ],
                    }
                    : core);
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft ? null : 0);
            }
            shape_6.register("float", (parameters) => make({
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
                "minimum": parameters.minimum,
                "maximum": parameters.maximum,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(float = shape_6.float || (shape_6.float = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_7) {
        var string;
        (function (string) {
            /**
             */
            function make(options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": undefined,
                    "description": undefined,
                    "pattern": undefined,
                    "min_length": undefined,
                    "max_lenth": undefined,
                }, options);
                return {
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                    "pattern": ((options.pattern === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.pattern)),
                    "min_length": ((options.min_length === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.min_length)),
                    "max_length": ((options.max_length === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.max_length)),
                };
            }
            string.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_7.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_7.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "string";
                    if (!(jstype_actual === jstype_expected)) {
                        shape_7.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        }));
                    }
                    else {
                        const value_ = value;
                        // pattern
                        {
                            if (!lib_plankton.pod.distinguish(subject.pattern, () => true, x => (new RegExp(x)).test(value_))) {
                                shape_7.inspection_add(inspection, lib_plankton.string.coin("string does not match the pattern '{{pattern}}'", {
                                    "pattern": lib_plankton.pod.cull(subject.pattern),
                                }));
                            }
                            else {
                                // do nothing
                            }
                        }
                        // min_length
                        {
                            if (!lib_plankton.pod.distinguish(subject.min_length, () => true, x => (value_.length >= x))) {
                                shape_7.inspection_add(inspection, lib_plankton.string.coin("string is shorter than '{{min_length}}'", {
                                    "min_length": lib_plankton.pod.cull(subject.min_length).toFixed(0),
                                }));
                            }
                            else {
                                // do nothing
                            }
                        }
                        // max_length
                        {
                            if (!lib_plankton.pod.distinguish(subject.max_length, () => true, x => (value_.length <= x))) {
                                shape_7.inspection_add(inspection, lib_plankton.string.coin("string is longer than '{{max_length}}'", {
                                    "min_length": lib_plankton.pod.cull(subject.max_length).toFixed(0),
                                }));
                            }
                            else {
                                // do nothing
                            }
                        }
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = "string";
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = "string";
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "string",
                    // TODO: transform?
                    "pattern": lib_plankton.pod.distinguish(subject.pattern, () => undefined, x => x),
                    "minLength": lib_plankton.pod.distinguish(subject.min_length, () => undefined, x => x),
                    "maxLenth": lib_plankton.pod.distinguish(subject.max_length, () => undefined, x => x),
                };
                return (subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ],
                    }
                    : core);
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft ? null : "");
            }
            shape_7.register("string", (parameters) => make({
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
                "pattern": parameters.pattern,
                "min_length": parameters.min_length,
                "max_length": parameters.max_length,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(string = shape_7.string || (shape_7.string = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_8) {
        var email;
        (function (email) {
            /**
             */
            function make(options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": undefined,
                    "description": undefined,
                }, options);
                return {
                    "core": {
                        "kind": "string",
                        "parameters": {
                            "soft": options.soft,
                            "defaultvalue": options.defaultvalue,
                            "description": options.description,
                            "pattern": "[^@]*@[^@]*",
                            "min_length": 0,
                            "max_length": 255,
                        }
                    },
                };
            }
            email.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                return sub_inspect(subject.core, value);
            }
            /**
             */
            function show(sub_show, subject) {
                return sub_show(subject.core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                return sub_to_typescript_type(subject.core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                return sub_to_jsonschema(subject.core);
            }
            /**
             */
            function example(sub_example, subject) {
                return sub_example(subject.core);
            }
            shape_8.register("email", (parameters) => make({
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_chema) => to_jsonschema(sub_to_oas_chema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(email = shape_8.email || (shape_8.email = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_9) {
        var list_;
        (function (list_) {
            /**
             */
            function make(shape_element, options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": lib_plankton.pod.make_empty(),
                    "description": lib_plankton.pod.make_empty(),
                }, options);
                return {
                    "shape_element": shape_element,
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                };
            }
            list_.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_9.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_9.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "object";
                    if (!(jstype_actual === jstype_expected)) {
                        lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        });
                    }
                    else {
                        if (!(value instanceof Array)) {
                            shape_9.inspection_add(inspection, "value does not seem to be an array-instance");
                        }
                        else {
                            value.forEach((element, index) => {
                                shape_9.inspection_extend(inspection, lib_plankton.string.coin("element #{{index}}", {
                                    "index": index.toFixed(0),
                                }), 
                                // subject.shape_element.inspect(element)
                                sub_inspect(subject.shape_element, element));
                            });
                        }
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = lib_plankton.string.coin("list<{{element}}>", {
                    "element": sub_show(subject.shape_element),
                });
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = lib_plankton.string.coin("Array<{{element}}>", {
                    "element": sub_to_typescript_type(subject.shape_element),
                });
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "array",
                    "items": sub_to_jsonschema(subject.shape_element),
                };
                return ((subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ]
                    }
                    : core));
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft
                    ? null
                    : [
                        sub_example(subject.shape_element)
                    ]);
            }
            shape_9.register("list", (parameters) => make(parameters.shape_element, {
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(list_ = shape_9.list_ || (shape_9.list_ = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_10) {
        var map;
        (function (map) {
            /**
             */
            function make(shape_key, shape_value, options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": lib_plankton.pod.make_empty(),
                    "description": lib_plankton.pod.make_empty(),
                }, options);
                return {
                    "shape_key": shape_key,
                    "shape_value": shape_value,
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                };
            }
            map.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_10.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_10.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "object";
                    if (!(jstype_actual === jstype_expected)) {
                        lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        });
                    }
                    else {
                        Object.entries(value)
                            .forEach(([key, value]) => {
                            shape_10.inspection_extend(inspection, lib_plankton.string.coin("key '{{key}}'", {
                                "key": String(key),
                            }), sub_inspect(subject.shape_key, key));
                            shape_10.inspection_extend(inspection, lib_plankton.string.coin("value for '{{key}}'", {
                                "key": String(key),
                            }), sub_inspect(subject.shape_value, value));
                        });
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = lib_plankton.string.coin("map<{{key}},{{value}}>", {
                    "key": sub_show(subject.shape_key),
                    "value": sub_show(subject.shape_value),
                });
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = lib_plankton.string.coin("Record<{{key}},{{value}}>", {
                    "key": sub_to_typescript_type(subject.shape_key),
                    "value": sub_to_typescript_type(subject.shape_key),
                });
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "object",
                    "additionalProperties": sub_to_jsonschema(subject.shape_value),
                    "properties": {},
                    "required": [],
                };
                return ((subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ]
                    }
                    : core));
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft
                    ? null
                    : {});
            }
            shape_10.register("map", (parameters) => make(parameters.shape_key, parameters.shape_value, {
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(map = shape_10.map || (shape_10.map = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:shape« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:shape« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:shape«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var shape;
    (function (shape_11) {
        var record;
        (function (record) {
            /**
             */
            function make(fields_raw, options = {}) {
                options = Object.assign({
                    "soft": false,
                    "defaultvalue": lib_plankton.pod.make_empty(),
                    "description": lib_plankton.pod.make_empty(),
                }, options);
                return {
                    "fields": fields_raw.map(field_raw => ({
                        "name": field_raw.name,
                        "shape": field_raw.shape,
                        "required": (field_raw.required ?? true)
                    })),
                    "soft": options.soft,
                    "defaultvalue": ((options.defaultvalue === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.defaultvalue)),
                    "description": ((options.description === undefined)
                        ? lib_plankton.pod.make_empty()
                        : lib_plankton.pod.make_filled(options.description)),
                };
            }
            record.make = make;
            /**
             */
            function inspect(sub_inspect, subject, value) {
                let inspection = shape_11.inspection_create();
                if (value === null) {
                    if (subject.soft) {
                        // all good
                    }
                    else {
                        shape_11.inspection_add(inspection, "null is not allowed");
                    }
                }
                else {
                    const jstype_actual = typeof (value);
                    const jstype_expected = "object";
                    if (!(jstype_actual === jstype_expected)) {
                        shape_11.inspection_add(inspection, lib_plankton.string.coin("expected JS-type '{{expected}}' but got '{{actual}}'", {
                            "expected": jstype_expected,
                            "actual": jstype_actual,
                        }));
                    }
                    else {
                        subject.fields.forEach(field => {
                            if (!(field.name in value)) {
                                if (field.required) {
                                    shape_11.inspection_add(inspection, "missing field '" + field.name + "'");
                                }
                                else {
                                    // do nothing
                                }
                            }
                            else {
                                const value_ = value[field.name];
                                shape_11.inspection_extend(inspection, ("field '" + field.name + "'"), sub_inspect(field.shape, value_));
                            }
                        });
                        // extra fields
                        {
                            const allowed = subject.fields.map(field => field.name);
                            (Object.keys(value)
                                .filter(name => (!allowed.includes(name)))
                                .forEach(name => {
                                shape_11.inspection_add(inspection, "extra field '" + name + "'");
                            }));
                        }
                    }
                }
                return inspection;
            }
            /**
             */
            function show(sub_show, subject) {
                const core = lib_plankton.string.coin("record<{{fields}}>", {
                    "fields": (subject.fields
                        .map(field => lib_plankton.string.coin("{{prefix}}{{name}}:{{shape}}", {
                        "prefix": (field.required ? "" : "?"),
                        "name": field.name,
                        "shape": sub_show(field.shape),
                    }))
                        .join(",")),
                });
                return (subject.soft ? ("~" + core) : core);
            }
            /**
             */
            function to_typescript_type(sub_to_typescript_type, subject) {
                const core = lib_plankton.string.coin("{{{fields}}}", {
                    "fields": (subject.fields
                        .map(field => lib_plankton.string.coin("{{name}}{{infix}}{{shape}}", {
                        "name": field.name,
                        "infix": (field.required ? ":" : "?:"),
                        "shape": sub_to_typescript_type(field.shape),
                    }))
                        .join(";")),
                });
                return (subject.soft ? ("(null | " + core + ")") : core);
            }
            /**
             */
            function to_jsonschema(sub_to_jsonschema, subject) {
                const common = {
                    "description": lib_plankton.pod.distinguish(subject.description, () => undefined, x => x),
                    "default": lib_plankton.pod.distinguish(subject.defaultvalue, () => undefined, x => x),
                };
                const core = {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": (Object.fromEntries(subject.fields
                        .map(field => ([
                        field.name,
                        sub_to_jsonschema(field.shape)
                    ])))),
                    "required": (subject.fields
                        .filter(field => field.required)
                        .map(field => field.name)),
                };
                return ((subject.soft
                    ? {
                        "anyOf": [
                            Object.assign({ "type": "null" }, common),
                            Object.assign(core, common),
                        ]
                    }
                    : core));
            }
            /**
             */
            function example(sub_example, subject) {
                return (subject.soft
                    ? null
                    : (Object.fromEntries(subject.fields
                        .filter(field => field.required)
                        .map(field => ([
                        field.name,
                        sub_example(field.shape)
                    ])))));
            }
            shape_11.register("record", (parameters) => make((parameters.fields
                .map(field_raw => ({
                "name": field_raw.name,
                "shape": field_raw.shape,
                "required": field_raw.required,
            }))), {
                "soft": parameters.soft,
                "description": parameters.description,
                "defaultvalue": parameters.defaultvalue,
            }), (subject) => ({
                "inspect": (sub_inspect, value) => inspect(sub_inspect, subject, value),
                "show": (sub_show) => show(sub_show, subject),
                "to_typescript_type": (sub_to_typescript_type) => to_typescript_type(sub_to_typescript_type, subject),
                "to_jsonschema": (sub_to_jsonschema) => to_jsonschema(sub_to_jsonschema, subject),
                "to_oas_schema": (sub_to_oas_schema) => to_jsonschema(sub_to_oas_schema, subject),
                "example": (sub_example) => example(sub_example, subject),
            }));
        })(record = shape_11.record || (shape_11.record = {}));
    })(shape = lib_plankton.shape || (lib_plankton.shape = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:www_form«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:www_form« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:www_form«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var www_form;
    (function (www_form) {
        /**
         * @author fenris
         */
        function encode(source) {
            return (Object.entries(source)
                .map(function (_a) {
                var key = _a[0], value = _a[1];
                return (key + "=" + encodeURIComponent(value));
            })
                .join("&"));
        }
        www_form.encode = encode;
        /**
         * @author fenris
         */
        function decode(target) {
            return (Object.fromEntries(target.split("&")
                .map(function (part) {
                var components = part.split("=");
                var key = components[0];
                var value = decodeURIComponent(components.slice(1).join("="));
                return [key, value];
            })));
        }
        www_form.decode = decode;
    })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:www_form«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:www_form« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:www_form«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var www_form;
    (function (www_form) {
        /**
         * @author fenris
         */
        var class_www_form = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_www_form() {
            }
            /**
             * @implementation
             * @author fenris
             */
            class_www_form.prototype.encode = function (source) {
                return www_form.encode(source);
            };
            /**
             * @implementation
             * @author fenris
             */
            class_www_form.prototype.decode = function (target) {
                return www_form.decode(target);
            };
            return class_www_form;
        }());
        www_form.class_www_form = class_www_form;
    })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:url«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:url« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:url« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:url«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:url« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:url« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var url;
    (function (url_1) {
        /**
         * @author fenris
         */
        function encode(url) {
            let result = "";
            // scheme
            {
                if (url.scheme !== null) {
                    result += (url.scheme + ":");
                }
            }
            // host
            {
                if (url.host !== null) {
                    result += "//";
                    // username
                    {
                        if (url.username !== null) {
                            result += url.username;
                            // password
                            {
                                if (url.password !== null) {
                                    result += (":" + url.password);
                                }
                            }
                            result += "@";
                        }
                    }
                    result += url.host;
                }
            }
            // port
            {
                if (url.port !== null) {
                    result += (":" + url.port.toString());
                }
            }
            // path
            {
                if (url.path !== null) {
                    result += url.path;
                }
            }
            // query
            {
                if (url.query !== null) {
                    result += ("?" + url.query);
                }
            }
            // hash
            {
                if (url.hash !== null) {
                    result += ("#" + url.hash);
                }
            }
            return result;
        }
        url_1.encode = encode;
        /**
         * @author fenris
         * @todo arguments
         */
        function decode(url_raw) {
            const builtin_url = new URL(url_raw);
            return {
                "scheme": builtin_url.protocol.slice(0, -1),
                "host": builtin_url.hostname,
                "username": ((builtin_url.username !== "")
                    ?
                        builtin_url.username
                    :
                        null),
                "password": ((builtin_url.password !== "")
                    ?
                        builtin_url.password
                    :
                        null),
                "port": ((builtin_url.port !== "")
                    ?
                        parseInt(builtin_url.port)
                    :
                        null),
                "path": builtin_url.pathname,
                "query": builtin_url.search.slice(1),
                "hash": ((builtin_url.hash !== "")
                    ?
                        builtin_url.hash.slice(1)
                    :
                        null),
            };
        }
        url_1.decode = decode;
        /**
         * @author fenris
         */
        function implementation_code() {
            return {
                "encode": encode,
                "decode": decode,
            };
        }
        url_1.implementation_code = implementation_code;
    })(url = lib_plankton.url || (lib_plankton.url = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:url«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:url« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:url« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:url«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var url;
    (function (url) {
        /**
         * @author fenris
         */
        class class_url {
            /**
             * @author fenris
             */
            constructor() {
            }
            /**
             * @implementation
             * @author fenris
             */
            encode(x) {
                return url.encode(x);
            }
            /**
             * @implementation
             * @author fenris
             */
            decode(x) {
                return url.decode(x);
            }
        }
        url.class_url = class_url;
    })(url = lib_plankton.url || (lib_plankton.url = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:random«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:random« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:random« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:random«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var random;
    (function (random) {
        /**
         * @author fenris
         */
        function sequence(n) {
            return ((n <= 0) ? [] : sequence(n - 1).concat([n - 1]));
        }
        /**
         * @author fenris
         */
        function interpolate(x, y, t) {
            return (((1 - t) * x) + (t * y));
        }
        /**
         * @author fenris
         */
        var _statestack = [
            {
                "builtin": true,
                "seed": Date.now()
            },
        ];
        /**
         * @author fenris
         */
        function state_get() {
            return _statestack[_statestack.length - 1];
        }
        /**
         * @author fenris
         */
        function state_push(state) {
            _statestack.push(state);
        }
        random.state_push = state_push;
        /**
         * @author fenris
         */
        function state_pop() {
            if (_statestack.length <= 1) {
                throw (new Error("no state to pop"));
            }
            else {
                return _statestack.pop();
            }
        }
        random.state_pop = state_pop;
        /**
         * @author fenris
         */
        function seed_tick() {
            var state = state_get();
            state.seed = ((state.seed << 8) % 99767);
        }
        /**
         * @author fenris
         */
        function seed_get(tick) {
            if (tick === void 0) { tick = true; }
            if (tick) {
                seed_tick();
            }
            else {
                // do nothing
            }
            return state_get().seed;
        }
        /**
         * returns a random floating point number in the interval [0,1[
         *
         * @author fenris
         */
        function generate_unit() {
            if (state_get().builtin) {
                return Math.random();
            }
            else {
                return ((Math.sin(seed_get() << 8) + 1) / 2);
            }
        }
        random.generate_unit = generate_unit;
        /**
         * returns a random boolean value
         *
         * @param {float} [probability] the probability for the return-value "true"; default: 0.5
         * @author fenris
         */
        function generate_boolean(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "probability": 0.5
            }, options);
            return (generate_unit() < options.probability);
        }
        random.generate_boolean = generate_boolean;
        /**
         * returns a random integer number in the interval [a,b]
         *
         * @param {int} [minimum] the left side of the halfopen interval (i.e. the smallest included value in the range)
         * @param {int} [minimum] the right side of the halfopen interval (i.e. the smallest excluded value in the range)
         * @author fenris
         */
        function generate_integer(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "minimum": 0,
                "maximum": ((1 << 16) - 1)
            }, options);
            return Math.floor(interpolate(options.minimum, options.maximum + 1, generate_unit()));
        }
        random.generate_integer = generate_integer;
        random.generate_int = generate_integer;
        /**
         * returns a random floating point number in the given interval
         *
         * @author fenris
         */
        function generate_float(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "minimum": 0.0,
                "maximum": 1.0
            }, options);
            return interpolate(options.minimum, options.maximum, generate_unit());
        }
        random.generate_float = generate_float;
        /**
         * returns a random date
         *
         * @author fenris
         */
        function generate_date(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "minimum": new Date(0),
                "maximum": new Date(Date.now())
            }, options);
            return (new Date(generate_integer({
                "minimum": options.minimum.getTime(),
                "maximum": options.maximum.getTime()
            })));
        }
        random.generate_date = generate_date;
        /**
         * @author fenris
         */
        function generate_hexdigit() {
            return (this.generate_integer({ "minimum": 0, "maximum": 15 }).toString(16).toUpperCase());
        }
        random.generate_hexdigit = generate_hexdigit;
        /**
         * generates a random string with an optional prefix
         *
         * @author fenris
         */
        function generate_string(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "length": 8
            }, options);
            return (sequence(options.length)
                .map(function (x) { return generate_integer({ "minimum": 65, "maximum": 90 }); })
                .map(function (x) { return String.fromCharCode(x); })
                .join("")
                .toLowerCase());
        }
        random.generate_string = generate_string;
        /**
         * chooses a value randomly from a list of values with weights (a higher weight means a higher probability to be chosen)
         *
         * @author fenris
         */
        function choose_weighted(sets) {
            var sum = sets.reduce(function (sum, set_) { return (sum + set_.weight); }, 0);
            if (sum === 0) {
                throw (new Error("weights sum up to zero; are all zero or are negative weights included?"));
            }
            else {
                var position_1 = generate_unit();
                return (sets.reduce(function (current, set_) {
                    var next = { "index": null, "value": null };
                    next.index = (current.index + (set_.weight / sum));
                    next.value = (((current.index <= position_1) && (position_1 < next.index))
                        ? set_.value
                        : current.value);
                    return next;
                }, { "index": 0, "value": null }).value);
            }
        }
        random.choose_weighted = choose_weighted;
        /**
         * chooses a value randomly from a list of values with equal probabilities
         *
         * @author fenris
         */
        function choose_uniformly(values) {
            return (choose_weighted(values.map(function (value) { return ({ "weight": 1, "value": value }); })));
        }
        random.choose_uniformly = choose_uniformly;
        /**
         * @author fenris
         */
        function shuffle(list) {
            var list_ = [];
            list.forEach(function (element) {
                var index = generate_integer({ "minimum": 0, "maximum": list_.length });
                list_.splice(index, 0, element);
            });
            return list_;
        }
        random.shuffle = shuffle;
        /**
         * @author fenris
         */
        function generate_vowel() {
            return (choose_weighted([
                { "weight": 1.0, "value": "u" },
                { "weight": 4.0, "value": "o" },
                { "weight": 6.0, "value": "a" },
                { "weight": 4.0, "value": "e" },
                { "weight": 1.0, "value": "i" },
            ]));
        }
        random.generate_vowel = generate_vowel;
        /**
         * @author fenris
         */
        function generate_halfvowel() {
            return (choose_weighted([
                { "weight": 4.0, "value": "y" },
                { "weight": 1.0, "value": "w" },
            ]));
        }
        random.generate_halfvowel = generate_halfvowel;
        /**
         * @author fenris
         */
        function generate_consonant() {
            return (choose_weighted([
                { "weight": 5.0, "value": "l" },
                { "weight": 5.0, "value": "m" },
                { "weight": 5.0, "value": "n" },
                { "weight": 4.0, "value": "b" },
                { "weight": 4.0, "value": "p" },
                { "weight": 4.0, "value": "d" },
                { "weight": 2.0, "value": "dj" },
                { "weight": 4.0, "value": "t" },
                { "weight": 2.0, "value": "tc" },
                { "weight": 4.0, "value": "g" },
                { "weight": 4.0, "value": "k" },
                { "weight": 3.0, "value": "v" },
                { "weight": 3.0, "value": "f" },
                { "weight": 3.0, "value": "z" },
                { "weight": 3.0, "value": "s" },
                { "weight": 3.0, "value": "j" },
                { "weight": 3.0, "value": "c" },
                { "weight": 2.0, "value": "r" },
                { "weight": 1.0, "value": "h" },
                { "weight": 1.0, "value": "x" },
            ]));
        }
        random.generate_consonant = generate_consonant;
        /**
         * @author fenris
         */
        function generate_letter() {
            return choose_uniformly([
                "a",
                "b",
                "c",
                "d",
                "e",
                "f",
                "g",
                "h",
                "i",
                "j",
                "k",
                "l",
                "m",
                "n",
                "o",
                "p",
                "q",
                "r",
                "s",
                "t",
                "u",
                "v",
                "w",
                "x",
                "y",
                "z",
            ]);
        }
        random.generate_letter = generate_letter;
        /**
         * @author fenris
         */
        function generate_syllable() {
            return (generate_consonant()
                +
                    generate_vowel()
                +
                    (generate_boolean({ "probability": 1 / 8 })
                        ? generate_halfvowel()
                        : "")
                +
                    (generate_boolean({ "probability": 1 / 4 })
                        ? generate_consonant()
                        : ""));
        }
        random.generate_syllable = generate_syllable;
        /**
         * @author fenris
         */
        function generate_word(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "syllable_count_minimum": 2,
                "syllable_count_maximum": 5
            }, options);
            return (sequence(generate_integer({
                "minimum": options.syllable_count_minimum,
                "maximum": options.syllable_count_maximum
            }))
                .map(function (x) { return generate_syllable(); })
                .join(""));
        }
        random.generate_word = generate_word;
        /**
         * @author fenris
         */
        function generate_text(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "word_count": generate_integer({ "minimum": 20, "maximum": 80 })
            }, options);
            return sequence(options.word_count).map(function (x) { return generate_word(); }).join(" ");
        }
        random.generate_text = generate_text;
        /**
         * @author fenris
         */
        function generate_city() {
            var str = (
            // prefix
            (generate_boolean({ "probability": 0.25 })
                ? choose_uniformly([
                    "unter",
                    "ober",
                    "mittel",
                    "groß",
                    "klein",
                    "neu",
                    "alt",
                ])
                : "")
                +
                    // infix
                    choose_uniformly([
                        "stein",
                        "frei",
                        "berns",
                        "kirch",
                        "fels",
                        "weiden",
                        "buchen",
                        "eichen",
                        "eiben",
                        "linden",
                        "ulmen",
                        "birken",
                        "eschen",
                        "erlen",
                        "grün",
                        "kreuz",
                        "wald",
                        "reichen",
                        "lieben",
                        "schön",
                        "heinrichs",
                        "friedrichs",
                        "johann",
                        "walters",
                        "günthers",
                        "rupperts",
                        "wilhems",
                        "albert",
                    ])
                +
                    // suffix
                    choose_uniformly([
                        "feld",
                        "thal",
                        "berg",
                        "burg",
                        "stadt",
                        "dorf",
                        "heim",
                        "bach",
                        "au",
                        "rode",
                        "ing",
                        "nitz",
                        "hausen",
                    ]));
            return (str[0].toUpperCase() + str.substring(1));
        }
        random.generate_city = generate_city;
        /**
         * @author fenris
         */
        function generate_street() {
            var str = (
            // prefix
            choose_uniformly([
                "haupt",
                "neben",
                "bahnhof",
                "markt",
                "augustus",
                "wilhelm",
                "albert",
                "friedrich",
                "maximilian",
                "wagner",
                "linden",
                "eichen",
                "buchen",
                "tannen",
                "pappel",
                "ulmen",
                "eschen",
            ])
                +
                    // core
                    choose_uniformly([
                        "straße",
                        "weg",
                        "allee",
                        "pfad",
                        "hain",
                        "anger",
                        "passage",
                        "platz",
                    ])
                +
                    // number
                    (" " + generate_integer({ "minimum": 1, "maximum": 80 }).toString()));
            return (str[0].toUpperCase() + str.substring(1));
        }
        random.generate_street = generate_street;
        /**
         * @author fenris
         */
        function generate_guid(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "with_braces": false
            }, options);
            /*
            return (
                [8,4,4,4,12]
                .map(length => sequence(length).map(_ => this.generate_hexdigit()).join(""))
                .join("-")
            );
             */
            var guid = ("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(new RegExp("[xy]", "g"), function (symbol) {
                var r = generate_integer({ "minimum": 0, "maximum": 15 });
                var v = ((symbol == "y") ? ((r & 0x3) | 0x8) : r);
                return (v.toString(16).toUpperCase());
            }));
            return (options.with_braces
                ? ("{" + guid + "}")
                : guid);
        }
        random.generate_guid = generate_guid;
        /**
         * @author fenris
         */
        function generate_domain(options) {
            if (options === void 0) { options = {}; }
            options = lib_plankton.base.object_merge({
                "steps": 3
            }, options);
            return (sequence(generate_integer({ "minimum": 1, "maximum": options.steps }))
                .map(function () { return generate_word(); })
                // tld
                .concat(sequence(generate_integer({ "minimum": 2, "maximum": 3 }))
                .map(function () { return generate_letter(); })
                .join(""))).join(".");
        }
        /**
         * @author fenris
         */
        function generate_url() {
            return (lib_plankton.url.encode({
                "scheme": choose_uniformly([
                    "http",
                    "https",
                    "git",
                    "smb",
                    "ftp",
                ]),
                "host": generate_domain(),
                "username": null,
                "password": null,
                "port": generate_integer({ "minimum": 20, "maximum": 99999 }),
                "path": ("/"
                    +
                        (sequence(generate_integer({ "minimum": 0, "maximum": 3 }))
                            .map(function () { return generate_word(); })
                            .join("/"))),
                "query": choose_uniformly([
                    null,
                    lib_plankton.www_form.encode(Object.fromEntries(sequence(generate_integer({ "minimum": 0, "maximum": 3 }))
                        .map(function () { return ([
                        generate_word(),
                        generate_integer().toFixed(0),
                    ]); }))),
                ]),
                "hash": null
            }));
        }
        random.generate_url = generate_url;
        /**
         * @author fenris
         */
        function generate_email_address() {
            return (
            // user
            generate_word()
                +
                    "@"
                +
                    generate_domain({ "steps": 1 }));
        }
        random.generate_email_address = generate_email_address;
        /**
         * @author fenris
         */
        function generate_telephone_number() {
            return (
            // country prefix
            ("+"
                +
                    generate_integer({ "minimum": 1, "maximum": 999 }).toFixed(0))
                +
                    " "
                +
                    // provider
                    +(sequence(3)
                        .map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); })
                        .join(""))
                +
                    " "
                +
                    // custom
                    +(sequence(7)
                        .map(function () { return generate_integer({ "minimum": 0, "maximum": 9 }); })
                        .join("")));
        }
        random.generate_telephone_number = generate_telephone_number;
        /**
         * @author fenris
         */
        function generate_time() {
            return {
                "hour": generate_integer({ "minimum": 0, "maximum": 23 }),
                "minute": generate_integer({ "minimum": 0, "maximum": 59 }),
                "second": generate_integer({ "minimum": 0, "maximum": 59 })
            };
        }
        random.generate_time = generate_time;
        /**
         * @author fenris
         * @deprecated
         * @todo remove
         */
        function generate_for_shape(shape) {
            throw (new Error("deprecated! use lib_shape!"));
        }
        random.generate_for_shape = generate_for_shape;
        /**
         * @author fenris
         */
        /*
        export function generate_for_shape_(
            shape : lib_plankton.shape.type_shape
        ) : any
        {
            switch (shape.name) {
                case "boolean": {
                    return generate_boolean();
                    break;
                }
                case "int": {
                    const min = shape.parameters["min"];
                    const max = shape.parameters["max"];
                    return generate_integer(
                        {
                            "minimum": ((min == null) ? undefined : min),
                            "maximum": ((max == null) ? undefined : max),
                        }
                    );
                    break;
                }
                case "float": {
                    return generate_float(
                        {
                            "minimum": shape.parameters["min"],
                            "maximum": shape.parameters["max"],
                        }
                    );
                    break;
                }
                case "string": {
                    return generate_string();
                    break;
                }
                case "url": {
                    return generate_url();
                    break;
                }
                case "email": {
                    return generate_email_address();
                    break;
                }
                case "time": {
                    return generate_time();
                    break;
                }
                case "array": {
                    return (
                        sequence(generate_integer({"minimum": 2, "maximum": 5}))
                        .map(() => generate_for_shape_(shape.parameters["shape_element"]))
                    );
                    break;
                }
                case "object": {
                    return Object.fromEntries(
                        shape.parameters["fields"]
                        .map(
                            field => ([
                                field["name"],
                                generate_for_shape_(field["shape"]),
                            ])
                        )
                    );
                    break;
                }
                case "date": {
                    return generate_date();
                    break;
                }
                case "enumeration": {
                    return choose_uniformly<any>(shape.parameters["options"])["value"];
                    break;
                }
                default: {
                    const message : string = `unhandled shape kind '${shape.name}'`;
                    // console.warn(message);
                    // return null;
                    throw (new Error(message));
                    break;
                }
            }
        }
         */
    })(random = lib_plankton.random || (lib_plankton.random = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:map«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:map« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:map«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:map« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var map;
    (function (map_1) {
        /**
         */
        function clear(map) {
            map.iterate(function (value, key) {
                map["delete"](key);
            });
        }
        map_1.clear = clear;
        /**
         */
        function keys(map) {
            var keys = [];
            map.iterate(function (value, key) {
                keys.push(key);
            });
            return keys;
        }
        map_1.keys = keys;
        /**
         */
        function values(map) {
            var values = [];
            map.iterate(function (value, key) {
                values.push(value);
            });
            return values;
        }
        map_1.values = values;
        /**
         */
        function dump(map) {
            var pairs = [];
            map.iterate(function (value, key) {
                pairs.push({ "key": key, "value": value });
            });
            return pairs;
        }
        map_1.dump = dump;
        /**
         */
        function show(map, options) {
            if (options === void 0) { options = {}; }
            options = Object.assign({
                "show_key": instance_show,
                "show_value": instance_show
            }, options);
            return ("["
                +
                    (dump(map)
                        .map(function (_a) {
                        var key = _a["key"], value = _a["value"];
                        return (options.show_key(key)
                            +
                                " -> "
                            +
                                options.show_value(value));
                    })
                        .join(", "))
                +
                    "]");
        }
        map_1.show = show;
    })(map = lib_plankton.map || (lib_plankton.map = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:map«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:map« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var map;
    (function (map) {
        var simplemap;
        (function (simplemap) {
            /**
             */
            function make(options) {
                if (options === void 0) { options = {}; }
                options = Object.assign({
                    "data": {}
                }, options);
                return {
                    "data": options.data
                };
            }
            simplemap.make = make;
            /**
             */
            function size(subject) {
                return Object.keys(subject.data).length;
            }
            simplemap.size = size;
            /**
             */
            function has(subject, key) {
                return (key in subject.data);
            }
            simplemap.has = has;
            /**
             */
            function get_safe(subject, key) {
                if (key in subject.data) {
                    return lib_plankton.pod.make_filled(subject.data[key]);
                }
                else {
                    return lib_plankton.pod.make_empty();
                }
            }
            simplemap.get_safe = get_safe;
            /**
             */
            function get(subject, key, fallback) {
                if (fallback === void 0) { fallback = lib_plankton.pod.make_empty(); }
                if (key in subject.data) {
                    return subject.data[key];
                }
                else {
                    if (!lib_plankton.pod.is_filled(fallback)) {
                        throw (new Error("key not found"));
                    }
                    else {
                        return lib_plankton.pod.cull(fallback);
                    }
                }
            }
            simplemap.get = get;
            /**
             */
            function set(subject, key, value) {
                subject.data[key] = value;
            }
            simplemap.set = set;
            /**
             */
            function delete_(subject, key) {
                delete subject.data[key];
            }
            simplemap.delete_ = delete_;
            /**
             */
            function iterate(subject, procedure) {
                Object.entries(subject.data).forEach(function (_a) {
                    var key = _a[0], value = _a[1];
                    procedure(value, key);
                });
            }
            simplemap.iterate = iterate;
            /**
             */
            function implementation_map(subject) {
                return {
                    "size": function () { return size(subject); },
                    "has": function (key) { return has(subject, key); },
                    "get": function (key, fallback) { return get(subject, key, fallback); },
                    "set": function (key, value) { return set(subject, key, value); },
                    "delete": function (key) { return delete_(subject, key); },
                    "iterate": function (function_) { return iterate(subject, function_); }
                };
            }
            simplemap.implementation_map = implementation_map;
        })(simplemap = map.simplemap || (map.simplemap = {}));
    })(map = lib_plankton.map || (lib_plankton.map = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:map«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:map« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var map;
    (function (map) {
        var hashmap;
        (function (hashmap) {
            /**
             */
            function make(hashing, options) {
                if (options === void 0) { options = {}; }
                options = Object.assign({
                    "pairs": []
                }, options);
                var subject = {
                    "hashing": hashing,
                    "core": lib_plankton.map.simplemap.make({})
                };
                options.pairs.forEach(function (pair) {
                    set(subject, pair.key, pair.value);
                });
                return subject;
            }
            hashmap.make = make;
            /**
             */
            function size(subject) {
                return lib_plankton.map.simplemap.size(subject.core);
            }
            hashmap.size = size;
            /**
             */
            function has(subject, key) {
                return lib_plankton.map.simplemap.has(subject.core, subject.hashing(key));
            }
            hashmap.has = has;
            /**
             */
            function get(subject, key, fallback) {
                if (fallback === void 0) { fallback = lib_plankton.pod.make_empty(); }
                /*
                we have to adjust the fallback argument, so that it can be used in our underlying simplemap core
                therefore we pack the value together with any key as dummy
                 */
                return (lib_plankton.map.simplemap.get(subject.core, subject.hashing(key), lib_plankton.pod.propagate(fallback, function (value) { return ({
                    "key": key,
                    "value": value
                }); }))
                    .value);
            }
            hashmap.get = get;
            /**
             */
            function set(subject, key, value) {
                var key_ = subject.hashing(key);
                return (lib_plankton.map.simplemap.set(subject.core, key_, { "key": key, "value": value }));
            }
            hashmap.set = set;
            /**
             */
            function delete_(subject, key) {
                return (lib_plankton.map.simplemap.delete_(subject.core, subject.hashing(key)));
            }
            hashmap.delete_ = delete_;
            /**
             */
            function iterate(subject, procedure) {
                return (lib_plankton.map.simplemap.iterate(subject.core, function (_a, key_) {
                    var key = _a["key"], value = _a["value"];
                    procedure(value, key);
                }));
            }
            hashmap.iterate = iterate;
            /**
             */
            function implementation_map(subject) {
                return {
                    "size": function () { return size(subject); },
                    "has": function (key) { return has(subject, key); },
                    "get": function (key, fallback) { return get(subject, key, fallback); },
                    "set": function (key, value) { return set(subject, key, value); },
                    "delete": function (key) { return delete_(subject, key); },
                    "iterate": function (procedure) { return iterate(subject, procedure); }
                };
            }
            hashmap.implementation_map = implementation_map;
        })(hashmap = map.hashmap || (map.hashmap = {}));
    })(map = lib_plankton.map || (lib_plankton.map = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:map«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:map« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:map« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:map«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var map;
    (function (map) {
        var collatemap;
        (function (collatemap) {
            /**
             */
            function make(collation, options) {
                if (options === void 0) { options = {}; }
                options = Object.assign({
                    "pairs": []
                }, options);
                var subject = {
                    "collation": collation,
                    "pairs": []
                };
                options.pairs.forEach(function (pair) {
                    set(subject, pair.key, pair.value);
                });
                return subject;
            }
            collatemap.make = make;
            /**
             */
            function size(subject) {
                return subject.pairs.length;
            }
            collatemap.size = size;
            /**
             */
            function has(subject, key) {
                return (subject.pairs.some(function (pair) { return subject.collation(key, pair.key); }));
            }
            collatemap.has = has;
            /**
             * @todo use .find
             */
            function get(subject, key, fallback) {
                var value;
                var found = (subject.pairs
                    .some(function (pair) {
                    if (subject.collation(key, pair.key)) {
                        value = pair.value;
                        return true;
                    }
                    else {
                        return false;
                    }
                }));
                if (found) {
                    return value;
                }
                else {
                    if (!lib_plankton.pod.is_filled(fallback)) {
                        throw (new Error("key not found"));
                    }
                    else {
                        return lib_plankton.pod.cull(fallback);
                    }
                }
            }
            collatemap.get = get;
            /**
             */
            function set(subject, key, value) {
                var found = (subject.pairs
                    .some(function (pair) {
                    if (subject.collation(key, pair.key)) {
                        // pair.value = value;
                        return true;
                    }
                    else {
                        return false;
                    }
                }));
                if (found) {
                    // nothing
                }
                else {
                    subject.pairs.push({
                        "key": key,
                        "value": value
                    });
                }
            }
            collatemap.set = set;
            /**
             */
            function delete_(subject, key) {
                var index;
                var found = (subject.pairs
                    .some(function (pair, index_) {
                    if (subject.collation(key, pair.key)) {
                        index = index_;
                        return true;
                    }
                    else {
                        return false;
                    }
                }));
                if (found) {
                    subject.pairs.splice(index, 1);
                }
                else {
                    // do nothing
                }
            }
            collatemap.delete_ = delete_;
            /**
             */
            function iterate(subject, function_) {
                subject.pairs
                    .forEach(function (pair) {
                    function_(pair.value, pair.key);
                });
            }
            collatemap.iterate = iterate;
            /**
             */
            function implementation_map(subject) {
                return {
                    "size": function () { return size(subject); },
                    "has": function (key) { return has(subject, key); },
                    "get": function (key, fallback) { return get(subject, key, fallback); },
                    "set": function (key, value) { return set(subject, key, value); },
                    "delete": function (key) { return delete_(subject, key); },
                    "iterate": function (function_) { return iterate(subject, function_); }
                };
            }
            collatemap.implementation_map = implementation_map;
        })(collatemap = map.collatemap || (map.collatemap = {}));
    })(map = lib_plankton.map || (lib_plankton.map = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:set«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:set« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:set« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:set«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:set«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:set« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:set« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:set«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var set;
    (function (set_1) {
        /**
         */
        function clear(set) {
            set.iterate(function (element) {
                set.remove(element);
            });
        }
        set_1.clear = clear;
        /**
         */
        function dump(set) {
            var elements = [];
            set.iterate(function (element) {
                elements.push(element);
            });
            return elements;
        }
        set_1.dump = dump;
        /**
         */
        function show(set, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b["show_element"], show_element = _c === void 0 ? instance_show : _c;
            return ("{"
                +
                    (dump(set)
                        .map(function (element) { return (show_element(element)); })
                        .join(", "))
                +
                    "}");
        }
        set_1.show = show;
        /**
         */
        function map(construct, set, transformator) {
            var result = construct();
            set.iterate(function (element_from) {
                var element_to = transformator(element_from);
                result.add(element_to);
            });
            return result;
        }
        set_1.map = map;
        /**
         */
        function filter(construct, set, predicate) {
            var result = construct();
            set.iterate(function (element) {
                if (!predicate(element)) {
                    // do nothing
                }
                else {
                    result.add(element);
                }
            });
            return result;
        }
        set_1.filter = filter;
        /**
         */
        function subset(set1, set2) {
            var result;
            set1.iterate(function (element) {
                if (!set2.has(element)) {
                    result = false;
                }
                else {
                    // do nothing
                }
            });
            return result;
        }
        set_1.subset = subset;
        /**
         */
        function superset(set1, set2) {
            return subset(set2, set1);
        }
        set_1.superset = superset;
        /**
         */
        function equal(set1, set2) {
            return (subset(set1, set2)
                &&
                    superset(set1, set2));
        }
        set_1.equal = equal;
        /**
         */
        function empty(set) {
            return (set.size() <= 0);
        }
        set_1.empty = empty;
        /**
         */
        function union(construct, set1, set2) {
            var result = construct();
            set1.iterate(function (element) {
                result.add(element);
            });
            set2.iterate(function (element) {
                result.add(element);
            });
            return result;
        }
        set_1.union = union;
        /**
         */
        function intersection(construct, set1, set2) {
            var result = construct();
            set1.iterate(function (element) {
                if (!set2.has(element)) {
                    // do nothing
                }
                else {
                    result.add(element);
                }
            });
            return result;
        }
        set_1.intersection = intersection;
        /**
         */
        function difference(construct, set1, set2) {
            var result = construct();
            set1.iterate(function (element) {
                if (set2.has(element)) {
                    // do nothing
                }
                else {
                    result.add(element);
                }
            });
            return result;
        }
        set_1.difference = difference;
        /**
         */
        function symmetric_difference(construct, set1, set2) {
            // X $ Y = (X ∪ Y) \ (X ∩ Y)
            return (difference(construct, union(construct, set1, set2), intersection(construct, set1, set2)));
        }
        set_1.symmetric_difference = symmetric_difference;
    })(set = lib_plankton.set || (lib_plankton.set = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:set«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:set« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:set« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:set«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var set;
    (function (set) {
        var hashset;
        (function (hashset) {
            /**
             */
            function make(hashing, options) {
                if (options === void 0) { options = {}; }
                options = Object.assign({
                    "elements": []
                }, options);
                return {
                    "core": lib_plankton.map.hashmap.make(hashing, {
                        "pairs": (options.elements
                            .map(function (element) { return ({
                            "key": element,
                            "value": null
                        }); }))
                    })
                };
            }
            hashset.make = make;
            /**
             */
            function size(subject) {
                return lib_plankton.map.hashmap.size(subject.core);
            }
            hashset.size = size;
            /**
             */
            function has(subject, element) {
                return lib_plankton.map.hashmap.has(subject.core, element);
            }
            hashset.has = has;
            /**
             */
            function add(subject, element) {
                return lib_plankton.map.hashmap.set(subject.core, element, null);
            }
            hashset.add = add;
            /**
             */
            function remove(subject, element) {
                lib_plankton.map.hashmap.delete_(subject.core, element);
            }
            hashset.remove = remove;
            /**
             */
            function iterate(subject, procedure) {
                lib_plankton.map.hashmap.iterate(subject.core, function (value, key) { procedure(key); });
            }
            hashset.iterate = iterate;
            /**
             */
            function implementation_set(subject) {
                return {
                    "size": function () { return size(subject); },
                    "has": function (element) { return has(subject, element); },
                    "add": function (element) { return add(subject, element); },
                    "remove": function (element) { return remove(subject, element); },
                    "iterate": function (procedure) { return iterate(subject, procedure); }
                };
            }
            hashset.implementation_set = implementation_set;
        })(hashset = set.hashset || (set.hashset = {}));
    })(set = lib_plankton.set || (lib_plankton.set = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:set«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:set« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:set« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:set«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var set;
    (function (set) {
        var collateset;
        (function (collateset) {
            /**
             */
            function make(collation, options) {
                if (options === void 0) { options = {}; }
                options = Object.assign({
                    "elements": []
                }, options);
                return {
                    "core": lib_plankton.map.collatemap.make(collation, {
                        "pairs": (options.elements
                            .map(function (element) { return ({
                            "key": element,
                            "value": null
                        }); }))
                    })
                };
            }
            collateset.make = make;
            /**
             */
            function size(subject) {
                return lib_plankton.map.collatemap.size(subject.core);
            }
            collateset.size = size;
            /**
             */
            function has(subject, element) {
                return lib_plankton.map.collatemap.has(subject.core, element);
            }
            collateset.has = has;
            /**
             */
            function add(subject, element) {
                return lib_plankton.map.collatemap.set(subject.core, element, null);
            }
            collateset.add = add;
            /**
             */
            function remove(subject, element) {
                lib_plankton.map.collatemap.delete_(subject.core, element);
            }
            collateset.remove = remove;
            /**
             */
            function iterate(subject, procedure) {
                lib_plankton.map.collatemap.iterate(subject.core, function (key, value) { procedure(key); });
            }
            collateset.iterate = iterate;
            /**
             */
            function implementation_set(subject) {
                return {
                    "size": function () { return size(subject); },
                    "has": function (element) { return has(subject, element); },
                    "add": function (element) { return add(subject, element); },
                    "remove": function (element) { return remove(subject, element); },
                    "iterate": function (procedure) { return iterate(subject, procedure); }
                };
            }
            collateset.implementation_set = implementation_set;
        })(collateset = set.collateset || (set.collateset = {}));
    })(set = lib_plankton.set || (lib_plankton.set = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:cache«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:cache« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:cache«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:cache« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var cache;
    (function (cache_1) {
        /**
         */
        function make({ "chest": chest = lib_plankton.storage.memory.implementation_chest({}), } = {}) {
            return chest;
        }
        cache_1.make = make;
        /**
         */
        function init(subject) {
            return subject.setup(undefined);
        }
        cache_1.init = init;
        /**
         */
        function clear(subject) {
            return subject.clear();
        }
        cache_1.clear = clear;
        /**
         */
        function invalidate(subject, key) {
            return subject.delete(key);
        }
        cache_1.invalidate = invalidate;
        /**
         */
        async function query(subject, key, lifetime, retrieve) {
            const now = lib_plankton.base.get_current_timestamp();
            return ((subject.read(key)
                .then((entry) => Promise.resolve({
                "found": true,
                "entry": entry,
            }))
                .catch(() => Promise.resolve({
                "found": false,
                "entry": null,
            })))
                .then((item) => {
                if ((!item.found)
                    ||
                        ((item.entry.expiry !== null)
                            &&
                                (item.entry.expiry <= now))) {
                    lib_plankton.log.info("plankton.cache.unknown_or_expired", {
                        "key": key,
                    });
                    return (retrieve()
                        .then((value) => (subject.write(key, {
                        "value": value,
                        "expiry": ((lifetime === null)
                            ?
                                null
                            :
                                (now + lifetime))
                    })
                        .then(() => Promise.resolve({
                        "retrieved": true,
                        "value": value
                    })))));
                }
                else {
                    lib_plankton.log.info("plankton.cache.known_and_valid", {
                        "key": key,
                    });
                    return Promise.resolve({
                        "retrieved": false,
                        "value": item.entry.value
                    });
                }
            }));
        }
        cache_1.query = query;
        /**
         * syntactic sugar: if the information, whether the value was retrieved, is irrelevant
         */
        function get(subject, key, lifetime, retrieve) {
            return (query(subject, key, lifetime, retrieve)
                .then(result => Promise.resolve(result.value)));
        }
        cache_1.get = get;
        /**
         */
        function get_complex(cache, group, input, lifetime, retrieve, { "encode_input": encode_input = (input => JSON.stringify(input)), } = {}) {
            return get(cache, (group + "." + encode_input(input)), lifetime, () => retrieve(input));
        }
        cache_1.get_complex = get_complex;
    })(cache = lib_plankton.cache || (lib_plankton.cache = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:complex«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:complex« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:complex« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:complex«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var complex;
    (function (complex) {
        /**
         * @author fenris
         */
        function _sequence(n) {
            return ((n <= 0) ? [] : _sequence(n - 1).concat([n - 1]));
        }
        /**
         * @author fenris
         */
        function _coin(template, arguments_) {
            if (arguments_ === void 0) { arguments_ = {}; }
            var result = template;
            Object.keys(arguments_).forEach(function (key) {
                var pattern = ("{{" + key + "}}");
                var replacement = String(arguments_[key]);
                result = result.replace(new RegExp(pattern, "g"), replacement);
            });
            return result;
        }
        /**
         * erstellt eine komplexe Zahl anhand ihrer kartesianischen Koordinaten
         *
         * @author fenris
         */
        function make_cartesian(rea_, ima_) {
            return {
                "rea": rea_,
                "ima": ima_
            };
        }
        complex.make_cartesian = make_cartesian;
        /**
         * erstellt eine komplexe Zahl anhand ihrer Polar-Koordinaten
         *
         * @author fenris
         */
        function make_polar(abs, arg) {
            return (make_cartesian((abs * Math.cos(arg)), (abs * Math.sin(arg))));
        }
        complex.make_polar = make_polar;
        /**
         * alias zu "make_cartesian"
         *
         * @author fenris
         */
        function make(rea_, ima_) {
            return (make_cartesian(rea_, ima_));
        }
        complex.make = make;
        /**
         * erstellt die komplexe Null
         *
         * @author fenris
         */
        function nul() {
            return (make(0, 0));
        }
        complex.nul = nul;
        /**
         * erstellt die komplexe Eins
         *
         * @author fenris
         */
        function one() {
            return (make(1, 0));
        }
        complex.one = one;
        /**
         * gibt den Real-Teil einer komplexen Zahl zurück
         *
         * @author fenris
         */
        function rea(x) {
            return (x.rea);
        }
        complex.rea = rea;
        /**
         * gibt den Imaginär-Teil einer komplexen Zahl zurück
         *
         * @author fenris
         */
        function ima(x) {
            return (x.ima);
        }
        complex.ima = ima;
        /**
         * gibt die konjugierte komplexe Zahl zurück
         *
         * @author fenris
         */
        function con(x) {
            return (make(+x.rea, -x.ima));
        }
        complex.con = con;
        /**
         * gibt den quadrierten Betrag einer komplexen Zahl zurück
         *
         * @author fenris
         */
        function sqrabs(x) {
            return (((x.rea * x.rea) + (x.ima * x.ima)));
        }
        /**
         * gibt den Betrag einer komplexen Zahl zurück
         *
         * @author fenris
         */
        function abs(x) {
            return (Math.sqrt(sqrabs(x)));
        }
        complex.abs = abs;
        /**
         * gibt das Argument einer komplexen Zahl zurück (auf dem Hauptzweig des komplexen Logarithmus)
         *
         * @author fenris
         */
        function arg(x) {
            return Math.atan2(x.ima, x.rea);
        }
        complex.arg = arg;
        /**
         * gibt eine skalierte komplexe Zahl zurück (das Produkt mit einer reellen Zahl)
         *
         * @author fenris
         */
        function scl(x, s) {
            return (make((x.rea * s), (x.ima * s)));
        }
        complex.scl = scl;
        /**
         * errechnet die Summe zweier komplexer Zahl
         *
         * @author fenris
         */
        function add(x, y) {
            return (make((x.rea + y.rea), (x.ima + y.ima)));
        }
        complex.add = add;
        /**
         * gibt die additiv inverse, also negierte komplexe Zahl zurück
         *
         * @author fenris
         */
        function neg(x) {
            return (make(-x.rea, -x.ima));
        }
        complex.neg = neg;
        /**
         * ermittelt die Differenz zweier komplexer Zahlen
         *
         * @author fenris
         */
        function sub(x, y) {
            return (add(x, neg(y)));
        }
        complex.sub = sub;
        /**
         * ermittelt das Produkt zweier komplexer Zahlen
         *
         * @author fenris
         */
        function mul(x, y) {
            return (make(((x.rea * y.rea) - (x.ima * y.ima)), ((x.rea * y.ima) + (x.ima * y.rea))));
        }
        complex.mul = mul;
        /**
         * ermittelt die multiplikativ inverse komplexe Zahl, also den Kehrwert
         *
         * @author fenris
         */
        function inv(x) {
            var a = sqrabs(x);
            if (a <= 0) {
                var message = "die komplexe Null ist nicht invertiebar";
                throw (new Error(message));
            }
            else {
                return (scl(con(x), (1 / a)));
            }
        }
        complex.inv = inv;
        /**
         * ermittelt den Quotienten zweier komplexer Zahlen
         *
         * @author fenris
         */
        function div(x, y) {
            return (mul(x, inv(y)));
        }
        complex.div = div;
        /**
         * ermittelt die natürliche Potenz einer komplexen Zahl
         *
         * @author fenris
         */
        function npow(x, n) {
            if (n < 0) {
                var message = "invalid exponent";
                throw (new Error(message));
            }
            else {
                var y_1 = one();
                _sequence(n).forEach(function () { y_1 = mul(y_1, x); });
                return y_1;
            }
        }
        complex.npow = npow;
        /**
         * ermittelt den Wert der natürlichen Exponential-Funktion
         *
         * @author fenris
         */
        function exp(x) {
            return make_polar(Math.exp(x.rea), x.ima);
        }
        complex.exp = exp;
        /**
         * ermittelt die Potenz zweier komplexer Zahlen
         *
         * @author fenris
         * @todo Probleme der komplexen Exponentiation berücksichtigen
         */
        function pow(x, y) {
            var a = abs(x);
            var b = arg(x);
            var c = y.rea;
            var d = y.ima;
            if (a === 0) {
                throw (new Error("not implemented"));
            }
            else {
                var l = Math.log(a);
                return (make_polar(Math.exp((l * c) - (b * d)), ((l * d) + (b * c))));
            }
        }
        complex.pow = pow;
        /**
         * gibt die n-ten komplexen Einheits-Wurzeln zurück ({x ∈ C | x^n = 1})
         *
         * @author fenris
         */
        function unitroots(n) {
            return (_sequence(n)
                .map(function (k) { return make_polar(1, (k / (n + 0.0)) * (2 * Math.PI)); }));
        }
        complex.unitroots = unitroots;
        /**
         * {x ∈ C | x^n = y}
         *
         * @author fenris
         */
        function normroots(n, y) {
            var z = make_polar(Math.pow(abs(y), (1.0 / n)), (arg(y) / n));
            return (unitroots(n)
                .map(function (w) { return mul(w, z); }));
        }
        complex.normroots = normroots;
        /**
         * ermittelt ob zwei komplexe Zahlen gleich sind
         *
         * @author fenris
         */
        function equ(x, y, threshold) {
            if (threshold === void 0) { threshold = 0.005; }
            // return (abs(sub(x, y)) <= threshold);
            return ((Math.abs(x.rea - y.rea) <= threshold)
                &&
                    (Math.abs(x.ima - y.ima) <= threshold));
        }
        complex.equ = equ;
        /**
         * gibt eine textuelle Repräsentation einer komplexen Zahl zurück
         *
         * @author fenris
         */
        function str(x) {
            return _coin(
            // "(({{rea}}) + ({{ima}}·i))",
            "<{{rea}},{{ima}}>", {
                "rea": x.rea.toFixed(4),
                "ima": x.ima.toFixed(4)
            });
        }
        complex.str = str;
    })(complex = lib_plankton.complex || (lib_plankton.complex = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:complex«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:complex« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:complex« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:complex«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var complex;
    (function (complex) {
        /**
         * @author fenris
         */
        var class_complex = /** @class */ (function () {
            /**
             * @author fenris
             */
            function class_complex(subject) {
                this.subject = subject;
            }
            /**
             * @author fenris
             */
            class_complex._cram = function (subject) {
                return (new class_complex(subject));
            };
            /**
             * @author fenris
             */
            class_complex._tear = function (instance) {
                return instance.subject;
            };
            /**
             * @author fenris
             */
            class_complex.make_cartesian = function (rea, ima) {
                return (class_complex._cram(complex.make_cartesian(rea, ima)));
            };
            /**
             * @author fenris
             */
            class_complex.make_polar = function (abs, arg) {
                return (class_complex._cram(complex.make_polar(abs, arg)));
            };
            /**
             * @author fenris
             */
            class_complex.make = function (rea, ima) {
                return (class_complex._cram(complex.make(rea, ima)));
            };
            /**
             * @author fenris
             */
            class_complex.nul = function () {
                return (class_complex._cram(complex.nul()));
            };
            /**
             * @author fenris
             */
            class_complex.one = function () {
                return (class_complex._cram(complex.one()));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.con = function () {
                return (class_complex._cram(complex.con(class_complex._tear(this))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.abs = function () {
                return (complex.abs(class_complex._tear(this)));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.arg = function () {
                return (complex.arg(class_complex._tear(this)));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.scl = function (s) {
                return (class_complex._cram(complex.scl(class_complex._tear(this), s)));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.add = function (other) {
                return (class_complex._cram(complex.add(class_complex._tear(this), class_complex._tear(other))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.neg = function () {
                return (class_complex._cram(complex.neg(class_complex._tear(this))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.sub = function (other) {
                return (class_complex._cram(complex.sub(class_complex._tear(this), class_complex._tear(other))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.mul = function (other) {
                return (class_complex._cram(complex.mul(class_complex._tear(this), class_complex._tear(other))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.inv = function () {
                return (class_complex._cram(complex.inv(class_complex._tear(this))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.div = function (other) {
                return (class_complex._cram(complex.div(class_complex._tear(this), class_complex._tear(other))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.exp = function () {
                return (class_complex._cram(complex.exp(class_complex._tear(this))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.pow = function (other) {
                return (class_complex._cram(complex.pow(class_complex._tear(this), class_complex._tear(other))));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.equ = function (other) {
                return (complex.equ(class_complex._tear(this), class_complex._tear(other)));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.str = function () {
                return (complex.str(class_complex._tear(this)));
            };
            /**
             * @author fenris
             */
            class_complex.prototype.toString = function () {
                return this.str();
            };
            return class_complex;
        }());
        complex.class_complex = class_complex;
    })(complex = lib_plankton.complex || (lib_plankton.complex = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:math«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:math« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:math« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:math«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var math;
    (function (math) {
        /**
         * @desc golden ratio (e.g. for generating colors)
         * @author fenris
         */
        math.phi = ((Math.sqrt(5) - 1) / 2);
        /**
         * @author fenris
         */
        math.e = Math.E;
        /**
         * @author fenris
         */
        math.pi = Math.PI;
        /**
         * @author fenris
         */
        math.tau = (2 * Math.PI);
    })(math = lib_plankton.math || (lib_plankton.math = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:math«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:math« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:math« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:math«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var math;
    (function (math) {
        /**
         * @author fenris
         */
        function clamp(x, a = 0.0, b = 1.0) {
            return Math.min(Math.max(x, a), b);
        }
        math.clamp = clamp;
        /**
         * @desc the mathematical sign-function
         * @return {int} an element of {-1,0,+1}
         * @author fenris
         */
        function sgn(x) {
            if (x === 0) {
                return 0;
            }
            else {
                if (x < 0) {
                    return -1;
                }
                else /* (x > 0) */ {
                    return +1;
                }
            }
        }
        math.sgn = sgn;
        /**
         * @desc integer division
         * @author fenris
         */
        function div(x, y) {
            return Math.floor(x / y);
        }
        math.div = div;
        /**
         * @desc real modulo operator
         * @author fenris
         */
        function mod(x, y) {
            // return (x - (div(x, y) * y));
            if (y <= 0) {
                throw (new Error("invalid divisor"));
            }
            else {
                return ((x >= 0)
                    ? (x % y)
                    : ((y - ((-x) % y)) % y));
            }
        }
        math.mod = mod;
        /**
         * @desc computes "x^y mod z" via square-and-multiply
         * @param {int} base ("x")
         * @param {int} exponent ("y")
         * @param {int} modulus ("z")
         * @return {int}
         * @author fenris
         * @todo handle invalid cases (e.g. "z < 1")
         * @todo implement iteratively
         */
        function modpow(base, exponent, modulus) {
            /*
            The idea is the following:
            
              x^y
            = x^((y div 2)·2 + (y mod 2))
            = x^((y div 2)·2) · x^(y mod 2)
            = (x^(y div 2))^2 · x^(y mod 2)
            
            For computing (x^(y div 2)) the algorithm is used recursively. Building the square is done without any magic.
            The second factor is either 1 or x, since (y mod 2) is either 0 or 1; in other words: multiplying x to the first
            factor is only necessary if y is odd.
             */
            if (exponent === 0) {
                return 1;
            }
            else {
                let a = modpow(base, exponent >> 1, modulus);
                a = ((a * a) % modulus);
                if ((exponent & 1) != 0) {
                    a = ((a * base) % modulus);
                }
                return a;
            }
        }
        math.modpow = modpow;
        /**
         * @desc determines if two integers are coprime, i.e. that they don't have a common divisor greater than 1
         * @author fenris
         * @todo write function "gcdx" and base on it
         */
        function coprime(x, y) {
            if (y === 0) {
                return false;
            }
            else if (y === 1) {
                return true;
            }
            else {
                let z = mod(x, y);
                return coprime(y, z);
            }
        }
        math.coprime = coprime;
        /**
         * @desc extended euclidean algorithm for computing multiplicative inverse elements
         * @param {int} modulus
         * @param {int} element
         * @author fenris
         * @todo write function "gcdx" and base on it
         * @todo handle more invalid cases
         */
        function inv(modulus, element, positive = false) {
            if (element === 0) {
                throw (new Error("not invertable"));
            }
            else if (element === 1) {
                return 1;
            }
            else {
                let result = div(1 - (modulus * inv(element, mod(modulus, element), false)), element);
                return (positive ? mod(result, modulus) : result);
            }
        }
        math.inv = inv;
        /**
         * @author fenris
         */
        function interpolate_linear(x, y, t = 0.5) {
            return ((1 - t) * x + t * y);
        }
        math.interpolate_linear = interpolate_linear;
        /**
         * @desc kind of the inverse of linear interpolation; i.e. to find the coefficient "t" for given values x, y and
         *     their presumed interpolation v
         * @author fenris
         */
        function appoint_linear(x, y, v) {
            return ((v - x) / (y - x));
        }
        math.appoint_linear = appoint_linear;
        /**
         * continued fraction decomposition
         */
        function cfd(x, n = (1 << 4)) {
            let result = [];
            let m = 0;
            let y = x;
            while (true) {
                if (m >= n) {
                    break;
                }
                else {
                    const a = Math.floor(y);
                    result.push(a);
                    if (y === a) {
                        break;
                    }
                    else {
                        y = (1 / (y - a));
                        m += 1;
                    }
                }
            }
            return result;
        }
        math.cfd = cfd;
    })(math = lib_plankton.math || (lib_plankton.math = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:math«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:math« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:math« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:math«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var math;
    (function (math) {
        /**
         * @author fenris
         */
        class class_relation {
            /**
             * @author fenris
             */
            check(value, reference) {
                return this.predicate(value, reference);
            }
            /**
             * @author fenris
             */
            /*protected*/ constructor(id, { "symbol": symbol = null, "name": name = null, "predicate": predicate, }) {
                this.id = id;
                this.symbol = symbol;
                this.name = name;
                this.predicate = predicate;
            }
            /**
             * @author fenris
             */
            id_get() {
                return this.id;
            }
            /**
             * @author fenris
             */
            symbol_get() {
                return this.symbol;
            }
            /**
             * @author fenris
             */
            name_get() {
                return this.name;
            }
            /**
             * @desc [accessor] [implementation]
             * @author fenris
             */
            _show() {
                return `[${this.symbol}]`;
            }
            /**
             * @desc [accessor] [implementation]
             * @author fenris
             */
            _hash() {
                return this.id;
            }
            /**
             * @desc [accessor] [implementation]
             * @author fenris
             */
            _collate(relation) {
                return (this.id == relation.id);
            }
            /**
             * @author fenris
             */
            toString() {
                return this._show();
            }
            /**
             * @author fenris
             */
            static pool() {
                return {
                    "eq": {
                        "symbol": "=",
                        "name": "gleich",
                        "predicate": (value, reference) => (value == reference),
                    },
                    "ne": {
                        "symbol": "≠",
                        "name": "ungleich",
                        "predicate": (value, reference) => (value != reference),
                    },
                    "gt": {
                        "symbol": ">",
                        "name": "größer",
                        "predicate": (value, reference) => (value > reference),
                    },
                    "ge": {
                        "symbol": "≥",
                        "name": "größer oder gleich",
                        "predicate": (value, reference) => (value >= reference),
                    },
                    "lt": {
                        "symbol": "<",
                        "name": "kleiner",
                        "predicate": (value, reference) => (value < reference),
                    },
                    "le": {
                        "symbol": "≤",
                        "name": "kleiner oder gleich",
                        "predicate": (value, reference) => (value <= reference),
                    },
                };
            }
            /**
             * @author fenris
             */
            static get(id) {
                let pool = this.pool();
                if (id in pool) {
                    return (new class_relation(id, pool[id]));
                }
                else {
                    throw (new Error(`no such relation`));
                }
            }
            /**
             * @author fenris
             */
            static available() {
                return Object.keys(this.pool());
            }
        }
        math.class_relation = class_relation;
        /**
         * @author fenris
         */
        class class_filtrationitem {
            /**
             * @author fenris
             */
            constructor({ "extract": extract, "relation": relation, "reference": reference, }) {
                this.extract = extract;
                this.relation = relation;
                this.reference = reference;
            }
            /**
             * @author fenris
             */
            check(dataset) {
                let value = this.extract(dataset);
                let result = this.relation.check(value, this.reference);
                return result;
            }
            /**
             * @desc [implementation]
             * @author fenris
             */
            _show() {
                return `(${this.relation.symbol_get()} ${instance_show(this.reference)})`;
            }
            /**
             * @author fenris
             */
            toString() {
                return this._show();
            }
        }
        math.class_filtrationitem = class_filtrationitem;
        /**
         * @desc disjunctive normal form
         * @author fenris
         */
        class class_filtration {
            /**
             * @author fenris
             */
            constructor(clauses) {
                this.clauses = clauses;
            }
            /**
             * @author fenris
             */
            check(dataset) {
                return (this.clauses.some(clause => clause.every(literal => literal.check(dataset))));
            }
            /**
             * @author fenris
             */
            use(datasets) {
                return datasets.filter(dataset => this.check(dataset));
            }
            /**
             * @desc [implementation]
             * @author fenris
             */
            _show() {
                return ("{" + this.clauses.map(clause => ("[" + clause.map(instance_show).join(",") + "]")).join(",") + "}");
            }
            /**
             * @author fenris
             */
            toString() {
                return this._show();
            }
        }
        math.class_filtration = class_filtration;
        /**
         * @author fenris
         * @deprecated
         */
        function comparator_to_relation(comparator) {
            console.warn("deprecated!");
            return ((x, y) => (comparator(x, y) <= 0));
        }
        math.comparator_to_relation = comparator_to_relation;
        /**
         * @author fenris
         * @deprecated
         */
        function relation_to_comparator(relation) {
            console.warn("deprecated!");
            return ((x, y) => (relation(x, y) ? (relation(y, x) ? 0 : -1) : 1));
        }
        math.relation_to_comparator = relation_to_comparator;
    })(math = lib_plankton.math || (lib_plankton.math = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:math«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:math« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:math« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:math«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_calculus;
(function (lib_calculus) {
    /**
     * @class Calculus
     * @desc Ensure precision of mathematical operations
     */
    class Calculus {
        /**
         * @constructor
         * @þaram {number} norm
         */
        constructor(norm = 100000) {
            this.NORM = norm;
        }
        /**
         * normalize
         * @param {number} value
         * @return {number}
         */
        normalize(value) {
            return (Math.floor(value * this.NORM));
        }
        /**
         * denormalize
         * @param {number} value
         * @return {number}
         */
        denormalize(value) {
            return (Math.floor(value) / this.NORM);
        }
    }
    lib_calculus.Calculus = Calculus;
})(lib_calculus || (lib_calculus = {}));
/*
This file is part of »bacterio-plankton:math«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:math« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:math« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:math«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var math;
    (function (math) {
        /**
         * {x ∈ C | 0 = x³ + px + q}
         *
         * @author fenris
         */
        function cardano_reduced(p, q) {
            // (p/3)^3 + (q/2)^2
            const determinant = (lib_plankton.complex.add(lib_plankton.complex.npow(lib_plankton.complex.scl(p, 1 / 3.0), 3), lib_plankton.complex.npow(lib_plankton.complex.scl(q, 1 / 2.0), 2)));
            const [u, v] = (lib_plankton.complex.normroots(2, determinant)
                .map(w => lib_plankton.complex.sub(w, lib_plankton.complex.scl(q, 1 / 2.0)))
                .map(z => lib_plankton.complex.normroots(3, z)));
            return [
                /*
                lib_plankton.complex.add(u[0], v[0]),
                lib_plankton.complex.add(u[1], v[2]),
                lib_plankton.complex.add(u[2], v[1]),
                 */
                // (p = -3uv) → (v = p/(-3u)) → (v = (p/(-3))/u)
                lib_plankton.complex.add(u[0], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[0])),
                lib_plankton.complex.add(u[1], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[1])),
                lib_plankton.complex.add(u[2], lib_plankton.complex.div(lib_plankton.complex.scl(p, -1 / 3.0), u[2])),
            ];
        }
        /**
         * {x ∈ C | 0 = x³ + ex² + fx + g}
         *
         * @author fenris
         */
        function cardano_normalized(e, f, g) {
            // p := (-1/3)·e² + f
            const p = (lib_plankton.complex.add(lib_plankton.complex.scl(lib_plankton.complex.npow(e, 2), -1 / 3.0), f));
            // q := (2/27)·e³ + (-1/3)·e·f + g
            const q = (lib_plankton.complex.add(lib_plankton.complex.add(lib_plankton.complex.scl(lib_plankton.complex.npow(e, 3), +2 / 27.0), lib_plankton.complex.scl(lib_plankton.complex.mul(e, f), -1 / 3.0)), g));
            return (cardano_reduced(p, q)
                .map(y => lib_plankton.complex.sub(y, lib_plankton.complex.scl(e, 1 / 3.0))));
        }
        /**
         * {x ∈ C | 0 = ax³ + bx² + cx + d}
         *
         * @author fenris
         */
        function cubic_solve(a, b, c, d) {
            if (lib_plankton.complex.equ(a, lib_plankton.complex.nul())) {
                const message = "Leitkoeffizient ist Null; dadurch sollte sich das Problem eigentlich vereinfachen";
                throw (new Error(message));
            }
            else {
                // e = b/a
                const e = lib_plankton.complex.div(b, a);
                // f = c/a
                const f = lib_plankton.complex.div(c, a);
                // g = d/a
                const g = lib_plankton.complex.div(d, a);
                return cardano_normalized(e, f, g);
            }
        }
        math.cubic_solve = cubic_solve;
        /**
         * {x ∈ C | 0 = ax³ + bx² + cx + d}
         *
         * @author fenris
         */
        function cubic_solve_real(a, b, c, d) {
            return cubic_solve(lib_plankton.complex.make(a, 0), lib_plankton.complex.make(b, 0), lib_plankton.complex.make(c, 0), lib_plankton.complex.make(d, 0));
        }
        math.cubic_solve_real = cubic_solve_real;
        /**
         * gets the coefficients of a polynom by the roots
         *
         * @author fenris
         */
        /*export*/ function cubic_construct(solutions) {
            const [x, y, z] = solutions.map(lib_plankton.complex.neg);
            const mix = function (values) {
                return (values
                    .map(group => (group
                    .reduce(lib_plankton.complex.mul, lib_plankton.complex.one())))
                    .reduce(lib_plankton.complex.add, lib_plankton.complex.nul()));
            };
            return {
                "a": mix([[]]),
                "b": mix([[x], [y], [z]]),
                "c": mix([[x, y], [x, z], [y, z]]),
                "d": mix([[x, y, z]]),
            };
        }
    })(math = lib_plankton.math || (lib_plankton.math = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:color«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:color« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:color« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:color«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:color«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:color« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:color« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:color«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var color;
    (function (color_1) {
        /**
         */
        function make_hsv({ "hue": hue = 0.0, "saturation": saturation = 0.5, "value": value = 0.5 }) {
            const h = lib_plankton.math.clamp(0, 1, hue);
            const s = lib_plankton.math.clamp(0, 1, saturation);
            const v = lib_plankton.math.clamp(0, 1, value);
            const sector = (Math.floor(h * 6) % 6);
            const phase = ((h * 6) - sector);
            const p = (v * (1 - s));
            const q = (v * (1 - (s * phase)));
            const t = (v * (1 - (s * (1 - phase))));
            return make_rgb([
                { "red": v, "green": t, "blue": p },
                { "red": q, "green": v, "blue": p },
                { "red": p, "green": v, "blue": t },
                { "red": p, "green": q, "blue": v },
                { "red": t, "green": p, "blue": v },
                { "red": v, "green": p, "blue": q },
            ][sector]);
        }
        color_1.make_hsv = make_hsv;
        /**
         */
        function make_hsl(model_hsl) {
            const { "hue": h, "saturation": s, "lightness": l } = model_hsl;
            const h_ = h;
            const v = (l + (s * (1 - Math.abs((2 * l) - 1)) / 2));
            const s_ = (2 * (1 - (l / v)));
            return make_hsv({
                "hue": h_,
                "saturation": s_,
                "value": v,
            });
        }
        color_1.make_hsl = make_hsl;
        /**
         */
        function make_rgb(model_rgb) {
            return {
                "model": {
                    "red": lib_plankton.math.clamp(0, 1, model_rgb.red),
                    "green": lib_plankton.math.clamp(0, 1, model_rgb.green),
                    "blue": lib_plankton.math.clamp(0, 1, model_rgb.blue),
                }
            };
        }
        color_1.make_rgb = make_rgb;
        /**
         */
        function from_hex(hex) {
            if (!(hex[0] === "#")) {
                throw (new Error("malformed"));
            }
            else {
                const factor = (1 / 255);
                return make_rgb({
                    "red": (parseInt(hex.slice(1, 3), 16) * factor),
                    "green": (parseInt(hex.slice(3, 5), 16) * factor),
                    "blue": (parseInt(hex.slice(5, 7), 16) * factor),
                });
            }
        }
        color_1.from_hex = from_hex;
        /**
         */
        function to_hsv(color) {
            const { "red": r, "green": g, "blue": b } = color.model;
            const p = Math.min(r, g, b);
            const q = Math.max(r, g, b);
            const c = (q - p);
            let h;
            {
                if (p === q) {
                    h = 0;
                }
                else if (q === r) {
                    h = ((0 / 3) + lib_plankton.math.mod((g - b) / (c * 6), 1));
                }
                else if (q === g) {
                    h = ((1 / 3) + ((b - r) / (c * 6)));
                }
                else if (q === b) {
                    h = ((2 / 3) + ((r - g) / (c * 6)));
                }
                else {
                    throw (new Error("impossible?"));
                }
            }
            const s = ((q === 0) ? 0 : c);
            const v = q;
            return {
                "hue": h,
                "saturation": s,
                "value": v,
            };
        }
        color_1.to_hsv = to_hsv;
        /**
         */
        function to_hsl(color) {
            const { "hue": h, "saturation": s, "value": v } = to_hsv(color);
            const h_ = h;
            const l = (1 / 2 * v * (2 - s));
            const s_ = ((v * s) / (1 - Math.abs((2 * l) - 1)));
            return {
                "hue": h,
                "saturation": s,
                "lightness": l,
            };
        }
        color_1.to_hsl = to_hsl;
        /**
         */
        function to_rgb(color) {
            return color.model;
        }
        color_1.to_rgb = to_rgb;
        /**
         */
        function to_cmyk(color) {
            throw (new Error("not implemented"));
        }
        color_1.to_cmyk = to_cmyk;
        /**
         */
        function add(color1, color2) {
            const rgb1 = to_rgb(color1);
            const rgb2 = to_rgb(color2);
            return make_rgb({
                "red": (rgb1.red + rgb2.red),
                "green": (rgb1.green + rgb2.green),
                "blue": (rgb1.blue + rgb2.blue),
            });
        }
        color_1.add = add;
        /**
         */
        function multiply(color1, color2) {
            const rgb1 = to_rgb(color1);
            const rgb2 = to_rgb(color2);
            return make_rgb({
                "red": (rgb1.red * rgb2.red),
                "green": (rgb1.green * rgb2.green),
                "blue": (rgb1.blue * rgb2.blue),
            });
        }
        color_1.multiply = multiply;
        /**
         * @todo blend through other model?
         */
        function blend(color1, color2, strength = 0.5) {
            let rgb1 = to_rgb(color1);
            let rgb2 = to_rgb(color2);
            let t = strength;
            return (make_rgb({
                "red": lib_plankton.math.interpolate_linear(rgb1.red, rgb2.red, t),
                "green": lib_plankton.math.interpolate_linear(rgb1.green, rgb2.green, t),
                "blue": lib_plankton.math.interpolate_linear(rgb1.blue, rgb2.blue, t)
            }));
        }
        color_1.blend = blend;
        /**
         */
        function mix(color1, color2, { "strength1": option_strength1 = 1, "strength2": option_strength2 = 1, } = {}) {
            return (blend(color1, color2, (option_strength1
                /
                    (option_strength1
                        +
                            option_strength2))));
        }
        color_1.mix = mix;
        /**
         */
        function output_rgb(color) {
            const format = (value => Math.round(value * 255).toFixed(0));
            const rgb = to_rgb(color);
            return ("rgb" + "(" + ["red", "green", "blue"].map(key => rgb[key]).map(format).join(",") + ")");
        }
        color_1.output_rgb = output_rgb;
        /**
         */
        function output_hex(color) {
            const rgb = to_rgb(color);
            const format = function (value) {
                const value_ = Math.round(value * 255);
                // let str : string = lib_plankton.string.pad(value_.toString(16), 2, "0", true);
                let str = value_.toString(16);
                while (str.length < 2)
                    str = ("0" + str);
                return str;
            };
            return ("#" + ["red", "green", "blue"].map(key => rgb[key]).map(format).join("") + "");
        }
        color_1.output_hex = output_hex;
        /**
         */
        function output_dot(color) {
            const hsv = to_hsv(color);
            let format = function (value) {
                return value.toFixed(8);
            };
            return ("" + ["hue", "saturation", "value"].map(key => hsv[key]).map(format).join("+") + "");
        }
        color_1.output_dot = output_dot;
        /**
         */
        function give_generic(n, { "offset": option_offset = 0, "saturation": option_saturation = undefined, "value": option_value = undefined, }) {
            return make_hsv({
                "hue": (((lib_plankton.math.phi
                    *
                        n)
                    +
                        option_offset)
                    %
                        1),
                "saturation": option_saturation,
                "value": option_value,
            });
        }
        color_1.give_generic = give_generic;
        /**
         */
        function give_gray({ "value": option_value = 0.5, }) {
            return make_hsv({ "hue": 0, "saturation": 0, "value": option_value });
        }
        color_1.give_gray = give_gray;
        /**
         */
        function give_black() {
            return give_gray({ "value": 0.0 });
        }
        color_1.give_black = give_black;
        /**
         */
        function give_white() {
            return give_gray({ "value": 1.0 });
        }
        color_1.give_white = give_white;
        /**
         */
        function give_red({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (0 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_red = give_red;
        /**
         */
        function give_green({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (2 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_green = give_green;
        /**
         */
        function give_blue({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (4 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_blue = give_blue;
        /**
         */
        function give_yellow({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (1 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_yellow = give_yellow;
        /**
         */
        function give_cyan({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (3 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_cyan = give_cyan;
        /**
         */
        function give_magenta({ "saturation": option_saturation = undefined, "value": option_value = undefined, } = {}) {
            return make_hsv({
                "hue": (5 / 6),
                "saturation": option_saturation,
                "value": option_value
            });
        }
        color_1.give_magenta = give_magenta;
    })(color = lib_plankton.color || (lib_plankton.color = {}));
})(lib_plankton || (lib_plankton = {}));
"use strict";
/*
This file is part of »bacterio-plankton:http_base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:http_base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:http_base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:http_base«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:http_base«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:http_base« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:http_base« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:http_base«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var http_base;
    (function (http_base) {
        /**
         */
        const linebreak = "\r\n";
        /**
         */
        function capitalize_all(str) {
            return str.split("-").map(x => lib_plankton.string.capitalize(x)).join("-");
        }
        /**
         */
        function encode_request(encode_method, request) {
            let request_raw = "";
            request_raw += lib_plankton.string.coin("{{method}} {{path}}{{query}} {{version}}{{linebreak}}", {
                "method": encode_method(request.method),
                "path": request.path,
                "query": ((request.query === null) ? "" : request.query),
                "version": request.version,
                "linebreak": linebreak,
            });
            if (request.host === null) {
                // do nothing
            }
            else {
                request_raw += lib_plankton.string.coin("Host: {{host}}{{linebreak}}", {
                    "host": request.host,
                    "linebreak": linebreak,
                });
            }
            for (const [key, value] of Object.entries(request.headers)) {
                request_raw += lib_plankton.string.coin("{{key}}: {{value}}{{linebreak}}", {
                    "key": capitalize_all(key),
                    "value": value,
                    "linebreak": linebreak,
                });
            }
            request_raw += linebreak;
            if (request.body === null) {
                // do nothing
            }
            else {
                request_raw += request.body.toString();
            }
            return request_raw;
        }
        http_base.encode_request = encode_request;
        /**
         */
        function decode_request(decode_method, has_body, request_raw) {
            const lines = lib_plankton.string.split(request_raw, linebreak);
            if (lines.length <= 0) {
                throw (new Error("malformed request"));
            }
            else {
                const first = lines[0];
                lines.shift();
                const parts = first.split(" ");
                const method = decode_method(parts[0]);
                const path_and_query = parts[1];
                const parts_ = path_and_query.split("?");
                const path = parts_[0];
                const query = ((parts_.length <= 1) ? null : ("?" + parts_.slice(1).join("?")));
                const version = parts[2];
                let headers = {};
                while (true) {
                    const line = lines[0];
                    lines.shift();
                    if (line === "") {
                        break;
                    }
                    else {
                        const [key, value] = line.split(": ", 2);
                        headers[key.toLowerCase()] = value;
                    }
                }
                const body = (has_body(method)
                    // @ts-ignore
                    ? Buffer.from(lines.join(linebreak))
                    : null);
                const request = {
                    // TODO
                    "scheme": "http",
                    "host": (headers["host"] ?? null),
                    "path": path,
                    "version": version,
                    "method": method,
                    "query": query,
                    "headers": headers,
                    "body": body,
                };
                return request;
            }
        }
        http_base.decode_request = decode_request;
        /**
         */
        function encode_response(encode_status_code, get_status_text, response) {
            let response_raw = "";
            response_raw += lib_plankton.string.coin("{{version}} {{status_code}} {{status_text}}{{linebreak}}", {
                "version": (response.version ?? ""),
                "status_code": encode_status_code(response.status_code),
                "status_text": get_status_text(response.status_code),
                "linebreak": linebreak,
            });
            for (const [key, value] of Object.entries(response.headers)) {
                response_raw += lib_plankton.string.coin("{{key}}: {{value}}{{linebreak}}", {
                    "key": capitalize_all(key),
                    "value": value,
                    "linebreak": linebreak,
                });
            }
            response_raw += linebreak;
            if (response.body === null) {
                // do nothing
            }
            else {
                response_raw += response.body.toString();
            }
            return response_raw;
        }
        http_base.encode_response = encode_response;
        /**
         */
        function decode_response(decode_status_code, response_raw) {
            const lines = response_raw.split(linebreak);
            const first = lines[0];
            lines.shift();
            const first_parts = first.split(" ");
            const version = first_parts[0];
            const status_code = decode_status_code(first_parts[1]);
            // first_parts.slice(2) ? probably irrelevant
            let headers = {};
            while (true) {
                const line = lines[0];
                lines.shift();
                if (line === "") {
                    break;
                }
                else {
                    const [key, value] = line.split(": ", 2);
                    headers[key.toLowerCase()] = value;
                }
            }
            // @ts-ignore
            const body = Buffer.from(lines.join(linebreak));
            const response = {
                // TODO
                "version": version,
                "status_code": status_code,
                "headers": headers,
                "body": body,
            };
            return response;
        }
        http_base.decode_response = decode_response;
        /**
         * executes an HTTP request
         *
         * @todo define type_signal
         */
        async function call(has_body, encode_method, decode_status_code, request, { "timeout": option_timeout = 5.0, "follow_redirects": option_follow_redirects = false, "implementation": option_implementation = "fetch", } = {}) {
            const target = lib_plankton.string.coin("{{scheme}}://{{host}}{{path}}{{query}}", {
                "scheme": request.scheme,
                "host": (request.host ?? ""),
                "path": request.path,
                "query": (request.query ?? ""),
            });
            switch (option_implementation) {
                default: {
                    return Promise.reject(new Error("invalid implementation: " + option_implementation));
                    break;
                }
                case "fetch": {
                    function core(signal) {
                        return (fetch(target, Object.assign({
                            "method": encode_method(request.method),
                            "headers": request.headers,
                            /*
                            "redirect": (
                                option_follow_redirects
                                ?
                                "follow"
                                :
                                "manual"
                            ),
                             */
                            "signal": (signal
                                ??
                                    undefined),
                            // "keepalive": false,
                        }, ((has_body(request.method)
                            &&
                                (request.body !== null))
                            ? {
                                "body": request.body.toString(),
                            }
                            : {})))
                            .catch((reason) => {
                            // console.info(reason);
                            return Promise.reject(reason);
                        })
                            .then((response_raw) => (response_raw.text()
                            .then((body) => Promise.resolve({
                            // TODO
                            "version": null,
                            "status_code": decode_status_code(response_raw.status.toFixed(0)),
                            "headers": ((headers_raw => {
                                let headers = {};
                                headers_raw.forEach((value, key) => {
                                    headers[key] = value;
                                });
                                return headers;
                            })(response_raw.headers)),
                            "body": body,
                        })))));
                    }
                    function timeout(controller) {
                        return (new Promise((resolve, reject) => {
                            if (option_timeout === null) {
                                // do nothing (neither resolve nor reject ever)
                            }
                            else {
                                setTimeout(() => {
                                    controller.abort();
                                    resolve(null);
                                }, (option_timeout * 1000));
                            }
                        }));
                    }
                    const controller = new AbortController();
                    const signal = controller.signal;
                    const response = await Promise.race([
                        timeout(controller),
                        core(signal),
                    ]);
                    if (response === null) {
                        throw (new Error("http_request_timeout"));
                    }
                    else {
                        return response;
                    }
                    break;
                }
                case "http_module": {
                    // @ts-ignore
                    const nm_http = require("http");
                    // @ts-ignore
                    const nm_https = require("https");
                    return (new Promise((resolve, reject) => {
                        const req = ((request.scheme === "https")
                            ? nm_https
                            : nm_http)
                            .request(target, {
                            "method": request.method,
                            "headers": request.headers,
                        }, 
                        // @ts-ignore
                        (res) => {
                            try {
                                let response_body = "";
                                res.setEncoding("utf8");
                                res.on("data", (chunk) => {
                                    response_body += chunk;
                                });
                                res.on("end", () => {
                                    resolve({
                                        // TODO
                                        "version": null,
                                        "status_code": res.statusCode,
                                        "headers": res.headers,
                                        "body": response_body,
                                    });
                                });
                            }
                            catch (error) {
                                reject(error);
                            }
                        });
                        req.on("error", (error) => {
                            reject(error);
                        });
                        req.write(request.body);
                        req.end();
                    }));
                    break;
                }
            }
        }
        http_base.call = call;
    })(http_base = lib_plankton.http_base || (lib_plankton.http_base = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:http«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:http« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:http« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var http;
    (function (http) {
        /**
         * @author fenris <frass@greenscale.de>
         */
        let enum_method;
        (function (enum_method) {
            enum_method["options"] = "options";
            enum_method["head"] = "head";
            enum_method["get"] = "get";
            enum_method["delete"] = "delete";
            enum_method["post"] = "post";
            enum_method["put"] = "put";
            enum_method["patch"] = "patch";
        })(enum_method = http.enum_method || (http.enum_method = {}));
        /**
         */
        let enum_status_code;
        (function (enum_status_code) {
            enum_status_code[enum_status_code["continue_"] = 100] = "continue_";
            enum_status_code[enum_status_code["switching_protocols"] = 101] = "switching_protocols";
            enum_status_code[enum_status_code["early_hints"] = 103] = "early_hints";
            enum_status_code[enum_status_code["ok"] = 200] = "ok";
            enum_status_code[enum_status_code["created"] = 201] = "created";
            enum_status_code[enum_status_code["accepted"] = 202] = "accepted";
            enum_status_code[enum_status_code["non_authoritative_information"] = 203] = "non_authoritative_information";
            enum_status_code[enum_status_code["no_content"] = 204] = "no_content";
            enum_status_code[enum_status_code["reset_content"] = 205] = "reset_content";
            enum_status_code[enum_status_code["partial_coentent"] = 206] = "partial_coentent";
            enum_status_code[enum_status_code["multiple_choices"] = 300] = "multiple_choices";
            enum_status_code[enum_status_code["moved_permanently"] = 301] = "moved_permanently";
            enum_status_code[enum_status_code["found"] = 302] = "found";
            enum_status_code[enum_status_code["see_other"] = 303] = "see_other";
            enum_status_code[enum_status_code["not_modified"] = 304] = "not_modified";
            enum_status_code[enum_status_code["temporary_redirect"] = 307] = "temporary_redirect";
            enum_status_code[enum_status_code["permanent_redirect"] = 308] = "permanent_redirect";
            enum_status_code[enum_status_code["bad_request"] = 400] = "bad_request";
            enum_status_code[enum_status_code["unauthorized"] = 401] = "unauthorized";
            enum_status_code[enum_status_code["payment_required"] = 402] = "payment_required";
            enum_status_code[enum_status_code["forbidden"] = 403] = "forbidden";
            enum_status_code[enum_status_code["not_found"] = 404] = "not_found";
            enum_status_code[enum_status_code["method_not_allowed"] = 405] = "method_not_allowed";
            enum_status_code[enum_status_code["not_acceptable"] = 406] = "not_acceptable";
            enum_status_code[enum_status_code["proxy_authentication_required"] = 407] = "proxy_authentication_required";
            enum_status_code[enum_status_code["request_timeout"] = 408] = "request_timeout";
            enum_status_code[enum_status_code["conflict"] = 409] = "conflict";
            enum_status_code[enum_status_code["gone"] = 410] = "gone";
            enum_status_code[enum_status_code["length_required"] = 411] = "length_required";
            enum_status_code[enum_status_code["precondition_failed"] = 412] = "precondition_failed";
            enum_status_code[enum_status_code["payload_too_large"] = 413] = "payload_too_large";
            enum_status_code[enum_status_code["uri_too_long"] = 414] = "uri_too_long";
            enum_status_code[enum_status_code["unsupported_media_type"] = 415] = "unsupported_media_type";
            enum_status_code[enum_status_code["range_not_satisfiable"] = 416] = "range_not_satisfiable";
            enum_status_code[enum_status_code["expectation_failed"] = 417] = "expectation_failed";
            enum_status_code[enum_status_code["i_m_a_teapot"] = 418] = "i_m_a_teapot";
            enum_status_code[enum_status_code["unprocessable_entity"] = 422] = "unprocessable_entity";
            enum_status_code[enum_status_code["too_early"] = 425] = "too_early";
            enum_status_code[enum_status_code["upgrade_required"] = 426] = "upgrade_required";
            enum_status_code[enum_status_code["precondition_required"] = 428] = "precondition_required";
            enum_status_code[enum_status_code["too_many_requests"] = 429] = "too_many_requests";
            enum_status_code[enum_status_code["request_header_fields_too_large"] = 431] = "request_header_fields_too_large";
            enum_status_code[enum_status_code["unavailable_for_legal_reasons"] = 451] = "unavailable_for_legal_reasons";
            enum_status_code[enum_status_code["internal_server_error"] = 500] = "internal_server_error";
            enum_status_code[enum_status_code["not_implemented"] = 501] = "not_implemented";
            enum_status_code[enum_status_code["bad_gateway"] = 502] = "bad_gateway";
            enum_status_code[enum_status_code["service_unavailable"] = 503] = "service_unavailable";
            enum_status_code[enum_status_code["gateway_timeout"] = 504] = "gateway_timeout";
            enum_status_code[enum_status_code["http_version_not_supported"] = 505] = "http_version_not_supported";
            enum_status_code[enum_status_code["variant_also_negotiates"] = 506] = "variant_also_negotiates";
            enum_status_code[enum_status_code["insufficient_storage"] = 507] = "insufficient_storage";
            enum_status_code[enum_status_code["loop_detected"] = 508] = "loop_detected";
            enum_status_code[enum_status_code["not_extended"] = 510] = "not_extended";
            enum_status_code[enum_status_code["network_authentication"] = 511] = "network_authentication";
        })(enum_status_code = http.enum_status_code || (http.enum_status_code = {}));
    })(http = lib_plankton.http || (lib_plankton.http = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:http«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:http« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:http« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var http;
    (function (http) {
        /**
         * @author fenris <frass@greenscale.de>
         */
        function encode_method(method) {
            switch (method) {
                case http.enum_method.get: return "GET";
                case http.enum_method.post: return "POST";
                case http.enum_method.patch: return "PATCH";
                case http.enum_method.put: return "PUT";
                case http.enum_method.delete: return "DELETE";
                case http.enum_method.options: return "OPTIONS";
                case http.enum_method.head: return "HEAD";
                default: throw (new Error("impossible"));
            }
        }
        http.encode_method = encode_method;
        /**
         * @author fenris <frass@greenscale.de>
         */
        function decode_method(method_raw) {
            switch (method_raw) {
                case "GET": return http.enum_method.get;
                case "POST": return http.enum_method.post;
                case "PATCH": return http.enum_method.patch;
                case "PUT": return http.enum_method.put;
                case "DELETE": return http.enum_method.delete;
                case "OPTIONS": return http.enum_method.options;
                case "HEAD": return http.enum_method.head;
                default: throw (new Error("unhandled method: " + method_raw));
            }
        }
        http.decode_method = decode_method;
        /**
         */
        function encode_status_code(status_code) {
            return status_code.toFixed(0);
        }
        /**
         * @todo check for existance
         */
        function decode_status_code(status_code_raw) {
            return parseInt(status_code_raw);
        }
        /**
         * @author fenris <frass@greenscale.de>
         */
        function get_status_text(statuscode) {
            switch (statuscode) {
                case 100: return "Continue";
                case 101: return "Switching Protocols";
                case 103: return "Early Hints";
                case 200: return "OK";
                case 201: return "Created";
                case 202: return "Accepted";
                case 203: return "Non-Authoritative Information";
                case 204: return "No Content";
                case 205: return "Reset Content";
                case 206: return "Partial Content";
                case 300: return "Multiple Choices";
                case 301: return "Moved Permanently";
                case 302: return "Found";
                case 303: return "See Other";
                case 304: return "Not Modified";
                case 307: return "Temporary Redirect";
                case 308: return "Permanent Redirect";
                case 400: return "Bad Request";
                case 401: return "Unauthorized";
                case 402: return "Payment Required";
                case 403: return "Forbidden";
                case 404: return "Not Found";
                case 405: return "Method Not Allowed";
                case 406: return "Not Acceptable";
                case 407: return "Proxy Authentication Required";
                case 408: return "Request Timeout";
                case 409: return "Conflict";
                case 410: return "Gone";
                case 411: return "Length Required";
                case 412: return "Precondition Failed";
                case 413: return "Payload Too Large";
                case 414: return "URI Too Long";
                case 415: return "Unsupported Media Type";
                case 416: return "Range Not Satisfiable";
                case 417: return "Expectation Failed";
                case 418: return "I'm a teapot";
                case 422: return "Unprocessable Entity";
                case 425: return "Too Early";
                case 426: return "Upgrade Required";
                case 428: return "Precondition Required";
                case 429: return "Too Many Requests";
                case 431: return "Request Header Fields Too Large";
                case 451: return "Unavailable For Legal Reasons";
                case 500: return "Internal Server Error";
                case 501: return "Not Implemented";
                case 502: return "Bad Gateway";
                case 503: return "Service Unavailable";
                case 504: return "Gateway Timeout";
                case 505: return "HTTP Version Not Supported";
                case 506: return "Variant Also Negotiates";
                case 507: return "Insufficient Storage";
                case 508: return "Loop Detected";
                case 510: return "Not Extended";
                case 511: return "Network Authentication";
                default: throw (new Error("unhandled statuscode: " + statuscode.toFixed(0)));
            }
        }
        /**
         * @author fenris <frass@greenscale.de>
         */
        function has_body(method) {
            return [
                http.enum_method.post,
                http.enum_method.put,
                http.enum_method.patch
            ].includes(method);
        }
        http.has_body = has_body;
        /**
         * @author fenris <frass@greenscale.de>
         */
        function encode_request(request) {
            return lib_plankton.http_base.encode_request(encode_method, request);
        }
        http.encode_request = encode_request;
        /**
         * @author fenris <frass@greenscale.de>
         */
        function decode_request(request_raw) {
            return lib_plankton.http_base.decode_request(decode_method, has_body, request_raw);
        }
        http.decode_request = decode_request;
        /**
         * @author fenris <frass@greenscale.de>
         */
        function encode_response(response) {
            return lib_plankton.http_base.encode_response(encode_status_code, get_status_text, response);
        }
        http.encode_response = encode_response;
        /**
         * @author fenris <frass@greenscale.de>
         */
        function decode_response(response_raw) {
            return lib_plankton.http_base.decode_response(decode_status_code, response_raw);
        }
        http.decode_response = decode_response;
        /**
         * executes an HTTP request
         *
         * @todo define type_signal
         */
        async function call(request, { "timeout": option_timeout = 5.0, "follow_redirects": option_follow_redirects = false, "implementation": option_implementation = "fetch", } = {}) {
            return lib_plankton.http_base.call(has_body, encode_method, decode_status_code, request, {
                "timeout": option_timeout,
                "follow_redirects": option_follow_redirects,
                "implementation": option_implementation,
            });
        }
        http.call = call;
    })(http = lib_plankton.http || (lib_plankton.http = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pit«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pit« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pit« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pit«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:pit«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:pit« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:pit« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:pit«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var pit;
    (function (pit_1) {
        /**
         * @todo complete
         */
        function timezone_name_to_timezone_shift(timezone_name) {
            const map = {
                "UTC": 0,
                "CET": +1,
                "CEST": +2,
            };
            if (!(timezone_name in map)) {
                throw (new Error("unhandled timezone: " + timezone_name));
            }
            else {
                return map[timezone_name];
            }
        }
        pit_1.timezone_name_to_timezone_shift = timezone_name_to_timezone_shift;
        /**
         */
        function date_object_get_week_of_year(date) {
            let date_ = new Date(date.getTime());
            date_.setHours(0, 0, 0, 0);
            // Thursday in current week decides the year.
            date_.setDate(date_.getDate() + 3 - (date_.getDay() + 6) % 7);
            // January 4 is always in week 1.
            let week1 = new Date(date_.getFullYear(), 0, 4);
            // Adjust to Thursday in week 1 and count number of weeks from date to week1.
            return (1
                +
                    Math.round((((date_.getTime() - week1.getTime()) / 86400000)
                        -
                            3
                        +
                            (week1.getDay() + 6) % 7)
                        /
                            7));
        }
        pit_1.date_object_get_week_of_year = date_object_get_week_of_year;
        /**
         */
        function to_unix_timestamp(pit) {
            return pit;
        }
        pit_1.to_unix_timestamp = to_unix_timestamp;
        /**
         */
        function from_unix_timestamp(unix_timestamp) {
            return unix_timestamp;
        }
        pit_1.from_unix_timestamp = from_unix_timestamp;
        /**
         */
        function to_date_object(pit) {
            return (new Date(pit * 1000));
        }
        pit_1.to_date_object = to_date_object;
        /**
         */
        function from_date_object(date_object) {
            return Math.round(date_object.getTime() / 1000);
        }
        pit_1.from_date_object = from_date_object;
        /**
         * @todo test
         */
        function to_datetime(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) {
            return lib_plankton.call.convey(pit, [
                to_date_object,
                (x) => x.getTime(),
                (x) => (x + ((option_timezone_shift * (60 * 60)) * 1000)),
                (x) => new Date(x),
                x => x.toISOString(),
                x => ({
                    "timezone_shift": option_timezone_shift,
                    "date": {
                        "year": parseInt(x.slice(0, 4)),
                        "month": parseInt(x.slice(5, 7)),
                        "day": parseInt(x.slice(8, 10)),
                    },
                    "time": {
                        "hour": parseInt(x.slice(11, 13)),
                        "minute": parseInt(x.slice(14, 16)),
                        "second": parseInt(x.slice(17, 19)),
                    },
                })
            ]);
        }
        pit_1.to_datetime = to_datetime;
        /**
         */
        function from_datetime(datetime) {
            return lib_plankton.call.convey(datetime, [
                (x) => lib_plankton.string.coin("{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}", {
                    "year": x.date.year.toFixed(0).padStart(4, "0"),
                    "month": x.date.month.toFixed(0).padStart(2, "0"),
                    "day": x.date.day.toFixed(0).padStart(2, "0"),
                    "hour": ((x.time !== null) ? x.time.hour : 0).toFixed(0).padStart(2, "0"),
                    "minute": ((x.time !== null) ? x.time.minute : 0).toFixed(0).padStart(2, "0"),
                    "second": ((x.time !== null) ? x.time.second : 0).toFixed(0).padStart(2, "0"),
                    "shift": (x.timezone_shift.toFixed(0).padStart(2, "0") + ":00"),
                }),
                x => (new Date(x)),
                from_date_object,
            ]);
        }
        pit_1.from_datetime = from_datetime;
        /**
         */
        function is_before(pit, reference) {
            return (pit < reference);
        }
        pit_1.is_before = is_before;
        /**
         */
        function is_after(pit, reference) {
            return (pit > reference);
        }
        pit_1.is_after = is_after;
        /**
         */
        function is_equal_or_after(pit, reference) {
            return (pit >= reference);
        }
        pit_1.is_equal_or_after = is_equal_or_after;
        /**
         */
        function is_between(pit, reference_left, reference_right) {
            return (is_equal_or_after(pit, reference_left)
                &&
                    is_before(pit, reference_right));
        }
        pit_1.is_between = is_between;
        /**
         */
        function shift_second(pit, increment) {
            return (pit + (increment));
        }
        pit_1.shift_second = shift_second;
        /**
         */
        function shift_minute(pit, increment) {
            return (pit + (60 * increment));
        }
        pit_1.shift_minute = shift_minute;
        /**
         */
        function shift_hour(pit, increment) {
            return (pit + (60 * 60 * increment));
        }
        pit_1.shift_hour = shift_hour;
        /**
         */
        function shift_day(pit, increment) {
            return (pit + (60 * 60 * 24 * increment));
        }
        pit_1.shift_day = shift_day;
        /**
         */
        function shift_week(pit, increment) {
            return (pit + (60 * 60 * 24 * 7 * increment));
        }
        pit_1.shift_week = shift_week;
        /**
         */
        function shift_year(pit, increment) {
            return (pit + (60 * 60 * 24 * 365 * increment));
        }
        pit_1.shift_year = shift_year;
        /**
         */
        function trunc_minute(pit) {
            const datetime_input = to_datetime(pit);
            const datetime_output = {
                "timezone_shift": 0,
                "date": {
                    "year": datetime_input.date.year,
                    "month": datetime_input.date.month,
                    "day": datetime_input.date.day,
                },
                "time": {
                    "hour": ((datetime_input.time === null)
                        ?
                            0
                        :
                            datetime_input.time.hour),
                    "minute": ((datetime_input.time === null)
                        ?
                            0
                        :
                            datetime_input.time.minute),
                    "second": 0,
                },
            };
            return from_datetime(datetime_output);
        }
        pit_1.trunc_minute = trunc_minute;
        /**
         */
        function trunc_hour(pit) {
            const datetime_input = to_datetime(pit);
            const datetime_output = {
                "timezone_shift": 0,
                "date": {
                    "year": datetime_input.date.year,
                    "month": datetime_input.date.month,
                    "day": datetime_input.date.day,
                },
                "time": {
                    "hour": ((datetime_input.time === null)
                        ?
                            0
                        :
                            datetime_input.time.hour),
                    "minute": 0,
                    "second": 0,
                },
            };
            return from_datetime(datetime_output);
        }
        pit_1.trunc_hour = trunc_hour;
        /**
         */
        function trunc_day(pit) {
            const datetime_input = to_datetime(pit);
            const datetime_output = {
                "timezone_shift": 0,
                "date": {
                    "year": datetime_input.date.year,
                    "month": datetime_input.date.month,
                    "day": datetime_input.date.day,
                },
                "time": {
                    "hour": 0,
                    "minute": 0,
                    "second": 0,
                },
            };
            return from_datetime(datetime_output);
        }
        pit_1.trunc_day = trunc_day;
        /**
         */
        function trunc_week(pit) {
            const date_object = to_date_object(pit);
            return lib_plankton.call.convey(date_object.getDay(), [
                (x) => ((x === 0) ? 7 : x),
                (x) => (x - 1),
                (x) => shift_day(pit, (-x)),
                trunc_day
            ]);
        }
        pit_1.trunc_week = trunc_week;
        /**
         */
        function trunc_month(pit) {
            const datetime_input = to_datetime(pit);
            const datetime_output = {
                "timezone_shift": 0,
                "date": {
                    "year": datetime_input.date.year,
                    "month": datetime_input.date.month,
                    "day": 1,
                },
                "time": {
                    "hour": 0,
                    "minute": 0,
                    "second": 0,
                },
            };
            return from_datetime(datetime_output);
        }
        pit_1.trunc_month = trunc_month;
        /**
         */
        function trunc_year(pit) {
            const datetime_input = to_datetime(pit);
            const datetime_output = {
                "timezone_shift": 0,
                "date": {
                    "year": datetime_input.date.year,
                    "month": 1,
                    "day": 1,
                },
                "time": {
                    "hour": 0,
                    "minute": 0,
                    "second": 0,
                },
            };
            return from_datetime(datetime_output);
        }
        pit_1.trunc_year = trunc_year;
        /**
         */
        function now() {
            return from_date_object(new Date(Date.now()));
        }
        pit_1.now = now;
        /**
         * @param year year according to specified timezone shift
         * @param week week according to specified timezone shift
         * @return the begin of the week (monday, 00:00)
         */
        function from_ywd(ywd, { "timezone_shift": option_timezone_shift = 0, } = {}) {
            return lib_plankton.call.convey({
                "timezone_shift": option_timezone_shift,
                "date": {
                    "year": ywd.year,
                    "month": 1,
                    "day": 1,
                },
                "time": {
                    "hour": 0,
                    "minute": 0,
                    "second": 0
                }
            }, [
                from_datetime,
                (x) => shift_week(x, (ywd.week - 1)),
                trunc_week,
                (x) => shift_day(x, (ywd.day - 1)),
            ]);
        }
        pit_1.from_ywd = from_ywd;
        /**
         * @todo timezone
         */
        function to_ywd(pit, { "timezone_shift": option_timezone_shift = 0, } = {}) {
            return lib_plankton.call.convey(pit, [
                to_date_object,
                x => ({
                    "year": x.getFullYear(),
                    "week": date_object_get_week_of_year(x),
                    "day": ((day => (day <= 0) ? 7 : day)(x.getDay())),
                })
            ]);
        }
        pit_1.to_ywd = to_ywd;
        /**
         */
        function number_of_weeks(year) {
            return lib_plankton.call.convey(year, [
                x => from_ywd({ "year": (x + 1), "week": 1, "day": 6 }),
                x => shift_week(x, -1),
                to_ywd,
                x => x.week,
            ]);
        }
        pit_1.number_of_weeks = number_of_weeks;
        /**
         * computes the point in time for switching to central european summer time
         *
         * @todo write tests
         */
        function cest_switch_on(year) {
            return lib_plankton.call.convey(year, [
                (x) => ({
                    "timezone_shift": 0,
                    "date": {
                        "year": x,
                        "month": 4,
                        "day": 1,
                    },
                    "time": {
                        "hour": 2,
                        "minute": 0,
                        "second": 0
                    },
                }),
                from_datetime,
                trunc_week,
                x => shift_day(x, -1),
            ]);
        }
        pit_1.cest_switch_on = cest_switch_on;
        /**
         * computes the point in time for switching away from central european summer time
         *
         * @todo write tests
         */
        function cest_switch_off(year) {
            return lib_plankton.call.convey(year, [
                (x) => ({
                    "timezone_shift": 0,
                    "date": {
                        "year": x,
                        "month": 11,
                        "day": 1,
                    },
                    "time": {
                        "hour": 1,
                        "minute": 0,
                        "second": 0
                    },
                }),
                from_datetime,
                trunc_week,
                x => shift_day(x, -1),
            ]);
        }
        pit_1.cest_switch_off = cest_switch_off;
        /**
         */
        function timezone_shift_ce(pit) {
            const year = to_datetime(pit).date.year;
            return (is_between(pit, cest_switch_on(year), cest_switch_off(year))
                ? +2
                : +1);
        }
        pit_1.timezone_shift_ce = timezone_shift_ce;
        /**
         * [convenience]
         */
        function to_datetime_ce(pit) {
            return to_datetime(pit, {
                "timezone_shift": timezone_shift_ce(pit),
            });
        }
        pit_1.to_datetime_ce = to_datetime_ce;
        /**
         */
        function datetime_translate(datetime, timezone_shift) {
            if (datetime.timezone_shift === timezone_shift) {
                return datetime;
            }
            else {
                const pit = from_datetime(datetime);
                const pit_shifted = shift_hour(pit, (timezone_shift - datetime.timezone_shift));
                const datetime_shifted = to_datetime(pit_shifted);
                return {
                    "timezone_shift": timezone_shift,
                    "date": datetime_shifted.date,
                    "time": ((datetime.time === null)
                        ?
                            null
                        :
                            datetime_shifted.time)
                };
            }
        }
        pit_1.datetime_translate = datetime_translate;
        /**
         * [convenience]
         */
        function datetime_translate_ce(datetime) {
            return datetime_translate(datetime, timezone_shift_ce(from_datetime(datetime)));
        }
        pit_1.datetime_translate_ce = datetime_translate_ce;
        /**
         */
        function timezone_shift_format(timezone_shift) {
            return lib_plankton.string.coin("{{sign}}{{value}}", {
                "sign": ((timezone_shift === 0)
                    ?
                        " "
                    :
                        ((timezone_shift > 0)
                            ?
                                "+"
                            :
                                "-")),
                "value": Math.abs(timezone_shift).toFixed(0),
            });
        }
        pit_1.timezone_shift_format = timezone_shift_format;
        /**
         */
        function date_format(date, { "short": short = false, } = {}) {
            return lib_plankton.string.coin("{{year}}{{separator}}{{month}}{{separator}}{{day}}", {
                "separator": (short ? "" : "-"),
                "year": date.year.toFixed(0).padStart(4, "0"),
                "month": date.month.toFixed(0).padStart(2, "0"),
                "day": date.day.toFixed(0).padStart(2, "0"),
            });
        }
        pit_1.date_format = date_format;
        /**
         */
        function time_format(time, { "show_seconds": option_show_seconds = false, } = {}) {
            return lib_plankton.string.coin((option_show_seconds
                ?
                    "{{hour}}:{{minute}}:{{seconds}}"
                :
                    "{{hour}}:{{minute}}"), {
                "hour": time.hour.toFixed(0).padStart(2, "0"),
                "minute": time.minute.toFixed(0).padStart(2, "0"),
                "second": time.second.toFixed(0).padStart(2, "0"),
            });
        }
        pit_1.time_format = time_format;
        /**
         */
        function datetime_format(datetime, { "timezone_indicator": option_timezone_indicator = "", "show_timezone": option_show_timezone = false, "adjust_to_ce": option_adjust_to_ce = false, "omit_date": option_omit_date = false, } = {}) {
            if (datetime === null) {
                return "-";
            }
            else {
                const datetime_adjusted = (option_adjust_to_ce
                    ?
                        to_datetime_ce(from_datetime(datetime))
                    :
                        datetime);
                return lib_plankton.string.coin("{{macro_date_and_time}}{{macro_timezone}}", {
                    "macro_date_and_time": ([
                        // date
                        (option_omit_date
                            ?
                                null
                            :
                                date_format(datetime_adjusted.date)),
                        // time
                        ((datetime_adjusted.time === null)
                            ?
                                null
                            :
                                time_format(datetime_adjusted.time)),
                    ]
                        .filter(x => (x !== null))
                        .join(", ")),
                    "macro_timezone": (option_show_timezone
                        ?
                            lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
                                "timezone_indicator": option_timezone_indicator,
                                "timezone_value": timezone_shift_format(datetime_adjusted.timezone_shift),
                            })
                        :
                            ""),
                });
            }
        }
        pit_1.datetime_format = datetime_format;
        /**
         */
        function timespan_format(from, to, { "timezone_indicator": timezone_indicator = "", "show_timezone": show_timezone = false, "adjust_to_ce": adjust_to_ce = false, "omit_date": omit_date = false, "indicator_open_both": indicator_open_both = "?", "indicator_open_right": indicator_open_right = "> ", "indicator_open_left": indicator_open_left = "< ", "indicator_closed": indicator_closed = " — ", } = {}) {
            const from_adjusted = ((from === null)
                ?
                    null
                :
                    (adjust_to_ce
                        ?
                            datetime_translate_ce(from)
                        :
                            from));
            const to_adjusted = ((to === null)
                ?
                    null
                :
                    (adjust_to_ce
                        ?
                            datetime_translate_ce(to)
                        :
                            to));
            return (((to_adjusted === null)
                &&
                    (from_adjusted === null))
                ?
                    indicator_open_both
                :
                    lib_plankton.string.coin("{{prefix}}{{from_macro}}{{interfix}}{{to_macro}}{{macro_timezone}}", {
                        "prefix": ((to_adjusted === null)
                            ?
                                indicator_open_right
                            :
                                ""),
                        "from_macro": ((from_adjusted === null)
                            ?
                                ""
                            :
                                datetime_format(from_adjusted, {
                                    "show_timezone": false,
                                    "adjust_to_ce": false,
                                    "omit_date": omit_date,
                                })),
                        "interfix": ((from_adjusted === null)
                            ?
                                indicator_open_left
                            :
                                ((to_adjusted === null)
                                    ?
                                        ""
                                    :
                                        indicator_closed)),
                        "to_macro": ((to_adjusted === null)
                            ?
                                ""
                            :
                                datetime_format(to_adjusted, {
                                    "omit_date": ((from_adjusted !== null)
                                        &&
                                            ((from_adjusted.date.year === to_adjusted.date.year)
                                                &&
                                                    (from_adjusted.date.month === to_adjusted.date.month)
                                                &&
                                                    (from_adjusted.date.day === to_adjusted.date.day)))
                                })),
                        "macro_timezone": (show_timezone
                            ?
                                lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
                                    "timezone_indicator": timezone_indicator,
                                    "timezone_value": timezone_shift_format(from_adjusted.timezone_shift),
                                })
                            :
                                ""),
                    }));
        }
        pit_1.timespan_format = timespan_format;
    })(pit = lib_plankton.pit || (lib_plankton.pit = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:translate«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:translate« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:translate« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:translate«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var translate;
    (function (translate) {
        /**
         * @desc contains the sets of strings
         * @author fenris
         */
        var _packages = {};
        /**
         * @desc specifies in which order the languages shall be queried; if getting a string from language #0 fails, the
         * 		system tries to get it from language #1, and so on
         * @author fenris
         */
        var _order = [];
        /**
         * @desc whether to automatically promote the language of a newly added package
         * @author fenris
         */
        var _autopromote = false;
        /**
         * @desc the level of verbosity, specifiying how much output the system shall provide about its actions
         * @author fenris
         */
        translate._verbosity = 1;
        /**
         * @desc which initial string to use for log-outputs
         * @author fenris
         */
        var _logprefix = "[lib_translate]";
        /**
         * @desc moves a language to the top of the order, making it the primary one
         * @author fenris
         */
        function promote(identifier) {
            if (Object.keys(_packages).indexOf(identifier) < 0) {
                if (translate._verbosity >= 1) {
                    console.warn(`${_logprefix} package '${identifier}' doesn't exist yet`);
                }
            }
            let position = _order.indexOf(identifier);
            if (position >= 0) {
                if (translate._verbosity >= 2) {
                    console.info(`${_logprefix} '${identifier}' already in order; will promote it`);
                }
                _order.splice(position, 1);
            }
            _order.unshift(identifier);
            if (translate._verbosity >= 2) {
                console.info(`${_logprefix} order is now ${_order.toString()}`);
            }
        }
        translate.promote = promote;
        /**
         * @desc adds a package to the sytem
         * @author fenris
         */
        function add(package_) {
            let identifier = package_.meta.identifier;
            if (identifier in _packages) {
                if (translate._verbosity >= 1) {
                    console.warn(`${_logprefix} package '${identifier}' has already been added; will overwrite`);
                }
            }
            else {
                if (translate._verbosity >= 2) {
                    console.log(`${_logprefix} got package '${identifier}'`);
                }
            }
            _packages[identifier] = package_;
            if (_autopromote) {
                promote(identifier);
            }
        }
        translate.add = add;
        /**
         * @desc integrates a package to the system, i.e. creates a new one if none existed so far or merges with an existing one
         * @author fenris
         */
        function feed(package_) {
            let identifier = package_.meta.identifier;
            if (identifier in _packages) {
                lib_plankton.object.patch(_packages[identifier].tree, package_.tree, {
                    "deep": true,
                });
            }
            else {
                if (translate._verbosity >= 2) {
                    console.info(`${_logprefix} package '${identifier}' didn't exist so far; will create it now`);
                }
                add(package_);
            }
        }
        translate.feed = feed;
        /**
         * @desc tries to retrieve a translation for a specific package identifier
         * @author fenris
         */
        function fetch(identifier, path, args = {}) {
            if (!(identifier in _packages)) {
                if (translate._verbosity >= 1) {
                    console.warn(`${_logprefix} no package '${identifier}'`);
                }
                return (lib_plankton.pod.make_empty());
            }
            else {
                // let str : string = lib_plankton.object.path_read<string>(_packages[identifier].tree, path);
                let str = _packages[identifier].tree[path];
                if (str == undefined) {
                    if (translate._verbosity >= 1) {
                        console.warn(`${_logprefix} string '${path}' missing in package '${identifier}'`);
                    }
                    return (lib_plankton.pod.make_empty());
                }
                else {
                    // resolve references
                    {
                        let regexp_reference = new RegExp("#\\(([\\w\\.]*)(?:\\?(\\w+)=(\\w+)(?:&(\\w+)=(\\w+))*)?\\)");
                        while (true) {
                            let matching = regexp_reference.exec(str);
                            if (matching != null) {
                                let path_ = matching[1];
                                let args_ = {};
                                if (translate._verbosity >= 2) {
                                    // console.info(`${_logprefix} found reference to '${path_}' with args ${JSON.stringify(args_)}`);
                                    console.info(`${_logprefix} found reference to '${path_}'`);
                                }
                                // parse args
                                {
                                    for (let index = 2; index <= matching.length - 1; index += 2) {
                                        let id = matching[index + 0];
                                        let value = matching[index + 1];
                                        if (id != undefined) {
                                            args_[id] = value;
                                        }
                                    }
                                }
                                // fetch referenced string
                                {
                                    let result_ = fetch(identifier, path_, args_);
                                    if (lib_plankton.pod.is_filled(result_)) {
                                        let front = str.slice(0, matching.index);
                                        let back = str.slice(matching.index + matching[0].length);
                                        str = (front + lib_plankton.pod.cull(result_) + back);
                                    }
                                    else {
                                        return (lib_plankton.pod.make_empty());
                                        break;
                                    }
                                }
                            }
                            else {
                                break;
                            }
                        }
                    }
                    // insert arguments
                    {
                        str = lib_plankton.string.coin(str, args);
                    }
                    return (lib_plankton.pod.make_filled(str));
                }
            }
        }
        translate.fetch = fetch;
        /**
         * @desc retrieves a string by going through the order and trying to fetch it for the current entry
         * @author fenris
         * @todo rename to "get"
         */
        function get_new(path, { "args": args = {}, "preferred_language": preferred_language = null, "fallback": fallback = null, } = {}) {
            if (fallback == null) {
                fallback = `{${path}}`;
            }
            if (translate._verbosity >= 2) {
                console.info(`${_logprefix} getting translation for string '${path}' with arguments ${JSON.stringify(args)} …`);
            }
            let result = lib_plankton.pod.make_empty();
            const order = ((preferred_language === null)
                ?
                    _order
                :
                    ([preferred_language].concat(_order.filter(x => (x !== preferred_language)))));
            const found = order.some(identifier => {
                if (translate._verbosity >= 2) {
                    console.info(`${_logprefix} trying package '${identifier}' …`);
                }
                const result_ = fetch(identifier, path, args);
                if (lib_plankton.pod.is_filled(result_)) {
                    result = result_;
                    return true;
                }
                else {
                    return false;
                }
            });
            if (found) {
                const str = lib_plankton.pod.cull(result);
                if (translate._verbosity >= 3) {
                    console.info(`${_logprefix} found translation: '${str}'`);
                }
                return str;
            }
            else {
                const str = fallback;
                if (translate._verbosity >= 1) {
                    console.warn(`${_logprefix} no package provides a translation for string '${path}'; will use the fallback translation '${str}'`);
                }
                return str;
            }
        }
        translate.get_new = get_new;
        /**
         * @desc retrieves a string by going through the order and trying to fetch it for the current entry
         * @author fenris
         * @deprecated use "get_new"
         * @todo remove
         */
        function get(path, args = {}, fallback = null) {
            return get_new(path, {
                "args": args,
                "fallback": fallback,
            });
        }
        translate.get = get;
        /**
         * @author fenris
         */
        function list() {
            return lib_plankton.object.to_array(_packages).map(x => x.value.meta);
        }
        translate.list = list;
        /**
         * @author fenris
         * @todo get rid of this; it's currenly needed only for the cdh-internal lib_completion
         */
        function paths() {
            return lib_plankton.object.keys(lib_plankton.object.flatten(_packages[_order[0]].tree));
        }
        translate.paths = paths;
        /**
         * @author fenris
         */
        function initialize({ "logprefix": logprefix = undefined, "verbosity": verbosity = undefined, "packages": packages = [], "order": order = undefined, "autopromote": autopromote = undefined, } = {}) {
            return (Promise.resolve(undefined)
                // set variables
                .then(_ => {
                if (logprefix != undefined)
                    _logprefix = logprefix;
                if (verbosity != undefined)
                    translate._verbosity = verbosity;
                // _packages = {};
                if (order != undefined)
                    _order = order;
                if (autopromote != undefined)
                    _autopromote = autopromote;
                return Promise.resolve(undefined);
            })
                // feed
                .then(_ => {
                packages.forEach(feed);
                return Promise.resolve(undefined);
            }));
        }
        translate.initialize = initialize;
    })(translate = lib_plankton.translate || (lib_plankton.translate = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:translate«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:translate« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:translate« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:translate«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var translate;
    (function (translate) {
        /**
         * @author fenris
         */
        function iso_639_1_to_iso_639_2(iso6391) {
            let mapping = {
                "af": "afr",
                "ar": "ara",
                "bg": "bul",
                "cs": "ces",
                "da": "dan",
                "de": "deu",
                "el": "ell",
                "en": "eng",
                "eo": "epo",
                "es": "esp",
                "fa": "fas",
                "fi": "fin",
                "fr": "fra",
                "hi": "hin",
                "hr": "hrv",
                "hu": "hun",
                "is": "isl",
                "it": "ita",
                "ja": "jpn",
                "ko": "kor",
                "nb": "nob",
                "nl": "nld",
                "nn": "nno",
                "pt": "por",
                "pl": "pol",
                "ro": "ron",
                "ru": "rus",
                "sk": "slk",
                "sv": "swe",
                "zh": "zho",
            };
            return mapping[iso6391];
        }
        translate.iso_639_1_to_iso_639_2 = iso_639_1_to_iso_639_2;
        /**
         * @author fenris
         */
        function stance(str) {
            let regexp = new RegExp("^translate:(.*)$");
            let matching = regexp.exec(str);
            if (matching != null) {
                return translate.get(matching[1]);
            }
            else {
                return str;
            }
        }
        translate.stance = stance;
    })(translate = lib_plankton.translate || (lib_plankton.translate = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_empty {
            /**
             */
            constructor() {
            }
            /**
             */
            load(target_element) {
                return Promise.resolve(undefined);
            }
        }
        zoo_widget.class_empty = class_empty;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_string {
            /**
             */
            constructor(content) {
                this.content = content;
            }
            /**
             */
            load(target_element) {
                const dom_element = document.createElement("span");
                dom_element.classList.add("widget-string");
                dom_element.textContent = this.content;
                target_element.appendChild(dom_element);
                return Promise.resolve(undefined);
            }
        }
        zoo_widget.class_string = class_string;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_link {
            /**
             */
            constructor(target, { "text": text = null, "open_in_new_tab": open_in_new_tab = false, } = {}) {
                this.target = target;
                this.text = text;
                this.open_in_new_tab = open_in_new_tab;
            }
            /**
             */
            load(target_element) {
                const dom_element = document.createElement("a");
                dom_element.classList.add("widget-link");
                dom_element.textContent = (this.text ?? this.target);
                dom_element.setAttribute("href", this.target);
                dom_element.setAttribute("target", this.open_in_new_tab ? "_blank" : "_self");
                target_element.appendChild(dom_element);
                return Promise.resolve(undefined);
            }
        }
        zoo_widget.class_link = class_link;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_text {
            /**
             */
            constructor(paragraphs) {
                this.paragraphs = paragraphs;
            }
            /**
             */
            load(target_element) {
                const dom_container = document.createElement("div");
                dom_container.classList.add("widget-text");
                this.paragraphs.forEach(paragraph => {
                    const dom_paragraph = document.createElement("p");
                    dom_paragraph.textContent = paragraph;
                    dom_container.appendChild(dom_paragraph);
                });
                target_element.appendChild(dom_container);
                return Promise.resolve(undefined);
            }
        }
        zoo_widget.class_text = class_text;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_list {
            /**
             */
            constructor(elements) {
                this.elements = elements;
            }
            /**
             */
            async load(target_element) {
                const dom_ul = document.createElement("ul");
                dom_ul.classList.add("widget-list");
                for (const element of this.elements) {
                    const dom_li = document.createElement("li");
                    dom_li.classList.add("widget-list-element");
                    await element.load(dom_li);
                    dom_ul.appendChild(dom_li);
                }
                target_element.appendChild(dom_ul);
            }
        }
        zoo_widget.class_list = class_list;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_panel {
            /**
             */
            constructor(content, { "collapseable": collapseable = true, "collapsed_initial_value": collapsed_initial_value = false, "classes": classes = [], } = {}) {
                this.content = content;
                this.collapseable = collapseable;
                this.collapsed_initial_value = collapsed_initial_value;
                this.classes = classes;
            }
            /**
             */
            async load(target_element) {
                const dom_container = document.createElement("div");
                dom_container.classList.add("widget-panel");
                this.classes.forEach(class_ => {
                    dom_container.classList.add(class_);
                });
                // vertical rule
                {
                    const dom_rule = document.createElement("div");
                    dom_rule.classList.add("widget-panel-rule");
                    if (!this.collapseable) {
                        // do nothing
                    }
                    else {
                        dom_rule.addEventListener("click", () => {
                            dom_container.classList.toggle("widget-panel-collapsed");
                        });
                    }
                    dom_container.classList.toggle("widget-panel-collapsed", this.collapsed_initial_value);
                    dom_container.appendChild(dom_rule);
                }
                // content
                {
                    const dom_content = document.createElement("div");
                    dom_content.classList.add("widget-panel-content");
                    await this.content.load(dom_content);
                    dom_container.appendChild(dom_content);
                }
                target_element.appendChild(dom_container);
            }
        }
        zoo_widget.class_panel = class_panel;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_panel_info extends zoo_widget.class_panel {
            /**
             */
            constructor(content, { "collapseable": collapseable = true, "collapsed_initial_value": collapsed_initial_value = false, "classes": classes = [], } = {}) {
                super(content, {
                    "collapseable": collapseable,
                    "collapsed_initial_value": collapsed_initial_value,
                    "classes": ["widget-panel_info"].concat(classes),
                });
            }
        }
        zoo_widget.class_panel_info = class_panel_info;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_panel_warning extends zoo_widget.class_panel {
            /**
             */
            constructor(content, { "collapseable": collapseable = true, "collapsed_initial_value": collapsed_initial_value = false, "classes": classes = [], } = {}) {
                super(content, {
                    "collapseable": collapseable,
                    "collapsed_initial_value": collapsed_initial_value,
                    "classes": ["widget-panel_warning"].concat(classes),
                });
            }
        }
        zoo_widget.class_panel_warning = class_panel_warning;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_panel_error extends zoo_widget.class_panel {
            /**
             */
            constructor(content, { "collapseable": collapseable = true, "collapsed_initial_value": collapsed_initial_value = false, "classes": classes = [], } = {}) {
                super(content, {
                    "collapseable": collapseable,
                    "collapsed_initial_value": collapsed_initial_value,
                    "classes": ["widget-panel_error"].concat(classes),
                });
            }
        }
        zoo_widget.class_panel_error = class_panel_error;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_panel_success extends zoo_widget.class_panel {
            /**
             */
            constructor(content, { "collapseable": collapseable = true, "collapsed_initial_value": collapsed_initial_value = false, "classes": classes = [], } = {}) {
                super(content, {
                    "collapseable": collapseable,
                    "collapsed_initial_value": collapsed_initial_value,
                    "classes": ["widget-panel_success"].concat(classes),
                });
            }
        }
        zoo_widget.class_panel_success = class_panel_success;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_bunch {
            /**
             */
            constructor(elements) {
                this.elements = elements;
            }
            /**
             */
            async load(target_element) {
                const dom_container = document.createElement("div");
                dom_container.classList.add("widget-bunch");
                for (const element of this.elements) {
                    const dom_element = document.createElement("div");
                    dom_element.classList.add("widget-bunch-element");
                    await element.load(dom_element);
                    dom_container.appendChild(dom_element);
                }
                target_element.appendChild(dom_container);
            }
        }
        zoo_widget.class_bunch = class_bunch;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-widget«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-widget« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-widget« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_widget;
    (function (zoo_widget) {
        /**
         */
        class class_slider {
            /**
             */
            constructor(content, { "threshold": threshold = 200, "acceleration_function": acceleration_function = (x => (x * 3)), "initial_index": initial_index = 1, } = {}) {
                this.conf = {
                    "content": content,
                    "threshold": threshold,
                    "acceleration_function": acceleration_function,
                };
                this.state = {
                    "dom_context": null,
                    "index": initial_index,
                    "touch_start_position": null,
                };
            }
            /**
             */
            static cap(minimum, maximum, value) {
                let result = value;
                if (minimum !== null) {
                    result = Math.max(minimum, result);
                }
                if (maximum !== null) {
                    result = Math.min(maximum, result);
                }
                return result;
            }
            /**
             */
            static position_subtract(position1, position2) {
                return {
                    "x": (position1.x - position2.x),
                    "y": (position1.y - position2.y),
                };
            }
            /**
             */
            static touch_event_position(touch_event) {
                return ((touch_event.changedTouches.length <= 0)
                    ?
                        null
                    :
                        {
                            "x": touch_event.changedTouches[0].pageX,
                            "y": touch_event.changedTouches[0].pageY,
                        });
            }
            /**
             */
            set_translation(position) {
                const difference = (((this.state.touch_start_position === null) || (position === null))
                    ?
                        null
                    :
                        class_slider.position_subtract(position, this.state.touch_start_position));
                this.state.dom_context.querySelector(".widget-slider-slides").style.transform = (([
                    lib_plankton.string.coin("translateX({{value}}%)", {
                        "value": ((this.state.index - 1) * (-100)).toFixed(0)
                    })
                ]
                    .concat((difference === null)
                    ?
                        []
                    :
                        [
                            lib_plankton.string.coin("translateX({{value}}px)", {
                                "value": class_slider.cap(((this.state.index >= this.conf.content.length)
                                    ?
                                        (-this.conf.threshold)
                                    :
                                        null), ((this.state.index <= 1)
                                    ?
                                        this.conf.threshold
                                    :
                                        null), this.conf.acceleration_function(difference.x)).toFixed(0),
                            })
                        ]))
                    .join(" "));
            }
            /**
             */
            start(position) {
                if (position === null) {
                    // do nothing
                }
                else {
                    if (this.state.touch_start_position === null) {
                        this.state.touch_start_position = position;
                    }
                    else {
                        // do nothing
                    }
                }
            }
            /**
             */
            update(position) {
                if (position === null) {
                    // do nothing
                }
                else {
                    if (this.state.touch_start_position === null) {
                        // do nothing
                    }
                    else {
                        this.set_translation(position);
                    }
                }
            }
            /**
             */
            finish(position) {
                if (position === null) {
                    this.state.touch_start_position = null;
                    // do nothing
                }
                else {
                    if (this.state.touch_start_position === null) {
                        // do nothing
                    }
                    else {
                        const difference = class_slider.position_subtract(position, this.state.touch_start_position);
                        const offset = this.conf.acceleration_function(difference.x);
                        const index_increment = (() => {
                            if (offset <= -this.conf.threshold) {
                                return ((this.state.index >= this.conf.content.length) ? 0 : (+1));
                            }
                            else if ((offset > -this.conf.threshold) && (offset < this.conf.threshold)) {
                                return 0;
                            }
                            else if (offset >= this.conf.threshold) {
                                return ((this.state.index <= 1) ? 0 : (-1));
                            }
                            else {
                                // not possible
                            }
                        })();
                        this.state.index += index_increment;
                        this.set_translation(null);
                        this.state.touch_start_position = null;
                    }
                }
            }
            /**
             */
            async load(target_element) {
                this.state.dom_context = target_element;
                // style
                {
                    const dom_style = document.createElement("style");
                    dom_style.textContent = ([
                        {
                            "selector": ".widget-slider",
                            "settings": {
                                "overflow": "hidden",
                                "white-space": "nowrap",
                                "width": "100%",
                            },
                        },
                        {
                            "selector": ".widget-slider-slides",
                            "settings": {
                                "width": "100%",
                                "height": "100%",
                                "transition": "transform 0.25s ease-in-out",
                            }
                        },
                        {
                            "selector": ".widget-slider-slide",
                            "settings": {
                                "display": "inline-block",
                                "height": "100%",
                                "width": "100%;",
                                "vertical-align": "top",
                                "white-space": "normal",
                                "transition": "width 0.25s ease-in-out",
                            }
                        }
                    ]
                        .map(rule => lib_plankton.string.coin("{{selector}} {{{settings}}}", {
                        "selector": rule.selector,
                        "settings": (Object.entries(rule.settings)
                            .map(([key, value]) => lib_plankton.string.coin("{{key}}: {{value}};", {
                            "key": key,
                            "value": value,
                        }))
                            .join(" "))
                    }))
                        .join("\n"));
                    this.state.dom_context.appendChild(dom_style);
                }
                // structure
                {
                    const dom_container = document.createElement("div");
                    dom_container.classList.add("widget-slider");
                    {
                        const dom_content = document.createElement("div");
                        dom_content.classList.add("widget-slider-slides");
                        for (const slide of this.conf.content) {
                            const dom_slide = document.createElement("div");
                            dom_slide.classList.add("widget-slider-slide");
                            await slide.load(dom_slide);
                            dom_content.appendChild(dom_slide);
                        }
                        dom_container.appendChild(dom_content);
                    }
                    this.state.dom_context.appendChild(dom_container);
                }
                // listeners
                {
                    this.state.dom_context.addEventListener("touchstart", (event) => {
                        this.start(class_slider.touch_event_position(event));
                    });
                    this.state.dom_context.addEventListener("touchmove", (event) => {
                        this.update(class_slider.touch_event_position(event));
                    });
                    this.state.dom_context.addEventListener("touchend", (event) => {
                        this.finish(class_slider.touch_event_position(event));
                    });
                    this.state.dom_context.addEventListener("touchcancel", (event) => {
                        this.finish(null);
                    });
                }
                this.set_translation(null);
            }
        }
        zoo_widget.class_slider = class_slider;
    })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-page«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-page« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-page« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-page«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_page;
    (function (zoo_page) {
        /**
         */
        zoo_page._pool = {};
        /**
         */
        let _fallback = null;
        /**
         */
        let _current = null;
        /**
         */
        let _target_element = null;
        /**
         */
        let _nav_entries;
        /**
         */
        function encode(location) {
            return ("#"
                +
                    ([location.name]
                        .concat(Object.entries(location.parameters)
                        .filter(([key, value]) => (value !== null))
                        .map(([key, value]) => (key + "=" + value)))));
        }
        zoo_page.encode = encode;
        /**
         */
        function decode(encoded) {
            if (encoded === "") {
                return null;
            }
            else {
                if (!encoded.startsWith("#")) {
                    return null;
                }
                else {
                    const parts = encoded.slice(1).split(",");
                    return {
                        "name": parts[0],
                        "parameters": Object.fromEntries(parts.slice(1)
                            .map(part => {
                            const parts_ = part.split("=");
                            return [parts_[0], parts_[1]];
                        })),
                    };
                }
            }
        }
        /**
         * renders a page to the main element
         */
        async function load(location) {
            // _target_element.innerHTML = "[loading …]";
            _target_element.innerHTML = "";
            if (location === null) {
                // do nothing
            }
            else {
                if (!(location.name in zoo_page._pool)) {
                    _target_element.innerHTML = "not found";
                }
                else {
                    await zoo_page._pool[location.name](location.parameters, _target_element);
                    _current = location;
                }
            }
        }
        /**
         * retrieves the location from the set URL
         */
        function get() {
            return decode(window.location.hash);
        }
        /**
         * encodes a location in the URL and loads it
         */
        function set(location) {
            window.location.hash = encode(location);
        }
        zoo_page.set = set;
        /**
         */
        function reload() {
            return load(get());
        }
        zoo_page.reload = reload;
        /**
         */
        function register(location_name, handler) {
            zoo_page._pool[location_name] = handler;
        }
        zoo_page.register = register;
        /**
         */
        function nav_set_groups(groups) {
            _nav_entries.forEach(nav_entry => {
                const active = ((groups === null)
                    ||
                        groups.some(group => nav_entry.definition.groups.includes(group)));
                nav_entry.element.classList.toggle("active", active);
            });
        }
        zoo_page.nav_set_groups = nav_set_groups;
        /**
         */
        function init(target_element, { "pool": pool = {}, "fallback": fallback = null, "nav_entries": nav_entries = [], "nav_initial_groups": nav_initial_groups = null, } = {}) {
            _target_element = target_element;
            _fallback = fallback;
            Object.entries(pool).forEach(([location_name, handler]) => {
                register(location_name, handler);
            });
            window.addEventListener("hashchange", () => {
                const location_old = _current;
                const location_new = (get() ?? _fallback);
                if (((location_old === null)
                    &&
                        (location_new !== null))
                    ||
                        ((location_old !== null)
                            &&
                                (location_new !== null)
                            &&
                                (location_old.name !== location_new.name))) {
                    load(location_new);
                }
                else {
                    // do nothing
                }
            });
            // nav
            {
                let ul_element = document.querySelector("nav > ul");
                _nav_entries = nav_entries.map(nav_entry_definition => {
                    let li_element = document.createElement("li");
                    {
                        let a_element = document.createElement("a");
                        a_element.setAttribute("href", encode(nav_entry_definition.location));
                        a_element.textContent = (nav_entry_definition.label ?? nav_entry_definition.location.name);
                        li_element.appendChild(a_element);
                    }
                    ul_element.appendChild(li_element);
                    return {
                        "definition": nav_entry_definition,
                        "element": li_element,
                    };
                });
                nav_set_groups(nav_initial_groups);
            }
        }
        zoo_page.init = init;
        /**
         */
        function start() {
            const location = (get() ?? _fallback);
            set(location);
            load(location);
        }
        zoo_page.start = start;
    })(zoo_page = lib_plankton.zoo_page || (lib_plankton.zoo_page = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_simple {
            /**
             */
            constructor(type, decode, encode, { "additional_attributes": additional_attributes = {}, } = {}) {
                this.type = type;
                this.decode = decode;
                this.encode = encode;
                this.additional_attributes = additional_attributes;
                this.dom_input = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_input = document.createElement("input");
                this.dom_input.setAttribute("type", this.type);
                Object.entries(this.additional_attributes).forEach(([key, value]) => {
                    if (value === null) {
                        // do nothing
                    }
                    else {
                        this.dom_input.setAttribute(key, value);
                    }
                });
                parent.appendChild(this.dom_input);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                const value = this.decode(this.dom_input.value);
                return Promise.resolve(value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_input.value = this.encode(value);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_input.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_input.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_input.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_input.focus();
            }
        }
        zoo_input.class_input_simple = class_input_simple;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_wrapped {
            /**
             */
            constructor(core, wrap, unwrap, options = {}) {
                options = Object.assign({}, options);
                this.core = core;
                this.wrap = wrap;
                this.unwrap = unwrap;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                return this.core.setup(parent);
            }
            /**
             * [implementation]
             */
            read() {
                return (this.core.read()
                    .then(value_inner => Promise.resolve(this.wrap(value_inner))));
            }
            /**
             * [implementation]
             */
            write(value) {
                return this.core.write(this.unwrap(value));
            }
            /**
             * [implementation]
             */
            lock(mode) {
                return this.core.lock(mode);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                return this.core.hook_change(action);
            }
            /**
             * [implementation]
             */
            focus() {
                this.core.focus();
            }
        }
        zoo_input.class_input_wrapped = class_input_wrapped;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_soft {
            /**
             */
            constructor(core, { "read_only": read_only = false, } = {}) {
                this.core = core;
                this.dom_set = null;
                this.dom_wrapper = null;
            }
            /**
             */
            toggle(also_element, mode) {
                if (also_element) {
                    this.dom_set.checked = mode;
                }
                else {
                    // do nothing
                }
                this.dom_wrapper.classList.toggle("plankton_input_soft_inactive", (!mode));
            }
            /**
             * [implementation]
             */
            async setup(parent) {
                let dom_container = document.createElement("div");
                dom_container.classList.add("plankton_input_soft_container");
                {
                    // set
                    {
                        this.dom_set = document.createElement("input");
                        this.dom_set.setAttribute("type", "checkbox");
                        this.dom_set.classList.add("plankton_input_soft_setter");
                        dom_container.appendChild(this.dom_set);
                    }
                    // core
                    {
                        this.dom_wrapper = document.createElement("div");
                        this.dom_wrapper.classList.add("plankton_input_soft_core_wrapper");
                        dom_container.appendChild(this.dom_wrapper);
                        await this.core.setup(this.dom_wrapper);
                    }
                }
                this.dom_set.addEventListener("change", (event) => {
                    this.toggle(false, event.target.checked);
                });
                parent.appendChild(dom_container);
                this.toggle(true, false);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                if (!this.dom_set.checked) {
                    return Promise.resolve(null);
                }
                else {
                    return this.core.read();
                }
            }
            /**
             * [implementation]
             */
            write(value) {
                if (value === null) {
                    this.toggle(true, false);
                    return Promise.resolve(undefined);
                }
                else {
                    this.toggle(true, true);
                    return this.core.write(value);
                }
            }
            /**
             * [implementation]
             */
            async lock(mode) {
                if (mode) {
                    this.dom_set.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_set.removeAttribute("disabled");
                }
                await this.core.lock(mode);
            }
            /**
             * [implementation]
             */
            async hook_change(action) {
                this.dom_set.addEventListener("change", () => {
                    action();
                });
                await this.core.hook_change(action);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_set.focus();
            }
        }
        zoo_input.class_input_soft = class_input_soft;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_hidden {
            /**
             */
            constructor({ "initial_value": initial_value = null, } = {}) {
                this.dom_input = null;
                this.value = initial_value;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_input = document.createElement("input");
                this.dom_input.setAttribute("type", "hidden");
                parent.appendChild(this.dom_input);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                const value = this.value;
                return Promise.resolve(value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.value = value;
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
            }
        }
        zoo_input.class_input_hidden = class_input_hidden;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         * @todo abstract
         */
        class class_input_text extends zoo_input.class_input_simple {
            /**
             */
            constructor({ "pattern": pattern = null, "placeholder": placeholder = null,
            // "autocompletion_list": autocompletion_list = null,
             } = {}) {
                super("text", representation => representation, value => value, {
                    "additional_attributes": {
                        "pattern": pattern,
                        "placeholder": placeholder,
                    }
                });
            }
        }
        zoo_input.class_input_text = class_input_text;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_email extends zoo_input.class_input_simple {
            /**
             */
            constructor() {
                super("email", representation => representation, value => value);
            }
        }
        zoo_input.class_input_email = class_input_email;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_textarea {
            /**
             */
            constructor() {
                this.dom_textarea = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_textarea = document.createElement("textarea");
                parent.appendChild(this.dom_textarea);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                return Promise.resolve(this.dom_textarea.value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_textarea.value = value;
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_textarea.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_textarea.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_textarea.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_textarea.focus();
            }
        }
        zoo_input.class_input_textarea = class_input_textarea;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        function value_decode(datestring) {
            const parts = datestring.split("-");
            return {
                "year": parseInt(parts[0]),
                "month": parseInt(parts[1]),
                "day": parseInt(parts[2]),
            };
        }
        /**
         */
        function value_encode(date) {
            return lib_plankton.string.coin("{{year}}-{{month}}-{{day}}", {
                "year": date.year.toFixed(0).padStart(4, "0"),
                "month": date.month.toFixed(0).padStart(2, "0"),
                "day": date.day.toFixed(0).padStart(2, "0"),
            });
        }
        /**
         * @author fenris
         */
        class class_input_date {
            /**
             */
            constructor({ "required": required = false, } = {}) {
                this.required = required;
                this.dom_input = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_input = document.createElement("input");
                this.dom_input.setAttribute("type", "date");
                if (this.required) {
                    this.dom_input.setAttribute("required", "required");
                }
                else { /*do nothing*/ }
                parent.appendChild(this.dom_input);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                if (this.required && (!this.dom_input.reportValidity())) {
                    return Promise.reject("required");
                }
                else {
                    return Promise.resolve((this.dom_input.value === "")
                        ? null
                        : value_decode(this.dom_input.value));
                }
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_input.value = ((value === null)
                    ? ""
                    : value_encode(value));
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_input.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_input.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_input.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_input.focus();
            }
        }
        zoo_input.class_input_date = class_input_date;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         * @todo abstract
         */
        class class_input_number extends zoo_input.class_input_simple {
            /**
             */
            constructor({ "step": step = null, } = {}) {
                super("number", representation => Number(representation), value => value.toString(), {
                    "additional_attributes": {
                        "step": step.toString(),
                    }
                });
            }
        }
        zoo_input.class_input_number = class_input_number;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_checkbox {
            /**
             */
            constructor() {
                this.dom_input = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_input = document.createElement("input");
                this.dom_input.setAttribute("type", "checkbox");
                parent.appendChild(this.dom_input);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                const value = this.dom_input.checked;
                return Promise.resolve(value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_input.checked = value;
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_input.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_input.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_input.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_input.focus();
            }
        }
        zoo_input.class_input_checkbox = class_input_checkbox;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_selection {
            /**
             */
            constructor(options) {
                this.options = options;
                this.dom_select = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_select = document.createElement("select");
                this.options.forEach((option) => {
                    let dom_option = document.createElement("option");
                    dom_option.setAttribute("value", option.value);
                    dom_option.textContent = option.label;
                    this.dom_select.appendChild(dom_option);
                });
                parent.appendChild(this.dom_select);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                return Promise.resolve(this.dom_select.value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_select.value = value;
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_select.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_select.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_select.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_select.focus();
            }
        }
        zoo_input.class_input_selection = class_input_selection;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_enumeration {
            /**
             */
            constructor(encode_value, decode_value, options) {
                this.encode_value = encode_value;
                this.decode_value = decode_value;
                this.options = options;
                this.dom_inputs = [];
            }
            /**
             * [implementation]
             * @todo unique name
             */
            setup(parent) {
                let dom_container = document.createElement("div");
                dom_container.classList.add("plankton_input_enumeration");
                const name = "radio";
                this.options.forEach((option) => {
                    let dom_label = document.createElement("label");
                    let dom_input = document.createElement("input");
                    dom_input.setAttribute("type", "radio");
                    dom_input.setAttribute("name", name);
                    dom_input.setAttribute("value", this.encode_value(option.value));
                    dom_label.appendChild(dom_input);
                    let dom_span = document.createElement("span");
                    dom_span.textContent = option.label;
                    dom_label.appendChild(dom_span);
                    dom_container.appendChild(dom_label);
                    this.dom_inputs.push(dom_input);
                });
                parent.appendChild(dom_container);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                const active_representations = (this.dom_inputs
                    .filter(dom_input => dom_input.checked)
                    .map(dom_input => dom_input.value));
                if (active_representations.length != 1) {
                    return Promise.reject(new Error("nothing picked"));
                }
                else {
                    const value = this.decode_value(active_representations[0]);
                    return Promise.resolve(value);
                }
            }
            /**
             * [implementation]
             */
            write(value) {
                const representation = this.encode_value(value);
                this.dom_inputs.forEach(dom_input => {
                    dom_input.checked = (representation === dom_input.value);
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                this.dom_inputs.forEach(dom_input => {
                    if (mode) {
                        dom_input.setAttribute("disabled", "disabled");
                    }
                    else {
                        dom_input.removeAttribute("disabled");
                    }
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_inputs.forEach(dom_input => {
                    dom_input.addEventListener("change", () => {
                        action();
                    });
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_inputs[0].focus();
            }
        }
        zoo_input.class_input_enumeration = class_input_enumeration;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_list {
            /**
             */
            constructor(element_input_factory, { "read_only": read_only = false, "translations": translations = {
                "add": "add",
                "remove": "remove",
            }, } = {}) {
                this.element_input_factory = element_input_factory;
                this.elements = [];
                this.elements_container_dom = null;
                this.read_only = read_only;
                this.translations = translations;
                this.locked = false;
            }
            /**
             */
            clear() {
                this.elements_container_dom.innerHTML = "";
                this.elements = [];
                return Promise.resolve(undefined);
            }
            /**
             */
            async add() {
                // model
                let element_dom = document.createElement("div");
                const input = this.element_input_factory();
                this.elements.push({ "dom": element_dom, "input": input });
                // view & control
                {
                    element_dom.classList.add("plankton_input_list_element");
                    // remover
                    {
                        let remover_dom = document.createElement("button");
                        remover_dom.classList.add("plankton_input_list_button");
                        remover_dom.classList.add("plankton_input_list_element_remover");
                        remover_dom.setAttribute("title", this.translations.remove);
                        if (this.read_only) {
                            remover_dom.setAttribute("disabled", "disabled");
                        }
                        remover_dom.textContent = "x";
                        remover_dom.addEventListener("click", (event) => {
                            if (this.locked) {
                                // do nothing
                            }
                            else {
                                event.preventDefault();
                                const index = this.elements.findIndex(element => (element.input === input));
                                const element = this.elements[index];
                                this.elements_container_dom.removeChild(element.dom);
                                this.elements.splice(index, 1);
                            }
                        });
                        element_dom.appendChild(remover_dom);
                    }
                    // input
                    {
                        let input_dom = document.createElement("div");
                        input_dom.classList.add("plankton_input_list_element_input");
                        await input.setup(input_dom);
                        element_dom.appendChild(input_dom);
                    }
                    this.elements_container_dom.appendChild(element_dom);
                }
                return Promise.resolve(input);
            }
            /**
             * [implementation]
             */
            setup(parent) {
                let container_dom = document.createElement("div");
                container_dom.classList.add("plankton_input_list");
                // elements
                {
                    this.elements_container_dom = document.createElement("div");
                    this.elements_container_dom.classList.add("plankton_input_list_elements");
                    container_dom.appendChild(this.elements_container_dom);
                }
                // foot
                {
                    let footer_dom = document.createElement("div");
                    footer_dom.classList.add("plankton_input_list_foot");
                    // adder
                    {
                        let adder_dom = document.createElement("button");
                        adder_dom.classList.add("plankton_input_list_button");
                        adder_dom.classList.add("plankton_input_list_adder");
                        adder_dom.setAttribute("title", this.translations.add);
                        if (this.read_only) {
                            adder_dom.setAttribute("disabled", "disabled");
                        }
                        adder_dom.textContent = "+";
                        adder_dom.addEventListener("click", (event) => {
                            if (this.locked) {
                                // do nothing
                            }
                            else {
                                event.preventDefault();
                                this.add();
                            }
                        });
                        footer_dom.appendChild(adder_dom);
                    }
                    container_dom.appendChild(footer_dom);
                }
                parent.appendChild(container_dom);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                return (Promise.all(this.elements
                    .map((element, index) => (element.input.read()
                    .then((element_value) => Promise.resolve({
                    "index": index,
                    "value": element_value,
                })))))
                    .then((elements) => Promise.resolve(elements
                    .sort((x, y) => ((x.index <= y.index) ? 0 : 1))
                    .map(element => element.value))));
            }
            /**
             * [implementation]
             */
            write(value) {
                return (this.clear()
                    .then(() => Promise.all(value
                    .map((element_value) => (this.add()
                    .then(element_input => element_input.write(element_value))))))
                    .then(() => Promise.resolve(undefined)));
            }
            /**
             * [implementation]
             */
            async lock(mode) {
                this.locked = mode;
                for (const element of this.elements) {
                    await element.input.lock(mode);
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            async hook_change(action) {
                for (const element of this.elements) {
                    await element.input.hook_change(action);
                }
            }
            /**
             * [implementation]
             */
            focus() {
                lib_plankton.log.notice("plankton.zoo_input.list.focus.dummy_implementation");
            }
        }
        zoo_input.class_input_list = class_input_list;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        class class_input_set {
            /**
             */
            constructor(options, show_element, { "read_only": read_only = false, } = {}) {
                this.show_element = show_element;
                this.options = options;
                this.read_only = read_only;
                this.checkboxes = new Map();
            }
            /**
             * [implementation]
             */
            setup(parent) {
                for (const option of this.options) {
                    // label
                    const element_container = document.createElement("label");
                    element_container.classList.add("plankton_input_set_option");
                    element_container.setAttribute("rel", option);
                    // checkbox
                    {
                        const element_checkbox = document.createElement("input");
                        element_checkbox.setAttribute("type", "checkbox");
                        element_container.appendChild(element_checkbox);
                        this.checkboxes.set(option, element_checkbox);
                    }
                    // text
                    {
                        const element_text = document.createElement("span");
                        element_text.textContent = this.show_element(option);
                        element_container.appendChild(element_text);
                    }
                    parent.appendChild(element_container);
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                const result = new Set();
                for (const option of this.options) {
                    const element_checkbox = this.checkboxes.get(option);
                    if (element_checkbox.checked) {
                        result.add(option);
                    }
                }
                return Promise.resolve(result);
            }
            /**
             * [implementation]
             */
            write(value) {
                for (const option of this.options) {
                    const element_checkbox = this.checkboxes.get(option);
                    element_checkbox.checked = value.has(option);
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                this.checkboxes.forEach(dom_checkbox => {
                    if (mode) {
                        dom_checkbox.setAttribute("disabled", "disabled");
                    }
                    else {
                        dom_checkbox.removeAttribute("disabled");
                    }
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.checkboxes.forEach(dom_checkbox => {
                    dom_checkbox.addEventListener("change", () => {
                        action();
                    });
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.checkboxes[0].focus();
            }
        }
        zoo_input.class_input_set = class_input_set;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_password {
            /**
             */
            constructor({ "exhibit_initial_value": exhibit_initial_value = false, "character_hide": character_hide = "~", "character_show": character_show = "o", } = {}) {
                this.exhibit = exhibit_initial_value;
                this.character_hide = character_hide;
                this.character_show = character_show;
                this.dom_input = null;
                this.dom_exhibit = null;
            }
            /**
             */
            toggle_exhibition({ "value": value = null, } = {}) {
                this.exhibit = ((value !== null)
                    ?
                        value
                    :
                        (!this.exhibit));
                this.dom_exhibit.textContent = (this.exhibit
                    ?
                        this.character_hide
                    :
                        this.character_show);
                this.dom_input.setAttribute("type", (this.exhibit
                    ?
                        "text"
                    :
                        "password"));
            }
            /**
             * [implementation]
             */
            setup(parent) {
                const dom_container = document.createElement("div");
                dom_container.classList.add("plankton_input_password_container");
                // input
                {
                    this.dom_input = document.createElement("input");
                    this.dom_input.setAttribute("type", "password");
                    this.dom_input.classList.add("plankton_input_password_input");
                    dom_container.appendChild(this.dom_input);
                }
                // exhibit	
                {
                    this.dom_exhibit = document.createElement("div");
                    this.dom_exhibit.classList.add("plankton_input_password_exhibit");
                    this.dom_exhibit.addEventListener("click", () => {
                        this.toggle_exhibition();
                    });
                    dom_container.appendChild(this.dom_exhibit);
                }
                parent.appendChild(dom_container);
                this.toggle_exhibition({ "value": this.exhibit });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                return Promise.resolve(this.dom_input.value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.dom_input.value = value;
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_input.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_input.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_input.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_input.focus();
            }
        }
        zoo_input.class_input_password = class_input_password;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_switch {
            /**
             */
            constructor({ "symbols": symbols = {
                "yes": "✔",
                "no": " "
            }, } = {}) {
                this.dom_element = null;
                this.value = false;
                this.symbols = symbols;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_element = document.createElement("input");
                this.dom_element.setAttribute("type", "text");
                this.dom_element.setAttribute("readonly", "readonly");
                this.dom_element.addEventListener("click", (event) => {
                    this.write(!this.value);
                });
                parent.appendChild(this.dom_element);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                return Promise.resolve(this.value);
            }
            /**
             * [implementation]
             */
            write(value) {
                this.value = value;
                if (value) {
                    this.dom_element.value = this.symbols.yes;
                }
                else {
                    this.dom_element.value = this.symbols.no;
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_element.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_element.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_element.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_element.focus();
            }
        }
        zoo_input.class_input_switch = class_input_switch;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        function value_encode(time) {
            return lib_plankton.string.coin("{{hour}}:{{minute}}", {
                "hour": time.hour.toFixed(0).padStart(2, "0"),
                "minute": time.minute.toFixed(0).padStart(2, "0"),
            });
        }
        /**
         */
        function value_decode(timestring) {
            const parts = timestring.split(":");
            return {
                "hour": parseInt(parts[0]),
                "minute": parseInt(parts[1]),
                "second": 0,
            };
        }
        /**
         * @author fenris
         */
        class class_input_time extends zoo_input.class_input_simple {
            /**
             */
            constructor() {
                super("time", representation => ((representation === "")
                    ?
                        null
                    :
                        value_decode(representation)), value => ((value === null)
                    ?
                        ""
                    :
                        value_encode(value)));
            }
        }
        zoo_input.class_input_time = class_input_time;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_group {
            /**
             */
            constructor(fields_raw) {
                this.fields = (fields_raw
                    .map(field_raw => ({
                    "name": field_raw.name,
                    "input": field_raw.input,
                    "label": (field_raw.label ?? null),
                    "help": (field_raw.help ?? null),
                })));
            }
            /**
             * [implementation]
             */
            async setup(parent) {
                let dom_group = document.createElement("div");
                dom_group.classList.add("plankton_input_group");
                for await (const field of this.fields) {
                    let dom_field = document.createElement("div");
                    dom_field.classList.add("plankton_input_group_field");
                    dom_field.setAttribute("rel", field.name);
                    await Promise.all([
                        // label
                        (async () => {
                            if (field.label === null) {
                                // do nothing
                            }
                            else {
                                let dom_label = document.createElement("label");
                                dom_label.classList.add("plankton_input_group_field_label");
                                dom_label.textContent = field.label;
                                dom_field.appendChild(dom_label);
                            }
                        })(),
                        // help
                        (async () => {
                            if (field.help === null) {
                                // do nothing
                            }
                            else {
                                let dom_help_content = document.createElement("div");
                                dom_help_content.classList.add("plankton_input_group_field_help_content");
                                dom_field.appendChild(dom_help_content);
                                await field.help.load(dom_help_content);
                            }
                        })(),
                        // input
                        field.input.setup(dom_field),
                    ]);
                    dom_group.appendChild(dom_field);
                    // return Promise.resolve<void>(undefined);
                }
                parent.appendChild(dom_group);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            async read() {
                return (Promise.all(this.fields.map((field) => (field.input.read()
                    .then((value) => Promise.resolve({ "key": field.name, "value": value })))))
                    .then(pairs => Promise.resolve(Object.fromEntries(pairs.map((pair) => ([pair.key, pair.value]))))));
            }
            /**
             * [implementation]
             */
            write(value) {
                return (Promise.resolve(Object.entries(value).map(([key, value]) => ({ "key": key, "value": value })))
                    .then((pairs) => Promise.all(pairs.map((pair) => (Promise.all(this.fields.filter((field) => (field.name === pair.key))
                    .map((field) => field.input.write(pair.value)))
                    .then(() => Promise.resolve(undefined))))))
                    .then(() => Promise.resolve(undefined)));
            }
            /**
             * [implementation]
             */
            lock(mode) {
                this.fields.forEach(field => {
                    field.input.lock(mode);
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.fields.forEach(field => {
                    field.input.hook_change(action);
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.fields[0].input.focus();
            }
        }
        zoo_input.class_input_group = class_input_group;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        class class_input_hashmap {
            /**
             */
            constructor(hash_key, key_input_factory, value_input_factory) {
                this.hash_key = hash_key;
                this.core = new zoo_input.class_input_list(() => new zoo_input.class_input_group([
                    {
                        "name": "key",
                        "input": key_input_factory(),
                    },
                    {
                        "name": "value",
                        "input": value_input_factory(),
                    },
                ]));
            }
            /**
             * [implementation]
             */
            setup(parent) {
                return this.core.setup(parent);
            }
            /**
             * [implementation]
             */
            async read() {
                const pairs = await this.core.read();
                const map = lib_plankton.map.hashmap.implementation_map(lib_plankton.map.hashmap.make(this.hash_key, {
                    "pairs": pairs
                }));
                return Promise.resolve(map);
            }
            /**
             * [implementation]
             */
            async write(map) {
                const pairs = lib_plankton.map.dump(map);
                await this.core.write(pairs);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                return this.core.lock(mode);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                return this.core.hook_change(action);
            }
            /**
             * [implementation]
             */
            focus() {
                this.core.focus();
            }
        }
        zoo_input.class_input_hashmap = class_input_hashmap;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        class class_input_datetime {
            /**
             */
            constructor({ "label_timezone_shift": label_timezone_shift = null, "label_date": label_date = null, "label_time": label_time = null, } = {}) {
                /*
                options = Object.assign(
                    {
                        "label_timezone_shift": "",
                        "label_date": "",
                        "label_time": "",
                    },
                    options
                );
                 */
                this.core = new zoo_input.class_input_group([
                    {
                        "name": "timezone_shift",
                        "input": new zoo_input.class_input_number(),
                        "label": label_timezone_shift,
                    },
                    {
                        "name": "date",
                        "input": new zoo_input.class_input_date(),
                        "label": label_date,
                    },
                    {
                        "name": "time",
                        "input": new zoo_input.class_input_soft(new zoo_input.class_input_time()),
                        "label": label_time,
                    },
                ]);
            }
            /**
             */
            setup(parent) {
                return this.core.setup(parent);
            }
            /**
             */
            read() {
                return this.core.read();
            }
            /**
             */
            write(value) {
                return this.core.write(value);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                return this.core.lock(mode);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                return this.core.hook_change(action);
            }
            /**
             * [implementation]
             */
            focus() {
                this.core.focus();
            }
        }
        zoo_input.class_input_datetime = class_input_datetime;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * for central europe with daylight saving time feature
         */
        class class_input_datetime_central_europe {
            /**
             */
            constructor({ "label_date": label_date = "", "label_time": label_time = "", } = {}) {
                this.core = new zoo_input.class_input_group([
                    {
                        "name": "date",
                        "input": new zoo_input.class_input_date(),
                        "label": label_date,
                    },
                    {
                        "name": "time",
                        "input": new zoo_input.class_input_soft(new zoo_input.class_input_time()),
                        "label": label_time,
                    },
                ]);
            }
            /**
             */
            setup(parent) {
                return this.core.setup(parent);
            }
            /**
             */
            async read() {
                const datetime_easy = await this.core.read();
                const datetime_cet = {
                    "timezone_shift": 1,
                    "date": datetime_easy.date,
                    "time": datetime_easy.time,
                };
                const datetime_cest = {
                    "timezone_shift": 2,
                    "date": datetime_easy.date,
                    "time": datetime_easy.time,
                };
                const datetime = (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_cet), lib_plankton.pit.cest_switch_on(datetime_easy.date.year), lib_plankton.pit.cest_switch_off(datetime_easy.date.year))
                    ?
                        datetime_cest
                    :
                        datetime_cet);
                if (datetime_easy.time === null) {
                    datetime.time = null;
                }
                else {
                    // do nothing
                }
                return Promise.resolve(datetime);
            }
            /**
             */
            async write(value) {
                const pit = lib_plankton.pit.from_datetime(value);
                const datetime_utc = lib_plankton.pit.to_datetime(pit, {
                    "timezone_shift": 0,
                });
                const datetime_relative = lib_plankton.pit.to_datetime(pit, {
                    "timezone_shift": (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_utc), lib_plankton.pit.cest_switch_on(datetime_utc.date.year), lib_plankton.pit.cest_switch_off(datetime_utc.date.year))
                        ?
                            2
                        :
                            1)
                });
                const datetime_easy = {
                    "date": datetime_relative.date,
                    "time": ((value.time === null) ? null : datetime_relative.time),
                };
                return this.core.write(datetime_easy);
            }
            /**
             * [implementation]
             */
            lock(mode) {
                return this.core.lock(mode);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                return this.core.hook_change(action);
            }
            /**
             * [implementation]
             */
            focus() {
                this.core.focus();
            }
        }
        zoo_input.class_input_datetime_central_europe = class_input_datetime_central_europe;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        class class_input_color extends zoo_input.class_input_simple {
            /**
             */
            constructor() {
                super("color", (representation) => ((representation === "")
                    ? null
                    : lib_plankton.color.from_hex(representation)), (value) => ((value === null)
                    ? ""
                    : lib_plankton.color.output_hex(value)));
            }
        }
        zoo_input.class_input_color = class_input_color;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         */
        function unwrap(hue) {
            return lib_plankton.color.make_hsv({
                "hue": (hue ?? 0),
                "saturation": 0.5,
                "value": 0.5,
            });
        }
        /**
         */
        function wrap(color) {
            return ((color === null)
                ?
                    null
                :
                    lib_plankton.color.to_hsv(color).hue);
        }
        /**
         */
        class class_input_hue extends zoo_input.class_input_wrapped {
            /**
             */
            constructor() {
                super(new zoo_input.class_input_color(), wrap, unwrap);
            }
        }
        zoo_input.class_input_hue = class_input_hue;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-input« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-input« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_input;
    (function (zoo_input) {
        /**
         * @author fenris
         */
        class class_input_file {
            /**
             */
            constructor({ "required": required = false, "mime_type": mime_type = null, "capture": capture = false, } = {}) {
                this.required = required;
                this.mime_type = mime_type;
                this.capture = capture;
                this.dom_input = null;
            }
            /**
             * [implementation]
             */
            setup(parent) {
                this.dom_input = document.createElement("input");
                this.dom_input.setAttribute("type", "file");
                if (this.mime_type === null) {
                    // do nothing
                }
                else {
                    this.dom_input.setAttribute("accept", this.mime_type);
                }
                if (!this.capture) {
                    // do nothing
                }
                else {
                    this.dom_input.setAttribute("capture", "capture");
                }
                if (!this.required) {
                    // do nothing
                }
                else {
                    this.dom_input.setAttribute("required", "required");
                }
                parent.appendChild(this.dom_input);
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            read() {
                if (this.required && (!this.dom_input.reportValidity())) {
                    return Promise.reject("required");
                }
                else {
                    return (new Promise((resolve, reject) => {
                        if (this.dom_input.files.length <= 0) {
                            resolve(null);
                        }
                        else {
                            const file = this.dom_input.files[0];
                            const reader = new FileReader();
                            reader.onerror = () => {
                                reader.abort();
                                reject(new Error());
                            };
                            reader.onload = (event) => {
                                resolve(reader.result);
                            };
                            // reader.readAsDataURL(file);
                            reader.readAsArrayBuffer(file);
                        }
                    }));
                }
            }
            /**
             * [implementation]
             */
            write(value) {
                if (value === null) {
                    this.dom_input.value = null;
                    return Promise.resolve(undefined);
                }
                else {
                    return Promise.reject(new Error("not implemented (might even be impossible)"));
                }
            }
            /**
             * [implementation]
             */
            lock(mode) {
                if (mode) {
                    this.dom_input.setAttribute("disabled", "disabled");
                }
                else {
                    this.dom_input.removeAttribute("disabled");
                }
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            hook_change(action) {
                this.dom_input.addEventListener("change", () => {
                    action();
                });
                return Promise.resolve(undefined);
            }
            /**
             * [implementation]
             */
            focus() {
                this.dom_input.focus();
            }
        }
        zoo_input.class_input_file = class_input_file;
    })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-form«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-form« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-form« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-form«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_form;
    (function (zoo_form) {
        /**
         */
        function make(method, fields, encode, decode, { "class_prefix": class_prefix = "plankton_form_", } = {}) {
            return {
                "method": method,
                "fields": fields.map(field_raw => ({
                    "name": field_raw.name,
                    "type": field_raw.type,
                    "label": (field_raw.label ?? null),
                })),
                "encode": encode,
                "decode": decode,
                "class_prefix": class_prefix,
                "root_element": null,
            };
        }
        zoo_form.make = make;
        /**
         */
        function make_simple(method, fields, options = {}) {
            options = Object.assign({
                "class_prefix": "plankton_form_",
            }, options);
            return {
                "method": method,
                "fields": fields.map(field_raw => ({
                    "name": field_raw.name,
                    "type": field_raw.type,
                    "label": (field_raw.label ?? null),
                })),
                "encode": x => x,
                "decode": x => x,
                "class_prefix": options.class_prefix,
                "root_element": null,
            };
        }
        zoo_form.make_simple = make_simple;
        /**
         */
        function class_name(subject, name) {
            return lib_plankton.string.coin("{{class_prefix}}{{name}}", {
                "class_prefix": subject.class_prefix,
                "name": name,
            });
        }
        /**
         */
        function field_input(subject, field) {
            return subject.root_element.querySelector(lib_plankton.string.coin(".{{class}}[name=\"{{name}}\"]", {
                "class": class_name(subject, "input"),
                "name": field.name,
            }));
        }
        /**
         */
        function clear(subject) {
            subject.fields.forEach(field => {
                switch (field.type) {
                    default: {
                        field_input(subject, field).value = "";
                        break;
                    }
                    case "checkbox": {
                        field_input(subject, field).checked = false;
                        break;
                    }
                }
            });
        }
        zoo_form.clear = clear;
        /**
         */
        function write(subject, value) {
            let raw = subject.encode(value);
            subject.fields.forEach(field => {
                switch (field.type) {
                    default: {
                        field_input(subject, field).value = raw[field.name];
                        break;
                    }
                    case "checkbox": {
                        field_input(subject, field).checked = (raw[field.name] === "on");
                        break;
                    }
                }
            });
        }
        zoo_form.write = write;
        /**
         */
        function read(subject) {
            let raw = {};
            subject.fields.forEach(field => {
                switch (field.type) {
                    default: {
                        raw[field.name] = field_input(subject, field).value;
                        break;
                    }
                    case "checkbox": {
                        raw[field.name] = (field_input(subject, field).checked ? "on" : "off");
                        break;
                    }
                }
            });
            const value = subject.decode(raw);
            return value;
        }
        zoo_form.read = read;
        /**
         */
        async function render(subject, target) {
            let element_form = document.createElement("form");
            element_form.classList.add(class_name(subject, "form"));
            subject.fields.forEach(field => {
                let element_field = document.createElement("div");
                element_field.classList.add(class_name(subject, "field"));
                // label
                {
                    let element_label = document.createElement("label");
                    element_label.classList.add(class_name(subject, "label"));
                    element_field.appendChild(element_label);
                    element_label.textContent = (field.label
                        ??
                            field.name.split("_").join(" "));
                }
                // input
                {
                    let element_input = document.createElement("input");
                    element_input.classList.add(class_name(subject, "input"));
                    element_input.setAttribute("name", field.name);
                    element_input.setAttribute("type", field.type);
                    element_field.appendChild(element_input);
                }
                element_form.appendChild(element_field);
            });
            subject.root_element = element_form;
            target.appendChild(element_form);
            return Promise.resolve(undefined);
        }
        zoo_form.render = render;
    })(zoo_form = lib_plankton.zoo_form || (lib_plankton.zoo_form = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-form«.

Copyright 2016-2025 'kcf' <fenris@folksprak.org>

»bacterio-plankton:zoo-form« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

»bacterio-plankton:zoo-form« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-form«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_plankton;
(function (lib_plankton) {
    var zoo_form;
    (function (zoo_form) {
        /**
         * @author fenris
         */
        class class_form {
            /**
             */
            constructor(encode, decode, input, actions) {
                this.encode = encode;
                this.decode = decode;
                this.input = input;
                this.actions = actions;
            }
            /**
             */
            async setup(parent) {
                let dom_form = document.createElement("form");
                dom_form.classList.add("plankton_form");
                // input
                {
                    let dom_container = document.createElement("div");
                    dom_container.classList.add("plankton_form_input");
                    await this.input.setup(dom_container);
                    dom_form.appendChild(dom_container);
                }
                // actions
                {
                    let dom_container = document.createElement("div");
                    dom_container.classList.add("plankton_form_actions");
                    this.actions.forEach((action) => {
                        let dom_button = document.createElement("button");
                        // dom_button.setAttribute("type", "submit");
                        dom_button.textContent = action.label;
                        if (action.target !== undefined) {
                            dom_button.setAttribute("formaction", action.target);
                        }
                        if (action.procedure !== undefined) {
                            dom_button.addEventListener("click", (event) => {
                                event.preventDefault();
                                action.procedure(() => this.input_read(), () => this.input_read_raw());
                            });
                        }
                        dom_container.appendChild(dom_button);
                    });
                    dom_form.appendChild(dom_container);
                }
                parent.appendChild(dom_form);
            }
            /**
             */
            input_read_raw() {
                return this.input.read();
            }
            /**
             */
            async input_read() {
                return this.decode(await this.input.read());
            }
            /**
             */
            input_write(value) {
                return this.input.write(this.encode(value));
            }
            /**
             */
            input_lock(mode) {
                return this.input.lock(mode);
            }
            /**
             */
            input_focus() {
                return this.input.focus();
            }
        }
        zoo_form.class_form = class_form;
    })(zoo_form = lib_plankton.zoo_form || (lib_plankton.zoo_form = {}));
})(lib_plankton || (lib_plankton = {}));
