#!/usr/bin/env node

/*
	
Build system abstractor "Koralle"
Copyright (C) 2016-2022 greenscale it <info@greenscale.de>

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

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
*/

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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 {
        var 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-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_base;
(function (lib_base) {
    /**
     * @author fenris
     */
    function environment() {
        var entries = [
            {
                "id": "web",
                "name": "Web",
                "predicate": function () { return (typeof (document) !== "undefined"); },
            },
            {
                "id": "node",
                "name": "Node.js",
                "predicate": function () { return (typeof (process) !== "undefined"); },
            },
            {
                "id": "rhino",
                "name": "Rhino",
                "predicate": function () { return (typeof (java) !== "undefined"); },
            },
            {
                "id": "webworker",
                "name": "WebWorker",
                "predicate": function () { return (typeof (self["WorkerNavigator"]) !== "undefined"); }
            }
        ];
        var id;
        var found = entries.some(function (entry) {
            if (entry.predicate()) {
                id = entry.id;
                return true;
            }
            else {
                return false;
            }
        });
        if (found) {
            return id;
        }
        else {
            throw (new Error("unknown environment"));
        }
    }
    lib_base.environment = environment;
})(lib_base || (lib_base = {}));
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_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_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_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_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_log.warn("[show]" + " " + "primitive value; using default implementation");
        }
        return String(value);
    }
}
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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/>.
 */
/**
 * @todo outsource to dedicated plankton-lib
 */
var lib_log;
(function (lib_log) {
    /**
     * @author fenris
     */
    function log() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        /*window.*/ console.log.apply(console, args);
    }
    lib_log.log = log;
    /**
     * @author fenris
     */
    function info() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        /*window.*/ console.info.apply(console, args);
    }
    lib_log.info = info;
    /**
     * @author fenris
     */
    function warn() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        /*window.*/ console.warn.apply(console, args);
    }
    lib_log.warn = warn;
    /**
     * @author fenris
     */
    function error() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        /*window.*/ console.error.apply(console, args);
    }
    lib_log.error = error;
})(lib_log || (lib_log = {}));
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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
 */
var class_observer = /** @class */ (function () {
    /**
     * @author frac
     */
    function class_observer() {
        this.counter = 0;
        this.actions = {};
        this.buffer = [];
    }
    /**
     * @author frac
     */
    class_observer.prototype.empty = function () {
        return (Object.keys(this.actions).length == 0);
    };
    /**
     * @author frac
     */
    class_observer.prototype.flush = function () {
        this.actions = {};
    };
    /**
     * @author frac
     */
    class_observer.prototype.set = function (id, action) {
        this.actions[id] = action;
    };
    /**
     * @author frac
     */
    class_observer.prototype.del = function (id) {
        delete this.actions[id];
    };
    /**
     * @author frac
     */
    class_observer.prototype.add = function (action) {
        this.set((this.counter++).toString(), action);
    };
    /**
     * @author frac
     */
    class_observer.prototype.notify = function (information, delayed) {
        var _this = this;
        if (information === void 0) { information = {}; }
        if (delayed === void 0) { delayed = false; }
        if (delayed) {
            this.buffer.push(information);
        }
        else {
            Object.keys(this.actions).forEach(function (id) { return _this.actions[id](information); });
        }
    };
    /**
     * @author frac
     */
    class_observer.prototype.rollout = function () {
        var _this = this;
        this.buffer.forEach(function (information) { return _this.notify(information, false); });
        this.buffer = [];
    };
    return class_observer;
}());
/**
 * @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-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_maybe;
(function (lib_maybe) {
    /**
     * @author fenris
     */
    function make_nothing() {
        return {
            "kind": "nothing",
            "parameters": {}
        };
    }
    lib_maybe.make_nothing = make_nothing;
    /**
     * @author fenris
     */
    function make_just(value) {
        return {
            "kind": "just",
            "parameters": {
                "value": value
            }
        };
    }
    lib_maybe.make_just = make_just;
    /**
     * @author fenris
     */
    function is_nothing(maybe) {
        return (maybe.kind === "nothing");
    }
    lib_maybe.is_nothing = is_nothing;
    /**
     * @author fenris
     */
    function is_just(maybe) {
        return (maybe.kind === "just");
    }
    lib_maybe.is_just = is_just;
    /**
     * @author fenris
     */
    function cull(maybe) {
        if (!is_just(maybe)) {
            var message = "cull from nothing";
            throw (new Error(message));
        }
        else {
            var value = maybe.parameters["value"];
            return value;
        }
    }
    lib_maybe.cull = cull;
    /**
     * @author fenris
     */
    function propagate(maybe, function_) {
        if (!is_just(maybe)) {
        }
        else {
            var value = maybe.parameters["value"];
            var maybe_ = function_(value);
            return maybe_;
        }
    }
    lib_maybe.propagate = propagate;
})(lib_maybe || (lib_maybe = {}));
/**
 * @author fenris
 */
/*export*/ var class_maybe = /** @class */ (function () {
    function class_maybe() {
    }
    /**
     * @desc whether the wrapper is nothing
     * @author fenris
     */
    class_maybe.prototype.is_nothing = function () {
        throw (new Error("not implemented: class_maybe.is_nothing"));
    };
    /**
     * @desc whether the wrapper is just
     * @author fenris
     */
    class_maybe.prototype.is_just = function () {
        throw (new Error("not implemented: class_maybe.is_just"));
    };
    /**
     * @desc return the value, stored in the maybe-wrapper
     * @author fenris
     */
    class_maybe.prototype.cull = function () {
        throw (new Error("not implemented: class_maybe.cull"));
    };
    /**
     * @author fenris
     */
    class_maybe.prototype.toString = function () {
        throw (new Error("not implemented: class_maybe.cull"));
    };
    /**
     * @author fenris
     */
    class_maybe.prototype.distinguish = function (action_just, action_nothing) {
        if (action_nothing === void 0) { action_nothing = function () { }; }
        throw (new Error("not implemented: class_maybe.distinguish"));
    };
    /**
     * @author fenris
     */
    class_maybe.prototype.propagate = function (action) {
        throw (new Error("not implemented: class_maybe.propagate"));
    };
    /**
     * @desc [implementation]
     * @author fenris
     */
    class_maybe.prototype._show = function () {
        return this.toString();
    };
    return class_maybe;
}());
/**
 * @author fenris
 */
/*export*/ var class_nothing = /** @class */ (function (_super) {
    __extends(class_nothing, _super);
    /**
     * @author fenris
     */
    function class_nothing(reason) {
        if (reason === void 0) { reason = null; }
        var _this = _super.call(this) || this;
        _this.reason = reason;
        return _this;
    }
    /**
     * @author fenris
     */
    class_nothing.prototype.is_nothing = function () {
        return true;
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.is_just = function () {
        return false;
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.cull = function () {
        var message = "you shouldn't cull a nothing-value …";
        lib_log.warn(message);
        return null;
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.toString = function () {
        return "<\u00B7>";
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.reason_get = function () {
        var content = ((this.reason == null) ? "·" : this.reason);
        return "<- " + content + " ->";
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.distinguish = function (action_just, action_nothing) {
        if (action_nothing === void 0) { action_nothing = function () { }; }
        action_nothing(this.reason);
    };
    /**
     * @author fenris
     */
    class_nothing.prototype.propagate = function (action) {
        return (new class_nothing(this.reason));
    };
    return class_nothing;
}(class_maybe));
/**
 * @author fenris
 */
/*export*/ var class_just = /** @class */ (function (_super) {
    __extends(class_just, _super);
    /**
     * @author fenris
     */
    function class_just(value) {
        var _this = _super.call(this) || this;
        _this.value = value;
        return _this;
    }
    /**
     * @author fenris
     */
    class_just.prototype.is_nothing = function () {
        return false;
    };
    /**
     * @author fenris
     */
    class_just.prototype.is_just = function () {
        return true;
    };
    /**
     * @author fenris
     */
    class_just.prototype.cull = function () {
        return this.value;
    };
    /**
     * @author fenris
     */
    class_just.prototype.toString = function () {
        var content = instance_show(this.value);
        return "<+ " + content + " +>";
    };
    /**
     * @author fenris
     */
    class_just.prototype.distinguish = function (action_just, action_nothing) {
        if (action_nothing === void 0) { action_nothing = function () { }; }
        action_just(this.value);
    };
    /**
     * @author fenris
     */
    class_just.prototype.propagate = function (action) {
        return action(this.value);
    };
    return class_just;
}(class_maybe));
/*
This file is part of »bacterio-plankton:base«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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
 */
var class_error = /** @class */ (function (_super) {
    __extends(class_error, _super);
    /**
     * @author frac
     */
    function class_error(message, suberrors) {
        if (suberrors === void 0) { suberrors = []; }
        var _this = _super.call(this, message) || this;
        _this.suberrors = suberrors;
        _this.mess = message;
        return _this;
    }
    /**
     * @override
     * @author frac
     */
    class_error.prototype.toString = function () {
        return ( /*super.toString()*/this.mess + " " + ("[" + this.suberrors.map(function (x) { return x.toString(); }).join(",") + "]"));
    };
    return class_error;
}(Error));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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/>.
 */
"use strict";
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_call) {
    /**
     * @desc hacked class for postfix function application
     * @author fenris
     */
    class class_valuewrapper {
        /**
         * @desc [constructor]
         * @author fenris
         */
        constructor(value) {
            this.value = value;
        }
        /**
         * @desc [accessor] applies a function and returns a new valuewrapper
         * @author fenris
         */
        pass(function_) {
            return (new class_valuewrapper(function_(this.value)));
        }
        /**
         * @desc [accessor] gives the wrapped value
         * @author fenris
         */
        extract() {
            return this.value;
        }
    }
    lib_call.class_valuewrapper = class_valuewrapper;
    /**
     * @desc shortcut for constructing a valuewrapper-object
     * @author fenris
     */
    function vw(value) {
        return (new class_valuewrapper(value));
    }
    lib_call.vw = vw;
    /**
     * @author fenris
     */
    function use(input, function_) {
        return function_(input);
    }
    lib_call.use = use;
    /**
     * @desc just the identity; useful for some callbacks etc.
     * @author fenris
     */
    function id(x) {
        return x;
    }
    lib_call.id = id;
    /**
     * @desc 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, lib_call.args2list(arguments)));
        });
    }
    lib_call.compose = compose;
    /**
     * @desc transforms a function with sequential input into a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
     * @param {function} f
     * @param {int} n (don't set manually)
     * @return {function} the currified version of the in put function
     * @author fenris
     */
    function curryfy(f, n = f.length) {
        switch (n) {
            case 0: {
                throw (new Error("[curryfy] impossible"));
                // break;
            }
            case 1: {
                return f;
                // break;
            }
            default: {
                return (function (x) {
                    return (curryfy(function () { return f.apply(f, [x].concat(lib_call.args2list(arguments))); }, n - 1));
                });
                // break;
            }
        }
    }
    lib_call.curryfy = curryfy;
})(lib_call || (lib_call = {}));
var lib_call;
(function (lib_call) {
    /**
     * @author fenris
     */
    function executor_resolve(result) {
        return ((resolve, reject) => resolve(result));
    }
    lib_call.executor_resolve = executor_resolve;
    /**
     * @author fenris
     */
    function executor_reject(reason) {
        return ((resolve, reject) => reject(reason));
    }
    lib_call.executor_reject = executor_reject;
    /**
     * @author fenris
     */
    function executor_transform(executor, transform_result, transform_reason) {
        return ((resolve, reject) => {
            executor(result => resolve(transform_result(result)), reason => reject(transform_reason(reason)));
        });
    }
    lib_call.executor_transform = executor_transform;
    /**
     * @author fenris
     */
    function executor_transform_default(executor, transform_result, wrap_string = null) {
        let transform_reason = (error => ((wrap_string == null) ? error : new class_error(wrap_string, [error])));
        return (executor_transform(executor, transform_result, transform_reason));
    }
    lib_call.executor_transform_default = executor_transform_default;
    /**
     * @author fenris
     */
    function executor_compose_sequential(first, second) {
        return ((resolve, reject) => {
            first(result => {
                second(result)(resolve, reject);
            }, reason => {
                reject(reason);
            });
        });
    }
    lib_call.executor_compose_sequential = executor_compose_sequential;
    /**
     * @author fenris
     */
    function executor_chain(state, executors) {
        return ((resolve, reject) => {
            if (executors.length == 0) {
                return resolve(state);
            }
            else {
                return executors[0](state)(result => {
                    executor_chain(result, executors.slice(1))(resolve, reject);
                }, reject);
            }
        });
        /*
         */
        /*
        if (executors.length == 0) {
            return executor_resolve<type_state, type_error>(state);
        }
        else if (executors.length == 1) {
            return executors[0](state);
        }
        else {
            return (
                executor_chain<type_state, type_error>(
                    state,
                    [
                        state => (resolve, reject) => executors[0](state)(result => executors[1](result)(resolve, reject), reject)
                    ].concat(executors.slice(2))
                )
            );
        }
         */
        /*
        return (
            executors.reduce(
                (chain, current) => executor_compose_sequential<type_state, type_state, type_error>(chain, current, deferred),
                executor_resolve<type_state, type_error>(state)
            )
        );
         */
    }
    lib_call.executor_chain = executor_chain;
    /**
     * @author fenris
     */
    function executor_first(executors) {
        /*
        return (
            (resolve, reject) => {
                if (executors.length == 0) {
                    reject(new Error("all failed"));
                }
                else {
                    executors[0](
                        result => {
                            resolve(result);
                        },
                        reason => {
                            executor_first<type_result, type_reason>(executors.slice(1))(resolve, reject);
                        }
                    )
                }
            }
        );
         */
        return ((resolve, reject) => {
            executor_chain([], executors.map(executor => reasons => (resolve_, reject_) => {
                executor(result => reject_(result), reason => resolve_(reasons.concat([reason])));
            }))(errors => reject(errors), result => resolve(result));
        });
    }
    lib_call.executor_first = executor_first;
    /**
     * @author fenris
     */
    function executor_condense(executors) {
        return (executor_chain([], executors.map(executor => result => (resolve, reject) => {
            executor(element => resolve(result.concat([element])), reject);
        })));
    }
    lib_call.executor_condense = executor_condense;
    /**
     * @author fenris
     * @deprecated use condense
     */
    function executor_filter(executors, predicate) {
        return (executor_chain([], executors.map(executor => result => (resolve, reject) => {
            executor(element => resolve(predicate(element) ? result.concat([element]) : result), reject);
        })));
    }
    lib_call.executor_filter = executor_filter;
    /**
     * @author fenris
     * @deprecated use condense
     */
    function executor_map(executors, transformator) {
        return (executor_chain([], executors.map(executor => result => (resolve, reject) => {
            executor(element1 => resolve(result.concat([transformator(element1)])), reject);
        })));
    }
    lib_call.executor_map = executor_map;
    /**
     * @author fenris
     * @deprecated use condense
     */
    function executor_reduce(executors, initial, accumulator) {
        return (executor_chain(initial, executors.map(executor => result => (resolve, reject) => {
            executor(element => resolve(accumulator(result, element)), reject);
        })));
    }
    lib_call.executor_reduce = executor_reduce;
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_call) {
    /**
     * @author fenris
     */
    function promise_reject(reason) {
        return Promise.reject(reason);
    }
    lib_call.promise_reject = promise_reject;
    /**
     * @author fenris
     */
    function promise_resolve(result) {
        return Promise.resolve(result);
    }
    lib_call.promise_resolve = promise_resolve;
    /**
     * @author fenris
     */
    function promise_make(executor) {
        return (new Promise(executor));
    }
    lib_call.promise_make = promise_make;
    /**
     * @author fenris
     */
    function promise_then_close(promise, resolver, rejector) {
        promise.then(resolver, rejector);
    }
    lib_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));
    }
    lib_call.promise_then_append = promise_then_append;
    /**
     * @author fenris
     */
    function promise_all(promises) {
        return Promise.all(promises);
    }
    lib_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)));
    }
    lib_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])))), []));
    }
    lib_call.promise_condense = promise_condense;
    /**
     * @author fenris
     */
    function promise_group(promises, serial = false) {
        const decorate = function (promise, name) {
            return (() => promise_then_append(promise(), value => promise_resolve({ "key": name, "value": value })));
        };
        const convert = function (array) {
            let object = {};
            array.forEach(({ "key": key, "value": value }) => { object[key] = value; });
            return object;
        };
        if (serial) {
            return (promise_then_append(promise_condense(Object.keys(promises)
                .map(name => decorate(promises[name], name))), list => promise_resolve(convert(list))));
        }
        else {
            return (promise_then_append(promise_all(Object.keys(promises)
                .map(name => decorate(promises[name], name))
                .map(promise => promise())), list => promise_resolve(convert(list))));
        }
    }
    lib_call.promise_group = promise_group;
    /**
     * @author fenris
     */
    function promise_wrap(promise, transformator_result, transformator_reason = lib_call.id) {
        return (promise_make((resolve, reject) => {
            promise_then_close(promise, result => resolve(transformator_result(result)), reason => reject(transformator_reason(reason)));
        }));
    }
    lib_call.promise_wrap = promise_wrap;
    /**
     * @author fenris
     */
    function promise_show(label) {
        return (result => promise_make((resolve, reject) => {
            lib_log.info(label + ": " + instance_show(result));
            resolve(result);
        }));
    }
    lib_call.promise_show = promise_show;
    /**
     * @author fenris
     */
    function promise_log(result) {
        return promise_show("log");
    }
    lib_call.promise_log = promise_log;
    /**
     * @author fenris
     */
    function promise_attach(state, promise, name) {
        return (promise_wrap(promise, result => {
            state[name] = result;
            return state;
        }));
    }
    lib_call.promise_attach = promise_attach;
    /**
     * @author fenris
     */
    function promise_delay(promise, delay) {
        return promise_make((resolve, reject) => {
            lib_call.timeout(() => {
                promise_then_close(promise, resolve, reject);
                return null;
            }, delay);
        });
    }
    lib_call.promise_delay = promise_delay;
    /**
     * @author fenris
     */
    function promise_to_executor(promise) {
        return ((resolve, reject) => promise.then(resolve, reject));
    }
    lib_call.promise_to_executor = promise_to_executor;
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_call) {
    lib_call.initializer_state_initial = 0;
    lib_call.initializer_state_waiting = 1;
    lib_call.initializer_state_successful = 2;
    lib_call.initializer_state_failed = 3;
    /**
     * @author fenris
     */
    function initializer_make(fetcher) {
        let subject = {
            "fetcher": fetcher,
            "state": lib_call.initializer_state_initial,
            "queue": [],
            "result": undefined,
            "reason": undefined,
        };
        return subject;
    }
    lib_call.initializer_make = initializer_make;
    /**
     * @author fenris
     */
    function initializer_actuate(subject) {
        switch (subject.state) {
            case lib_call.initializer_state_successful: {
                subject.queue.forEach(entry => entry.resolve(subject.result));
                break;
            }
            case lib_call.initializer_state_failed: {
                subject.queue.forEach(entry => entry.reject(subject.reason));
                break;
            }
            default: {
                let message = `unhandled state ${subject.state}`;
                throw (new Error(message));
                break;
            }
        }
    }
    /**
     * @author fenris
     */
    function initializer_reset(subject) {
        subject.state = lib_call.initializer_state_initial;
        subject.queue = [];
    }
    lib_call.initializer_reset = initializer_reset;
    /**
     * @author fenris
     */
    function initializer_state(subject) {
        return subject.state;
    }
    lib_call.initializer_state = initializer_state;
    /**
     * @author fenris
     */
    function initializer_get(subject) {
        switch (subject.state) {
            case lib_call.initializer_state_initial: {
                subject.state = lib_call.initializer_state_waiting;
                return (lib_call.promise_make((resolve, reject) => {
                    subject.queue.push({ "resolve": resolve, "reject": reject });
                    subject.fetcher().then(result => {
                        subject.state = lib_call.initializer_state_successful;
                        subject.result = result;
                        initializer_actuate(subject);
                    }, reason => {
                        subject.state = lib_call.initializer_state_failed;
                        subject.reason = reason;
                        initializer_actuate(subject);
                    });
                }));
                break;
            }
            case lib_call.initializer_state_waiting: {
                return (lib_call.promise_make((resolve, reject) => {
                    subject.queue.push({ "resolve": resolve, "reject": reject });
                }));
                break;
            }
            case lib_call.initializer_state_successful: {
                return (lib_call.promise_resolve(subject.result));
                break;
            }
            case lib_call.initializer_state_failed: {
                return (lib_call.promise_reject(subject.reason));
                break;
            }
            default: {
                let message = `unhandled state ${subject.state}`;
                throw (new Error(message));
                break;
            }
        }
    }
    lib_call.initializer_get = initializer_get;
    /**
     * @author fenris
     */
    function initializer_get_sync(subject) {
        switch (subject.state) {
            case lib_call.initializer_state_successful: {
                return subject.result;
                break;
            }
            case lib_call.initializer_state_failed: {
                throw subject.reason;
                break;
            }
            default: {
                let message = `unhandled state ${subject.state}`;
                throw (new Error(message));
                break;
            }
        }
    }
    /**
     * @author fenris
     */
    function initializer_set_sync(subject, result) {
        switch (subject.state) {
            case lib_call.initializer_state_successful: {
                subject.result = result;
                break;
            }
            case lib_call.initializer_state_failed: {
                subject.state = lib_call.initializer_state_successful;
                subject.result = result;
                break;
            }
            default: {
                let message = `unhandled state ${subject.state}`;
                throw (new Error(message));
                break;
            }
        }
    }
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_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;
        });
    }
    lib_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);
            })))
        });
    }
    lib_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))));
    }
    lib_call.deferral_wrap = deferral_wrap;
    /**
     * @author fenris
     */
    function deferral_id() {
        return (deferral_make((input, convey) => convey(input)));
    }
    lib_call.deferral_id = deferral_id;
    /**
     * @author fenris
     */
    function deferral_const(value) {
        return (deferral_make((input, convey) => convey(value)));
    }
    lib_call.deferral_const = deferral_const;
    /**
     * @author fenris
     */
    function deferral_delay(output, delay) {
        return (deferral_make((input, convey) => {
            setTimeout(() => convey(output), delay);
        }));
    }
    lib_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)))
        };
    }
    lib_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_maybe.make_nothing(),
                "right": lib_maybe.make_nothing(),
            };
            let finish = function () {
                if (lib_maybe.is_just(object.left)
                    &&
                        lib_maybe.is_just(object.right)) {
                    let result = {
                        "left": lib_maybe.cull(object.left),
                        "right": lib_maybe.cull(object.right),
                    };
                    convey(result);
                }
                else {
                    // do nothing
                }
            };
            deferral_use(deferral_left, input, output_left => {
                object.left = lib_maybe.make_just(output_left);
                finish();
            });
            deferral_use(deferral_right, input, output_right => {
                object.right = lib_maybe.make_just(output_right);
                finish();
            });
        }));
    }
    lib_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()));
    }
    lib_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}> {
        
    }
     */
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_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(lib_call.deferral_make(handler)));
        }
        /**
         * @author fenris
         */
        use(input, procedure) {
            return (lib_call.deferral_use(class_deferral._tear(this), input, procedure));
        }
        /**
         * @author fenris
         */
        compose_serial(second) {
            return (class_deferral._cram(lib_call.deferral_compose_serial(class_deferral._tear(this), class_deferral._tear(second))));
        }
        /**
         * @author fenris
         */
        static chain(members) {
            return (class_deferral._cram(lib_call.deferral_chain(members.map(member => class_deferral._tear(member)))));
        }
        /**
         * @author fenris
         */
        static wrap(function_) {
            return (class_deferral._cram(lib_call.deferral_wrap(function_)));
        }
        /**
         * @author fenris
         */
        static const_(value) {
            return (class_deferral._cram(lib_call.deferral_const(value)));
        }
        /**
         * @author fenris
         */
        static delay(output, delay) {
            return (class_deferral._cram(lib_call.deferral_delay(output, delay)));
        }
    }
    lib_call.class_deferral = class_deferral;
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:call«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_call;
(function (lib_call) {
    /**
     * @author fenris
     */
    function timeout(function_, delay) {
        return (
        /*window.*/ setTimeout(function_, delay));
    }
    lib_call.timeout = timeout;
    /**
     * @desc a definition for a value being "defined"
     * @author neuc
     */
    function is_def(obj, null_is_valid = false) {
        return (!((typeof (obj) === "undefined")
            ||
                (!null_is_valid && (obj === null))));
    }
    lib_call.is_def = is_def;
    /**
     * @desc 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, type = null, null_is_valid = false) {
        if (is_def(value, null_is_valid)
            &&
                (is_def(type)
                    ? ((typeof value === type)
                        ||
                            ((value === null)
                                &&
                                    null_is_valid))
                    : true)) {
            return value;
        }
        else {
            return default_value;
        }
    }
    lib_call.def_val = def_val;
    ;
    /**
     * @desc just the empty function; useful for some callbacks etc.
     * @author fenris
     */
    function nothing() {
    }
    lib_call.nothing = nothing;
    /**
     * @desc outputs
     * @author fenris
     */
    function output(...args) {
        lib_log.info.apply(lib_log, args);
    }
    lib_call.output = output;
    /**
     * @desc converts the "arguments"-map into an array
     * @param {Object} args
     * @author fenris
     */
    function args2list(args) {
        return Object.keys(args).map(key => args[key]);
    }
    lib_call.args2list = args2list;
    /**
     * @desc provides the call for an attribute of a class as a regular function
     * @param {string} name the name of the attribute
     * @return {*}
     * @author fenris
     */
    function attribute(name) {
        return ((object) => object[name]);
    }
    lib_call.attribute = attribute;
    /**
     * @desc provides a method of a class as a regular function
     * @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)); });
    }
    lib_call.method = method;
    /**
     * @author fenris
     */
    function distinguish(unival, handlers, fallback = null) {
        if (unival.kind in handlers) {
            let handler = handlers[unival.kind];
            return handler(unival.data);
        }
        else {
            let message = ("unhandled kind '" + unival.kind + "'");
            if (fallback !== null) {
                console.warn(message);
                return fallback(unival);
            }
            else {
                throw (new Error(message));
            }
        }
    }
    lib_call.distinguish = distinguish;
})(lib_call || (lib_call = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    var _pool = {};
    /**
     * @author fenris
     */
    var _aliases = {};
    /**
     * @author fenris
     */
    function list() {
        return [].concat(Object.keys(_pool)).concat(Object.keys(_aliases));
    }
    lib_shape.list = list;
    /**
     * @author fenris
     */
    function inspection_create() {
        return {
            "messages": []
        };
    }
    lib_shape.inspection_create = inspection_create;
    /**
     * @author fenris
     */
    function inspection_add(main, message) {
        main.messages.push(message);
    }
    lib_shape.inspection_add = inspection_add;
    /**
     * @author fenris
     */
    function inspection_extend(main, prefix, sub) {
        main.messages = main.messages.concat(sub.messages.map(message => `${prefix}: ${message}`));
    }
    lib_shape.inspection_extend = inspection_extend;
    /**
     * @author fenris
     * @todo check for existing
     */
    function register({ "name": name, "make": make, "inspect": _inspect, "stance": _stance, "show": _show, }) {
        const entry = {
            "name": name,
            "make": make,
            "inspect": _inspect,
            "stance": _stance,
            "show": _show,
        };
        _pool[name] = entry;
    }
    lib_shape.register = register;
    /**
     * @author fenris
     * @todo check for existing
     */
    function define_alias({ "name": name, "target": target, }) {
        const entry = {
            "name": "alias",
            "target": target,
        };
        _aliases[name] = entry;
    }
    lib_shape.define_alias = define_alias;
    /**
     * @author fenris
     * @todo check for existing
     */
    /*
    export function inspect_jstype(
        inspection,
        jstype_expected : string,
        value : any
    ) : void {
        let jstype_actual : string = typeof(value);
        if (jstype_actual === jstype_expected) {
            // all good
        }
        else {
            inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
        }
    }
     */
    /**
     * @author fenris
     */
    function make(raw) {
        const name = raw["name"];
        if (_aliases.hasOwnProperty(name)) {
            const alias = _aliases[name];
            return alias.target;
        }
        else {
            if (_pool.hasOwnProperty(name)) {
                const entry = _pool[name];
                const parameters = entry.make(raw["parameters"] || {}, make);
                return {
                    "name": name,
                    "parameters": parameters,
                };
            }
            else {
                const message = `no shape registered with name '${name}'`;
                throw (new Error(message));
            }
        }
    }
    lib_shape.make = make;
    /**
     * @author fenris
     */
    function inspect(shape, value) {
        if (_pool.hasOwnProperty(shape.name)) {
            const entry = _pool[shape.name];
            return entry.inspect(shape.parameters, value, inspect);
        }
        else {
            const message = `no shape registered with name '${shape.name}'`;
            throw (new Error(message));
        }
    }
    lib_shape.inspect = inspect;
    /**
     * @author fenris
     */
    function check(shape, value) {
        if (_pool.hasOwnProperty(shape.name)) {
            const entry = _pool[shape.name];
            const inspection = inspect(shape, value);
            inspection.messages
                .forEach((message) => { console.warn(message); });
            return (inspection.messages.length === 0);
        }
        else {
            const message = `no shape registered with name '${shape.name}'`;
            throw (new Error(message));
        }
    }
    lib_shape.check = check;
    /**
     * @author fenris
     */
    function stance(shape, bindings) {
        if (_pool.hasOwnProperty(shape.name)) {
            const entry = _pool[shape.name];
            return entry.stance(shape.parameters, bindings, stance);
        }
        else {
            const message = `no shape registered with name '${shape.name}'`;
            throw (new Error(message));
        }
    }
    lib_shape.stance = stance;
    /**
     * @author fenris
     */
    function show(shape) {
        if (_pool.hasOwnProperty(shape.name)) {
            const entry = _pool[shape.name];
            return entry.show(shape.parameters, show);
        }
        else {
            const message = `no shape registered with name '${shape.name}'`;
            throw (new Error(message));
        }
    }
    lib_shape.show = show;
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function variable_make({ "name": name }) {
        if (name == undefined) {
            let message = `mandatory parameter 'name' missing`;
            throw (new Error(message));
        }
        else {
            return {
                "name": name,
            };
        }
    }
    /**
     * @author fenris
     */
    function variable_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        let message = "cannot inspect a value against a type variable";
        console.warn(message + "; will just pass ...");
        // throw (new Error(message));
        return inspection;
    }
    /**
     * @author fenris
     */
    function variable_stance(parameters, bindings, _stance) {
        if (parameters.name in bindings) {
            return bindings[parameters.name];
        }
        else {
            return {
                "name": "variable",
                "parameters": parameters
            };
        }
    }
    /**
     * @author fenris
     */
    function variable_show(parameters, _show) {
        let str;
        // core
        {
            str = ("$" + parameters.name);
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "variable",
        "make": variable_make,
        "inspect": variable_inspect,
        "stance": variable_stance,
        "show": variable_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function function_make({ "soft": soft = false, "shape_input": shape_input, "shape_output": shape_output, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_input === undefined) {
            let message = `mandatory parameter 'shape_input' missing`;
            throw (new Error(message));
        }
        if (shape_output === undefined) {
            let message = `mandatory parameter 'shape_output' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : (x => x));
        }
        return {
            "soft": soft,
            "shape_input": _make(shape_input),
            "shape_output": _make(shape_output),
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function function_stance(parameters, bindings, _stance) {
        return {
            "name": "function",
            "parameters": {
                "soft": parameters.soft,
                "shape_input": _stance(parameters.shape_input, bindings),
                "shape_output": _stance(parameters.shape_output, bindings)
            }
        };
    }
    /**
     * @author fenris
     * @todo closer look not possible?
     */
    function function_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "function";
            if (jstype_actual === jstype_expected) {
                // all good?
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function function_show(parameters, _show) {
        let str;
        /*
        // core
        {
            str = "function";
        }
        // in/out
        {
            str += (
                "<"
                +
                [
                    _show(parameters.shape_input),
                    _show(parameters.shape_output),
                ].join(",")
                +
                ">"
            );
        }
         */
        str = "";
        str += ("(" + _show(parameters.shape_input) + " => " + _show(parameters.shape_output) + ")");
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "function",
        "make": function_make,
        "inspect": function_inspect,
        "stance": function_stance,
        "show": function_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function void_make({ "soft": soft = true, }) {
        return {
            "soft": soft,
        };
    }
    /**
     * @author fenris
     */
    function void_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            // all good
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function void_stance(parameters, bindings, _stance) {
        return {
            "name": "void",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function void_show(parameters, _show) {
        let str;
        // core
        {
            str = "void";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "void",
        "make": void_make,
        "inspect": void_inspect,
        "stance": void_stance,
        "show": void_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function any_make({ "soft": soft = true, "mutable": mutable = true, "defaultvalue": defaultvalue = null, }) {
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function any_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            // all good
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function any_stance(parameters, bindings, _stance) {
        return {
            "name": "any",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function any_show(parameters, _show) {
        let str;
        // core
        {
            str = "any";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "any",
        "make": any_make,
        "inspect": any_inspect,
        "stance": any_stance,
        "show": any_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function boolean_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : false);
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function boolean_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "boolean";
            if (jstype_actual === jstype_expected) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function boolean_stance(parameters, bindings, _stance) {
        return {
            "name": "boolean",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function boolean_show(parameters, _show) {
        let str;
        // core
        {
            str = "boolean";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "boolean",
        "make": boolean_make,
        "inspect": boolean_inspect,
        "stance": boolean_stance,
        "show": boolean_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function int_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, "minimum": minimum = null, "maximum": maximum = null, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : 0);
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
            "minimum": minimum,
            "maximum": maximum,
        };
    }
    /**
     * @author fenris
     */
    function int_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "number";
            if (jstype_actual === jstype_expected) {
                if (!isNaN(parseInt(value))) {
                    if ((parameters.minimum === null) || (value >= parameters.minimum)) {
                        if ((parameters.maximum === null) || (value <= parameters.maximum)) {
                            // all good
                        }
                        else {
                            lib_shape.inspection_add(inspection, `value is beyond maximum`);
                        }
                    }
                    else {
                        lib_shape.inspection_add(inspection, `value is below minimum`);
                    }
                }
                else {
                    lib_shape.inspection_add(inspection, `value is not parsable into a valid int`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function int_stance(parameters, bindings, _stance) {
        return {
            "name": "int",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function int_show(parameters, _show) {
        let str;
        // core
        {
            str = "int";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "int",
        "make": int_make,
        "inspect": int_inspect,
        "stance": int_stance,
        "show": int_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function float_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : 0.0);
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function float_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "number";
            if (jstype_actual === jstype_expected) {
                if (!isNaN(parseFloat(value))) {
                    // all good
                }
                else {
                    lib_shape.inspection_add(inspection, `value is not parsable into a valid float`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function float_stance(parameters, bindings, _stance) {
        return {
            "name": "float",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function float_show(parameters, _show) {
        let str;
        // core
        {
            str = "float";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "float",
        "make": float_make,
        "inspect": float_inspect,
        "stance": float_stance,
        "show": float_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function string_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, "long": long = false, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : "");
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
            "long": long,
        };
    }
    /**
     * @author fenris
     */
    function string_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "string";
            if (jstype_actual === jstype_expected) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function string_stance(parameters, bindings, _stance) {
        return {
            "name": "string",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function string_show(parameters, _show) {
        let str;
        // core
        {
            str = "string";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "string",
        "make": string_make,
        "inspect": string_inspect,
        "stance": string_stance,
        "show": string_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function email_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : "");
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function email_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "string";
            if (jstype_actual === jstype_expected) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function email_stance(parameters, bindings, _stance) {
        return {
            "name": "email",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function email_show(parameters, _show) {
        let str;
        // core
        {
            str = "email";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "email",
        "make": email_make,
        "inspect": email_inspect,
        "stance": email_stance,
        "show": email_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function url_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, "type": type = "link", }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : "");
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
            "type": type,
        };
    }
    /**
     * @author fenris
     */
    function url_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "string";
            if (jstype_actual === jstype_expected) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function url_stance(parameters, bindings, _stance) {
        return {
            "name": "url",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function url_show(parameters, _show) {
        let str;
        // core
        {
            str = "url";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "url",
        "make": url_make,
        "inspect": url_inspect,
        "stance": url_stance,
        "show": url_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function markdown_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, "type": type = "link", }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : "");
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
            "type": type,
        };
    }
    /**
     * @author fenris
     */
    function markdown_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "string";
            if (jstype_actual === jstype_expected) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function markdown_stance(parameters, bindings, _stance) {
        return {
            "name": "markdown",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function markdown_show(parameters, _show) {
        let str;
        // core
        {
            str = "markdown";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "markdown",
        "make": markdown_make,
        "inspect": markdown_inspect,
        "stance": markdown_stance,
        "show": markdown_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function time_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : "");
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function time_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                // all good?
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function time_stance(parameters, bindings, _stance) {
        return {
            "name": "time",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function time_show(parameters, _show) {
        let str;
        // core
        {
            str = "time";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "time",
        "make": time_make,
        "inspect": time_inspect,
        "stance": time_stance,
        "show": time_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function array_make({ "soft": soft = false, "mutable": mutable = true, "shape_element": shape_element, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_element === undefined) {
            let message = `mandatory parameter 'shape_element' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : []);
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "shape_element": _make(shape_element),
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function array_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                if (value instanceof Array) {
                    value.forEach((element, index) => {
                        lib_shape.inspection_extend(inspection, `element #${index.toFixed(0)}`, _inspect(parameters.shape_element, element));
                    });
                }
                else {
                    lib_shape.inspection_add(inspection, `value does not seem to be an array-instance`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function array_stance(parameters, bindings, _stance) {
        return {
            "name": "array",
            "parameters": {
                "soft": parameters.soft,
                "shape_element": _stance(parameters.shape_element, bindings)
            }
        };
    }
    /**
     * @author fenris
     */
    function array_show(parameters, _show) {
        let str;
        // core
        {
            str = "array";
        }
        // shape_element
        {
            str += ("<"
                +
                    _show(parameters.shape_element)
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "array",
        "make": array_make,
        "inspect": array_inspect,
        "stance": array_stance,
        "show": array_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function enumeration_make({ "soft": soft = false, "mutable": mutable = true, "shape_option": shape_option, "options": options, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_option === undefined) {
            let message = `mandatory parameter 'shape_option' missing`;
            throw (new Error(message));
        }
        if (options === undefined) {
            let message = `mandatory parameter 'options' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : options[0].value);
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "shape_option": _make(shape_option),
            "options": options,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function enumeration_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            lib_shape.inspection_extend(inspection, `given value for enumeration`, _inspect(parameters.shape_option, value));
            // TODO: check if corresponding option exists
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function enumeration_stance(parameters, bindings, _stance) {
        return {
            "name": "enumeration",
            "parameters": {
                "soft": parameters.soft,
                "shape_option": _stance(parameters.shape_option, bindings),
                "options": parameters.options,
            }
        };
    }
    /**
     * @author fenris
     */
    function enumeration_show(parameters, _show) {
        let str;
        // core
        {
            str = "enumeration";
        }
        // shape_option
        {
            str += ("<"
                +
                    parameters.options.map(option => String(option)).join(",") + ":" + _show(parameters.shape_option)
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "enumeration",
        "make": enumeration_make,
        "inspect": enumeration_inspect,
        "stance": enumeration_stance,
        "show": enumeration_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function date_make({ "soft": soft = false, "mutable": mutable = true, "defaultvalue": defaultvalue = undefined, }) {
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : (new Date(Date.now())));
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function date_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                if (value instanceof Date) {
                    // all gode
                }
                else {
                    lib_shape.inspection_add(inspection, `value does not seem to be a date-instance`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function date_stance(parameters, bindings, _stance) {
        return {
            "name": "date",
            "parameters": parameters
        };
    }
    /**
     * @author fenris
     */
    function date_show(parameters, _show) {
        let str;
        // core
        {
            str = "date";
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "date",
        "make": date_make,
        "inspect": date_inspect,
        "stance": date_stance,
        "show": date_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function object_make({ "soft": soft = false, "mutable": mutable = true, "fields": fields = [], "defaultvalue": defaultvalue = undefined, }, _make) {
        let fields_ = (fields
            .map((field) => ({ "name": field.name, "shape": _make(field.shape) })));
        if (defaultvalue === undefined) {
            if (soft) {
                defaultvalue = null;
            }
            else {
                defaultvalue = {};
                fields_.forEach(field => {
                    defaultvalue[field.name] = field.shape.parameters["defaultvalue"];
                });
            }
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "fields": fields_,
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function object_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                parameters.fields.forEach(field => {
                    let value_ = value[field.name];
                    lib_shape.inspection_extend(inspection, `field '${field.name}'`, _inspect(field.shape, value_));
                });
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function object_stance(parameters, bindings, _stance) {
        return {
            "name": "object",
            "parameters": {
                "soft": parameters.soft,
                "fields": parameters.fields.map(field => {
                    return {
                        "name": field.name,
                        "shape": _stance(field.shape, bindings)
                    };
                })
            }
        };
    }
    /**
     * @author fenris
     */
    function object_show(parameters, _show) {
        let str;
        // core
        {
            str = "object";
        }
        // fields
        {
            str += ("<"
                +
                    parameters.fields.map(field => (field.name + ":" + _show(field.shape))).join(",")
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "object",
        "make": object_make,
        "inspect": object_inspect,
        "stance": object_stance,
        "show": object_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function map_make({ "soft": soft = false, "mutable": mutable = true, "shape_key": shape_key, "shape_value": shape_value, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_key === undefined) {
            let message = `mandatory parameter 'shape_key' missing`;
            throw (new Error(message));
        }
        if (shape_value === undefined) {
            let message = `mandatory parameter 'shape_value' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : {});
        }
        return {
            "soft": soft,
            "mutable": mutable,
            "shape_key": _make(shape_key),
            "shape_value": _make(shape_value),
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function map_stance(parameters, bindings, _stance) {
        return {
            "name": "map",
            "parameters": {
                "soft": parameters.soft,
                "shape_key": _stance(parameters.shape_key, bindings),
                "shape_value": _stance(parameters.shape_value, bindings)
            }
        };
    }
    /**
     * @author fenris
     * @todo closer look not possible?
     */
    function map_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                Object.keys(value).forEach(key => {
                    lib_shape.inspection_extend(inspection, `key '${key}'`, _inspect(parameters.shape_key, key));
                    let value_ = value[key];
                    lib_shape.inspection_extend(inspection, `value for key '${key}'`, _inspect(parameters.shape_value, value_));
                });
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function map_show(parameters, _show) {
        let str;
        // core
        {
            str = "map";
        }
        // in/out
        {
            str += ("<"
                +
                    [
                        _show(parameters.shape_key),
                        _show(parameters.shape_value),
                    ].join(",")
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "map",
        "make": map_make,
        "inspect": map_inspect,
        "stance": map_stance,
        "show": map_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function maybe_make({ "soft": soft = false, "shape_value": shape_value, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_value === undefined) {
            let message = `mandatory parameter 'shape_value' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : { "kind": "nothing" });
        }
        return {
            "soft": soft,
            "shape_value": _make(shape_value),
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function maybe_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                if ("kind" in value) {
                    // all good?
                }
                else {
                    lib_shape.inspection_add(inspection, `field 'kind' missing`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function maybe_stance(parameters, bindings, _stance) {
        return {
            "name": "maybe",
            "parameters": {
                "soft": parameters.soft,
                "shape_value": _stance(parameters.shape_value, bindings)
            }
        };
    }
    /**
     * @author fenris
     */
    function maybe_show(parameters, _show) {
        let str;
        // core
        {
            str = "maybe";
        }
        // shape_value
        {
            str += ("<"
                +
                    _show(parameters.shape_value)
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "maybe",
        "make": maybe_make,
        "inspect": maybe_inspect,
        "stance": maybe_stance,
        "show": maybe_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     */
    function promise_make({ "soft": soft = false, "shape_result": shape_result, "shape_reason": shape_reason, "defaultvalue": defaultvalue = undefined, }, _make) {
        if (shape_result === undefined) {
            let message = `mandatory parameter 'shape_result' missing`;
            throw (new Error(message));
        }
        if (shape_reason === undefined) {
            let message = `mandatory parameter 'shape_reason' missing`;
            throw (new Error(message));
        }
        if (defaultvalue === undefined) {
            defaultvalue = (soft ? null : Promise.resolve(null));
        }
        return {
            "soft": soft,
            "shape_result": _make(shape_result),
            "shape_reason": _make(shape_reason),
            "defaultvalue": defaultvalue,
        };
    }
    /**
     * @author fenris
     */
    function promise_stance(parameters, bindings, _stance) {
        return {
            "name": "promise",
            "parameters": {
                "soft": parameters.soft,
                "shape_result": _stance(parameters.shape_result, bindings),
                "shape_reason": _stance(parameters.shape_reason, bindings)
            }
        };
    }
    /**
     * @author fenris
     * @todo closer look not possible?
     */
    function promise_inspect(parameters, value, _inspect) {
        let inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            let jstype_actual = typeof (value);
            let jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                if (value instanceof Promise /*<any, any>*/) {
                    // all good?
                }
                else {
                    lib_shape.inspection_add(inspection, `values is not an Promise-instance`);
                }
            }
            else {
                lib_shape.inspection_add(inspection, `expected JS-type '${jstype_expected}' but got '${jstype_actual}'`);
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function promise_show(parameters, _show) {
        let str;
        // core
        {
            str = "promise";
        }
        // in/out
        {
            str += ("<"
                +
                    [
                        _show(parameters.shape_result),
                        _show(parameters.shape_reason),
                    ].join(",")
                +
                    ">");
        }
        // soft
        {
            if (parameters.soft) {
                str = `~${str}`;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "promise",
        "make": promise_make,
        "inspect": promise_inspect,
        "stance": promise_stance,
        "show": promise_show,
    });
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:shape«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_shape;
(function (lib_shape) {
    /**
     * @author fenris
     * @todo use a treemap-function (but first make one :P)
     */
    function adjust_labels(shape, transformator) {
        if (false) {
        }
        else if (shape.name === "enumeration") {
            return {
                "name": "enumeration",
                "parameters": {
                    "soft": shape.parameters["soft"],
                    "shape_option": adjust_labels(shape.parameters["shape_option"], transformator),
                    "options": shape.parameters["options"].map(option => {
                        return {
                            "value": option.value,
                            "label": transformator(option.label),
                        };
                    }),
                    "defaultvalue": shape.parameters["defaultvalue"],
                }
            };
        }
        else if (shape.name === "array") {
            return {
                "name": "array",
                "parameters": {
                    "soft": shape.parameters["soft"],
                    "shape_element": adjust_labels(shape.parameters["shape_element"], transformator),
                    "defaultvalue": shape.parameters["defaultvalue"],
                }
            };
        }
        else if (shape.name === "object") {
            return {
                "name": "object",
                "parameters": {
                    "soft": shape.parameters["soft"],
                    "fields": shape.parameters["fields"].map(field => {
                        return {
                            "name": field.name,
                            "shape": adjust_labels(field.shape, transformator),
                            "label": transformator(field.label),
                        };
                    }),
                    "defaultvalue": shape.parameters["defaultvalue"],
                }
            };
        }
        // lil' hacky …
        else {
            // shape["label"] = ((shape["label"] == null) ? null : transformator(shape["label"]));
            return shape;
        }
    }
    lib_shape.adjust_labels = adjust_labels;
    /**
     * @author fenris
     */
    function register_(id, factory) {
        const message = "not implemented; dummy impl";
        console.warn(message);
    }
    lib_shape.register_ = register_;
    /**
     * @author fenris
     */
    function retrieve_(id) {
        const message = "not implemented; returning dummy";
        console.warn(message);
        return { "name": "any" };
    }
    lib_shape.retrieve_ = retrieve_;
})(lib_shape || (lib_shape = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @author fenris
     */
    function domain_make(_a, _make) {
        var _b = _a["soft"], soft = _b === void 0 ? false : _b, kind = _a["kind"];
        return {
            "soft": soft,
            "kind": kind
        };
    }
    /**
     * @author fenris
     */
    function domain_inspect(parameters, value, _inspect) {
        var inspection = lib_shape.inspection_create();
        if (value == undefined) {
            if (parameters.soft) {
                // all good
            }
            else {
                lib_shape.inspection_add(inspection, "null is not allowed");
            }
        }
        else {
            var jstype_actual = typeof (value);
            var jstype_expected = "object";
            if (jstype_actual === jstype_expected) {
                if ("domain" in value) {
                    var domain_actual = value["domain"]["kind"];
                    var domain_expected = parameters.kind;
                    if (domain_actual == domain_expected) {
                        // all good?
                    }
                    else {
                        lib_shape.inspection_add(inspection, "expected domain-kind '" + domain_expected + "' but got '" + domain_actual + "'");
                    }
                }
                else {
                    lib_shape.inspection_add(inspection, "field 'domain' missing");
                }
            }
            else {
                lib_shape.inspection_add(inspection, "expected JS-type '" + jstype_expected + "' but got '" + jstype_actual + "'");
            }
        }
        return inspection;
    }
    /**
     * @author fenris
     */
    function domain_stance(parameters, bindings, _stance) {
        return {
            "name": "domain",
            "parameters": {
                "soft": parameters.soft,
                "kind": parameters.kind
            }
        };
    }
    /**
     * @author fenris
     */
    function domain_show(parameters, _show) {
        var str;
        // core
        {
            str = ("#" + parameters.kind);
        }
        /*
        // parameters
        {
            str += (":" + JSON.stringify(parameters.parameters))
        }
         */
        // soft
        {
            if (parameters.soft) {
                str = "~" + str;
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    lib_shape.register({
        "name": "domain",
        "make": domain_make,
        "inspect": domain_inspect,
        "stance": domain_stance,
        "show": domain_show
    });
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @author fenris
     */
    lib_trait._verbosity = 1;
    /**
     * @author fenris
     */
    lib_trait._logprefix = "[lib_trait] ";
    /**
     * @desc holds all defined traits
     * @author fenris
     */
    var _pool = {};
    /**
     * @author fenris
     */
    var _typechecker = function (value, shape, logger) {
        var messages = lib_shape.inspect(shape, value).messages;
        messages.forEach(logger);
        return (messages.length == 0);
    };
    /**
     * @author fenris
     */
    function log(_a) {
        var message = _a["message"], _b = _a["kind"], kind = _b === void 0 ? "log" : _b, _c = _a["level"], level = _c === void 0 ? 0 : _c;
        if (level <= lib_trait._verbosity) {
            var message_ = "" + lib_trait._logprefix + message;
            switch (kind) {
                default:
                case "log": {
                    console.log(message_);
                    break;
                }
                case "information":
                case "info": {
                    console.info(message_);
                    break;
                }
                case "warning":
                case "warn": {
                    console.warn(message_);
                    break;
                }
                case "error":
                case "err": {
                    console.error(message_);
                    break;
                }
            }
        }
    }
    /**
     * @author fenris
     */
    function set_typechecker(typechecker) {
        _typechecker = typechecker;
    }
    lib_trait.set_typechecker = set_typechecker;
    /**
     * @author fenris
     */
    function domain_instance(domain, value) {
        return { "domain": domain, "value": value };
    }
    lib_trait.domain_instance = domain_instance;
    /**
     * @desc adds a trait
     * @author fenris
     */
    function define(trait_id, variable_conditions, facets_raw) {
        if (trait_id in _pool) {
            var message = "trait '" + trait_id + "' already registered";
            throw (new Error(message));
        }
        else {
            var trait_1 = {
                "variables": {},
                "facets": {},
                "attendants": {}
            };
            Object.keys(variable_conditions).forEach(function (variable_name) {
                var variable = {
                    "conditions": variable_conditions[variable_name],
                    "bindings": {}
                };
                trait_1.variables[variable_name] = variable;
            });
            Object.keys(facets_raw).forEach(function (facet_name) {
                var facet_raw = facets_raw[facet_name];
                var facet = {
                    "shape": lib_shape.make(facet_raw.shape || { "name": "any" }),
                    "description": facet_raw.description,
                    "implementation": facet_raw.implementation,
                    "handlers": {}
                };
                trait_1.facets[facet_name] = facet;
            });
            _pool[trait_id] = trait_1;
        }
    }
    lib_trait.define = define;
    /**
     * @desc adhoc binding
     * @author fenris
     */
    function attend(trait_id, domain_kind, bindings, handlers, condition) {
        if (condition === void 0) { condition = null; }
        var strict_binding = true;
        var strict_handling = true;
        if (trait_id in _pool) {
            var trait_2 = _pool[trait_id];
            // assignments
            {
                // variables
                {
                    Object.keys(bindings)
                        .forEach(function (variable_name) {
                        if (variable_name in trait_2.variables) {
                            var variable = trait_2.variables[variable_name];
                            if (!(domain_kind in variable.bindings)) {
                                variable.bindings[domain_kind] = lib_shape.make(bindings[variable_name]);
                            }
                            else {
                                var message = "";
                                message += "variable '" + variable_name + "'";
                                message += " already bound for domain '" + domain_kind + "'";
                                message += " in trait '" + trait_id + "'";
                                throw (new Error(message));
                            }
                        }
                        else {
                            var message = "";
                            message += "no variable '" + variable_name + "'";
                            message += " to bind in trait '" + trait_id + "'";
                            log({ "message": message, "kind": "warning" });
                            // throw (new Error(message));
                        }
                    });
                }
                // facets
                {
                    Object.keys(handlers)
                        .forEach(function (facet_name) {
                        if (facet_name in trait_2.facets) {
                            var facet = trait_2.facets[facet_name];
                            var intrinsic = (facet.implementation != undefined);
                            if (intrinsic) {
                                var message = "";
                                message = "shadowing intrinsic facet '" + facet_name + "'";
                                console.warn(message);
                            }
                            else {
                                // do nothing
                            }
                            if (!(domain_kind in facet.handlers)) {
                                facet.handlers[domain_kind] = handlers[facet_name];
                            }
                            else {
                                var message = "";
                                message += "facet '" + facet_name + "'";
                                message += " already implemented in domain '" + domain_kind + "'";
                                message += " at trait '" + trait_id + "'";
                                throw (new Error(message));
                            }
                        }
                        else {
                            var message = "";
                            message += "no facet '" + facet_name + "'";
                            message += " to implement at trait '" + trait_id + "'";
                            log({ "kind": "warning", "message": message });
                            // throw (new Error(message));
                        }
                    });
                }
                // attendants
                {
                    trait_2.attendants[domain_kind] = {
                        "condition": condition
                    };
                }
            }
            // checks
            {
                var messages_1 = [];
                // variables
                {
                    if (strict_binding) {
                        {
                            var variable_names_given_1 = Object.keys(bindings);
                            var variable_names_present = Object.keys(trait_2.variables);
                            var variable_names_missing = variable_names_present.filter(function (variable_name) { return !variable_names_given_1.some(function (variable_name_) { return (variable_name == variable_name_); }); });
                            variable_names_missing.forEach(function (variable_name) {
                                var message = "binding missing for variable '" + variable_name + "'";
                                messages_1.push(message);
                            });
                        }
                    }
                    else {
                        // do nothing
                    }
                }
                // facets
                {
                    if (strict_handling) {
                        {
                            var facet_names_given_1 = Object.keys(handlers);
                            var facet_names_needed = Object.keys(trait_2.facets).filter(function (facet_name) { return (trait_2.facets[facet_name].implementation == undefined); });
                            var facet_names_missing = (facet_names_needed
                                .filter(function (facet_name) { return (!facet_names_given_1.some(function (facet_name_) { return (facet_name == facet_name_); })); }));
                            facet_names_missing
                                .forEach(function (facet_name) {
                                var message = "implementation missing for the facet '" + facet_name + "'";
                                messages_1.push(message);
                            });
                        }
                    }
                    else {
                        // do nothing
                    }
                }
                if (messages_1.length > 0) {
                    var message = "";
                    message += "assignment of domain '" + domain_kind + "'";
                    message += " to trait '" + trait_id + "'";
                    message += " incomplete: " + messages_1.join(", ");
                    throw (new Error(message));
                }
            }
        }
        else {
            var message = "no trait '" + trait_id + "'";
            throw (new Error(message));
        }
    }
    lib_trait.attend = attend;
    /**
     * @desc calls a facet from a trait according to a given domain
     * @author fenris
     */
    function call(trait_id, facet_name, domain, check) {
        if (check === void 0) { check = true; }
        if (trait_id in _pool) {
            var trait_3 = _pool[trait_id];
            if (facet_name in trait_3.facets) {
                var facet = trait_3.facets[facet_name];
                var intrinsic = (facet.implementation != undefined);
                var result = void 0;
                if (intrinsic) {
                    result = facet.implementation(function (facet_name_) { return call(trait_id, facet_name_, domain, check); });
                }
                else {
                    if (domain.kind in facet.handlers) {
                        var show_shape = (function (shape) { return lib_shape.show(shape); });
                        var handler = facet.handlers[domain.kind];
                        var bindings_1 = {};
                        Object.keys(trait_3.variables).forEach(function (variable_name) {
                            bindings_1[variable_name] = trait_3.variables[variable_name].bindings[domain.kind];
                        });
                        result = handler(domain.parameters);
                        if (check
                            &&
                                (_typechecker != null)
                            &&
                                (facet.shape != undefined)) {
                            var shape = lib_shape.stance(facet.shape, bindings_1);
                            // console.info("expected shape of result: " + lib_shape.show(shape)); console.info("result: ", result);
                            var valid = _typechecker(result, shape, function (message) { return log({ "kind": "warning", "message": "[typechecker] [result] " + message }); });
                            if (!valid) {
                                var message = "";
                                message += "result '" + instance_show(result) + "'";
                                message += " doesn't match the expected type '" + show_shape(shape) + "'";
                                message += " at trait '" + trait_id + "'";
                                message += " for facet '" + facet_name + "'";
                                message += " in domain '" + domain.kind + "'";
                                log({ "kind": "warning", "message": message });
                            }
                            {
                                var condition = trait_3.attendants[domain.kind].condition;
                                if (condition != null) {
                                    var attends = function (trait_id_, domain_) {
                                        return ((trait_id_ in _pool) && (domain_.kind in _pool[trait_id_].attendants));
                                    };
                                    if (condition(attends)(domain.parameters)) {
                                        // do nothing
                                    }
                                    else {
                                        var message = "";
                                        message += "condition not fulfilled";
                                        message += " at trait '" + trait_id + "'";
                                        message += " for facet '" + facet_name + "'";
                                        message += " in domain '" + domain.kind + "'";
                                        log({ "kind": "warning", "message": message });
                                    }
                                }
                                else {
                                    // do nothing
                                }
                            }
                        }
                    }
                    else {
                        var message = "";
                        message += "implementation missing";
                        message += " at trait '" + trait_id + "'";
                        message += " for facet '" + facet_name + "'";
                        message += " in domain '" + domain.kind + "'";
                        throw (new Error(message));
                    }
                }
                return result;
            }
            else {
                var message = "no facet '" + facet_name + "' in trait '" + trait_id + "'";
                throw (new Error(message));
            }
        }
        else {
            var message = "no trait '" + trait_id + "'";
            throw (new Error(message));
        }
    }
    lib_trait.call = call;
    /**
     * @author fenris
     */
    function explain(trait_id) {
        if (trait_id in _pool) {
            var trait_4 = _pool[trait_id];
            var str_1 = "";
            // head
            {
                str_1 += "<<" + trait_id + ">>";
                str_1 += (" "
                    +
                        "("
                    +
                        (Object.keys(trait_4.variables)
                            .map(function (variable_name) {
                            var shape = lib_shape.make({
                                "name": "variable",
                                "parameters": {
                                    "name": variable_name
                                }
                            });
                            return lib_shape.show(shape);
                        })
                            .join(","))
                    +
                        ")");
                str_1 += "\n";
            }
            // facets
            {
                Object.keys(trait_4.facets)
                    .forEach(function (facet_name) {
                    var facet = trait_4.facets[facet_name];
                    // str += "\t";
                    str_1 += "* ";
                    str_1 += ((facet.implementation != undefined) ? ("[" + facet_name + "]") : facet_name);
                    str_1 += (" : " + lib_shape.show(facet.shape));
                    if (facet.description !== undefined) {
                        str_1 += (" ~ " + "" + facet.description + "");
                    }
                    str_1 += "\n";
                });
            }
            return str_1;
        }
        else {
            var message = "no trait '" + trait_id + "'";
            throw (new Error(message));
        }
    }
    lib_trait.explain = explain;
    /**
     * @author fenris
     */
    function explain_all() {
        return Object.keys(_pool).map(function (trait_id) { return explain(trait_id); }).join("\n");
    }
    lib_trait.explain_all = explain_all;
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @desc the ability to check for equality with another element of the same domain
     * @author fenris
     */
    function define_collatable() {
        lib_trait.define("collatable", {
            "value": []
        }, {
            "collate": {
                "shape": {
                    "name": "function",
                    "parameters": {
                        "shape_input": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        },
                        "shape_output": {
                            "name": "function",
                            "parameters": {
                                "shape_input": {
                                    "name": "variable",
                                    "parameters": {
                                        "name": "value"
                                    }
                                },
                                "shape_output": {
                                    "name": "boolean"
                                }
                            }
                        }
                    }
                }
            }
        });
        lib_trait.attend("collatable", "crude", {
            "value": {
                "name": "any"
            }
        }, {
            "collate": function () { return function (instance) { return function (other) {
                if (typeof (instance) === "object") {
                    if (instance == null) {
                        return (other == null);
                    }
                    else {
                        if ("_collate" in instance) {
                            return instance["_collate"](other);
                        }
                        else {
                            var message = ("[collate]" + " " + "object has no such method");
                            throw (new Error(message));
                        }
                    }
                }
                else {
                    if (lib_trait._verbosity >= 1) {
                        var message = ("[collate]" + " " + "primitive value; using default implementation");
                        console.warn(message);
                    }
                    return (instance === other);
                }
            }; }; }
        });
    }
    lib_trait.define_collatable = define_collatable;
    /**
     * @author fenris
     */
    function _collate(instance, other, domain) {
        if (domain === void 0) { domain = { "kind": "crude" }; }
        return lib_trait.call("collatable", "collate", domain)(instance)(other);
    }
    lib_trait._collate = _collate;
    define_collatable();
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @desc the ability to compare with another element of the same domain for determining if the first is "smaller than or equal to" the latter
     * @author fenris
     */
    function define_comparable() {
        lib_trait.define("comparable", {
            "value": []
        }, {
            "compare": {
                "shape": {
                    "name": "function",
                    "parameters": {
                        "shape_input": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        },
                        "shape_output": {
                            "name": "function",
                            "parameters": {
                                "shape_input": {
                                    "name": "variable",
                                    "parameters": {
                                        "name": "value"
                                    }
                                },
                                "shape_output": {
                                    "name": "boolean"
                                }
                            }
                        }
                    }
                }
            }
        });
        lib_trait.attend("comparable", "crude", {
            "value": {
                "name": "any"
            }
        }, {
            "compare": function () { return function (instance) { return function (other) {
                if (typeof (instance) === "object") {
                    if ("_compare" in instance) {
                        return instance["_compare"](other);
                    }
                    else {
                        throw (new Error("[compare]" + " " + "object has no such method"));
                    }
                }
                else {
                    if (lib_trait._verbosity >= 1) {
                        console.warn("[compare]" + " " + "primitive value; using default implementation");
                    }
                    return (instance <= other);
                }
            }; }; }
        });
    }
    lib_trait.define_comparable = define_comparable;
    /**
     * @author fenris
     */
    function _compare(instance, other, domain) {
        if (domain === void 0) { domain = { "kind": "crude" }; }
        return lib_trait.call("comparable", "compare", domain)(instance)(other);
    }
    lib_trait._compare = _compare;
    define_comparable();
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @desc the ability to create an exact copy
     * @author fenris
     */
    function define_clonable() {
        lib_trait.define("clonable", {
            "value": []
        }, {
            "clone": {
                "shape": {
                    "name": "function",
                    "parameters": {
                        "shape_input": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        },
                        "shape_output": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        }
                    }
                }
            }
        });
        lib_trait.attend("clonable", "crude", {
            "value": {
                "name": "any"
            }
        }, {
            "clone": function () { return function (instance) {
                if (typeof (instance) === "object") {
                    if ("_clone" in instance) {
                        return instance["_clone"]();
                    }
                    else {
                        throw (new Error("[clone]" + " " + "object has no such method"));
                    }
                }
                else {
                    if (lib_trait._verbosity >= 1) {
                        console.warn("[clone]" + " " + "primitive value; using default implementation");
                    }
                    return instance;
                }
            }; }
        });
    }
    lib_trait.define_clonable = define_clonable;
    /**
     * @author fenris
     */
    function _clone(instance, domain) {
        if (domain === void 0) { domain = { "kind": "crude" }; }
        return lib_trait.call("clonable", "clone", domain)(instance);
    }
    lib_trait._clone = _clone;
    define_clonable();
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @desc the ability to generate a string out of the element, which identifies it to a high degree
     * @author fenris
     */
    function define_hashable() {
        lib_trait.define("hashable", {
            "value": []
        }, {
            "hash": {
                "shape": {
                    "name": "function",
                    "parameters": {
                        "shape_input": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        },
                        "shape_output": {
                            "name": "string"
                        }
                    }
                }
            }
        });
        lib_trait.attend("hashable", "crude", {
            "value": {
                "name": "any"
            }
        }, {
            "hash": function () { return function (thing) {
                if (typeof (thing) === "object") {
                    if ("_hash" in thing) {
                        return thing["_hash"]();
                    }
                    else {
                        var message = ("[hash]" + " " + "object has no such method");
                        throw (new Error(message));
                    }
                }
                else {
                    if (lib_trait._verbosity >= 1) {
                        var message = ("[hash]" + " " + "primitive value; using default implementation");
                        console.warn(message);
                    }
                    return String(thing);
                }
            }; }
        });
    }
    lib_trait.define_hashable = define_hashable;
    /**
     * @author fenris
     */
    function _hash(instance, domain) {
        if (domain === void 0) { domain = { "kind": "crude" }; }
        return lib_trait.call("hashable", "hash", domain)(instance);
    }
    lib_trait._hash = _hash;
    define_hashable();
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:trait«.

Copyright 2016-2018 greenscale <info@greenscale.de>

»bacterio-plankton:trait« 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:trait« is distributed in the hope that it will be callful,
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:trait«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_trait;
(function (lib_trait) {
    /**
     * @desc the ability to map the element to a textual representation (most likely not injective)
     * @author fenris
     */
    function define_showable() {
        lib_trait.define("showable", {
            "value": []
        }, {
            "show": {
                "shape": {
                    "name": "function",
                    "parameters": {
                        "shape_input": {
                            "name": "variable",
                            "parameters": {
                                "name": "value"
                            }
                        },
                        "shape_output": {
                            "name": "string",
                            "parameters": {
                                "soft": false
                            }
                        }
                    }
                }
            }
        });
        lib_trait.attend("showable", "crude", {
            "value": {
                "name": "any"
            }
        }, {
            "show": function () { return function (instance) {
                if (typeof (instance) === "object") {
                    if (instance == null) {
                        return "NULL";
                    }
                    else {
                        if ("_show" in instance) {
                            return instance["_show"]();
                        }
                        else {
                            // throw (new Error("[show]" + " " + "object has no such method"));
                            return JSON.stringify(instance);
                        }
                    }
                }
                else {
                    if (lib_trait._verbosity >= 1) {
                        var message = ("[show]" + " " + "primitive value; using default implementation");
                        // console.warn(message);
                    }
                    return String(instance);
                }
            }; }
        });
    }
    lib_trait.define_showable = define_showable;
    /**
     * @author fenris
     */
    function _show(instance, domain) {
        if (domain === void 0) { domain = { "kind": "crude" }; }
        return lib_trait.call("showable", "show", domain)(instance);
    }
    lib_trait._show = _show;
    define_showable();
})(lib_trait || (lib_trait = {}));
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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) {
    var 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, caseSense) {
    if (rtl === void 0) { rtl = false; }
    if (caseSense === void 0) { caseSense = true; }
    if (str === "") {
        return str;
    }
    else {
        var marks = {
            ".": true,
            "?": true,
            "!": true
        };
        var default_mark = ".";
        var 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, delimiter, default_string, sloppy) {
    if (fabric === void 0) { fabric = function (object, key) { return object[key]; }; }
    if (delimiter === void 0) { delimiter = "%"; }
    if (default_string === void 0) { default_string = null; }
    function get_tags(str) {
        var 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) {
        var 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) {
            var 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) {
    if (_fabrics === void 0) { _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 () {
    var _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 () {
    var 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) {
        var _template = "";
        _template += "--%boundrary%\n";
        _template += "Content-Type: %contenttype%\n\n%body%\n\n";
        //_template += "--%boundrary%--\n\n";
        var 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) {
        var _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";
        var 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) {
            var 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) {
        var ret = "";
        var 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-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_string;
(function (lib_string) {
    /**
     * @author fenris
     */
    var hexdigits = 4;
    /**
     * @author fenris
     */
    var index_max = (1 << (4 * hexdigits));
    /**
     * @author fenris
     */
    var index_is = 0;
    /**
     * @author neuc,frac
     */
    function empty(str) {
        return (str.trim() === "");
    }
    lib_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) {
        if (prefix === void 0) { prefix = "string_"; }
        if (index_is > index_max) {
            throw (new Error("[string_generate] out of valid indices"));
        }
        else {
            return lib_string.sprintf(prefix + "%0" + hexdigits.toString() + "X", [index_is++]);
        }
    }
    lib_string.generate = generate;
    /**
     * @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 (separator === void 0) { separator = " "; }
        if (chain.length == 0) {
            return [];
        }
        else {
            return chain.split(separator);
        }
    }
    lib_string.split = split;
    /**
     * @author neu3no
     */
    function explode(str, needle, max) {
        var temp = str.split(needle);
        var right = temp.splice(max - 1);
        temp.push(right.join(needle));
        return temp;
    }
    lib_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)));
        var result = "";
        for (var n = 0; n < count; n += 1) {
            result += word;
        }
        return result;
    }
    lib_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) {
        if (symbol === void 0) { symbol = " "; }
        if (mode === void 0) { 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
                var 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: {
                var message = ("unhandled mode '" + mode + "'");
                console.warn(message);
                return word;
                break;
            }
        }
    }
    lib_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);
    }
    lib_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));
    }
    lib_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));
    }
    lib_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) {
        var cnt = 0;
        var 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);
    }
    lib_string.count_occourrences = count_occourrences;
    /**
     * @desc replaces occurences of "${name}" in a string by the corresponding values of an argument object
     * @author fenris
     */
    function coin(str, args) {
        Object.keys(args).forEach(function (key) {
            // old syntax
            {
                var value = args[key];
                var regexp_argument = new RegExp("\\${" + key + "}");
                str = str.replace(regexp_argument, value);
            }
            // new syntax
            {
                var value = args[key];
                var regexp_argument = new RegExp("{{" + key + "}}");
                str = str.replace(regexp_argument, value);
            }
        });
        return str;
    }
    lib_string.coin = coin;
    /**
     * @author fenris
     */
    lib_string.stance = coin;
    /**
     * @author fenris
     */
    function url_encode(_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["protocol"], protocol = _c === void 0 ? null : _c, _d = _b["host"], host = _d === void 0 ? null : _d, _e = _b["port"], port = _e === void 0 ? null : _e, _f = _b["path"], path = _f === void 0 ? null : _f, _g = _b["arguments"], arguments_ = _g === void 0 ? null : _g;
        var url = "";
        // protocol
        {
            if (protocol != null) {
                url = protocol + ":" + url;
            }
        }
        // host
        {
            if (host != null) {
                url = url + "//" + host;
            }
        }
        // port
        {
            if (port != null) {
                url = url + ":" + port.toString();
            }
        }
        // path
        {
            if (path != null) {
                var path_ = encodeURI(path);
                url = "" + url + path_;
            }
        }
        // arguments
        {
            if (arguments_ != null) {
                var suffix = Object.keys(arguments_).map(function (key) { return key + "=" + arguments_[key]; }).join("&");
                var suffix_ = encodeURI(suffix);
                url = url + "?" + suffix_;
            }
        }
        return url;
    }
    lib_string.url_encode = url_encode;
    /**
     * @author fenris
     */
    lib_string.make_url = url_encode;
    /**
     * @author fenris
     * @todo arguments
     */
    function url_decode(url) {
        var regexp = new RegExp("^([^:]*)://([^:]*):([^/]*)/(.*)$");
        var matching = regexp.exec(url);
        if (matching === null) {
            return null;
        }
        else {
            var components = {
                "protocol": matching[1],
                "host": matching[2],
                "port": parseInt(matching[3]),
                "path": ("/" + matching[4])
            };
            return components;
        }
    }
    lib_string.url_decode = url_decode;
    /**
     * @author fenris
     */
    function cut(str, length, delimiter) {
        if (delimiter === void 0) { delimiter = "…"; }
        if (str.length <= length) {
            return str;
        }
        else {
            return (str.slice(0, length - delimiter.length) + delimiter);
        }
    }
    lib_string.cut = cut;
})(lib_string || (lib_string = {}));
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_string;
(function (lib_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}
     */
    lib_string.sprintf = function (input, args, original) {
        if (args === void 0) { args = []; }
        if (original === void 0) { 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)
                + lib_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(lib_string.sprintf(format, args));
    }
    lib_string.printf = printf;
})(lib_string || (lib_string = {}));
var sprintf = lib_string.sprintf;
var printf = lib_string.printf;
/*
This file is part of »bacterio-plankton:string«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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) {
            if (next === void 0) { 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;
})();
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/*
This file is part of »bacterio-plankton:xml«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:xml« 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:xml« 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:xml«. If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @author fenris
 */
var lib_xml;
(function (lib_xml) {
    /**
     * @author fenris
     */
    function string_repeat(symbol, count) {
        return ((count <= 0) ? "" : (string_repeat(symbol, count - 1) + symbol));
    }
    /**
     * @author fenris
     */
    var class_node = /** @class */ (function () {
        function class_node() {
        }
        return class_node;
    }());
    lib_xml.class_node = class_node;
    /**
     * @author fenris
     */
    var class_node_text = /** @class */ (function (_super) {
        __extends(class_node_text, _super);
        /**
         * @author fenris
         */
        function class_node_text(content) {
            var _this = _super.call(this) || this;
            _this.content = content;
            return _this;
        }
        /**
         * @author fenris
         */
        class_node_text.prototype.compile = function (depth) {
            if (depth === void 0) { depth = 0; }
            return (string_repeat("\t", depth) + this.content + "\n");
        };
        return class_node_text;
    }(class_node));
    lib_xml.class_node_text = class_node_text;
    /**
     * @author fenris
     */
    var class_node_comment = /** @class */ (function (_super) {
        __extends(class_node_comment, _super);
        /**
         * @author fenris
         */
        function class_node_comment(content) {
            var _this = _super.call(this) || this;
            _this.content = content;
            return _this;
        }
        /**
         * @author fenris
         */
        class_node_comment.prototype.compile = function (depth) {
            if (depth === void 0) { depth = 0; }
            return (string_repeat("\t", depth) + "<!-- " + this.content + " -->" + "\n");
        };
        return class_node_comment;
    }(class_node));
    lib_xml.class_node_comment = class_node_comment;
    /**
     * @author fenris
     */
    var class_node_complex = /** @class */ (function (_super) {
        __extends(class_node_complex, _super);
        /**
         * @author fenris
         */
        function class_node_complex(name, attributes, children) {
            if (attributes === void 0) { attributes = {}; }
            if (children === void 0) { children = []; }
            var _this = _super.call(this) || this;
            _this.name = name;
            _this.attributes = attributes;
            _this.children = children;
            return _this;
        }
        /**
         * @author fenris
         */
        class_node_complex.prototype.compile = function (depth) {
            var _this = this;
            if (depth === void 0) { depth = 0; }
            var output = "";
            var attributes = (Object.keys(this.attributes)
                .filter(function (key) { return (_this.attributes[key] !== null); })
                .map(function (key) { return (" " + key + "=" + ("\"" + _this.attributes[key] + "\"")); })
                .join(""));
            output += (string_repeat("\t", depth) + "<" + this.name + attributes + ">" + "\n");
            this.children.forEach(function (child) { return (output += child.compile(depth + 1)); });
            output += (string_repeat("\t", depth) + "</" + this.name + ">" + "\n");
            return output;
        };
        return class_node_complex;
    }(class_node));
    lib_xml.class_node_complex = class_node_complex;
})(lib_xml || (lib_xml = {}));
/*
This file is part of »bacterio-plankton:object«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_object;
(function (lib_object) {
    /**
     * @author fenris
     */
    function fetch(object, fieldname, fallback, escalation) {
        if (fallback === void 0) { fallback = null; }
        if (escalation === void 0) { escalation = 1; }
        if ((fieldname in object) && (object[fieldname] !== undefined)) {
            return object[fieldname];
        }
        else {
            switch (escalation) {
                case 0: {
                    return fallback;
                    break;
                }
                case 1: {
                    var message = ("field '" + fieldname + "' not in structure");
                    message += ("; using fallback value '" + String(fallback) + "'");
                    // console.warn(message);
                    return fallback;
                    break;
                }
                case 2: {
                    var message = ("field '" + fieldname + "' not in structure");
                    throw (new Error(message));
                    break;
                }
                default: {
                    throw (new Error("invalid escalation level " + escalation));
                    break;
                }
            }
        }
    }
    lib_object.fetch = fetch;
    /**
     * @author fenris
     */
    function map(object_from, transformator) {
        var object_to = {};
        Object.keys(object_from).forEach(function (key) { return (object_to[key] = transformator(object_from[key], key)); });
        return object_to;
    }
    lib_object.map = map;
    /**
     * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück
     * @author fenris
     */
    function filter(object_from, predicate) {
        var object_to = {};
        Object.keys(object_from).forEach(function (key) {
            var value = object_from[key];
            if (predicate(value, key)) {
                object_to[key] = value;
            }
        });
        return object_to;
    }
    lib_object.filter = filter;
    /**
     * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um
     * @author fenris
     */
    function from_array(array) {
        var object = {};
        array.forEach(function (entry) { return (object[entry.key] = entry.value); });
        return object;
    }
    lib_object.from_array = from_array;
    /**
     * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um
     * @author fenris
     */
    function to_array(object) {
        var array = [];
        Object.keys(object).forEach(function (key) { return array.push({ "key": key, "value": object[key] }); });
        return array;
    }
    lib_object.to_array = to_array;
    /**
     * @desc gibt eine Liste von Schlüsseln eines Objekts zurück
     * @author fenris
     */
    function keys(object) {
        return Object.keys(object);
    }
    lib_object.keys = keys;
    /**
     * @desc gibt eine Liste von Werten eines Objekts zurück
     * @author fenris
     */
    function values(object) {
        return to_array(object).map(function (entry) { return entry.value; });
    }
    lib_object.values = values;
    /**
     * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus
     * @author fenris
     */
    function path_read(object, path, fallback, escalation) {
        if (fallback === void 0) { fallback = null; }
        if (escalation === void 0) { escalation = 1; }
        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 = object_fetch(position_1, step, null, 0);
                return (position_1 != null);
            });
            if (reachable) {
                return object_fetch(position_1, steps[steps.length - 1], fallback, escalation);
            }
            else {
                return object_fetch({}, "_dummy_", fallback, escalation);
            }
        }
    }
    lib_object.path_read = path_read;
    /**
     * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt
     * @author fenris
     */
    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_ = object_fetch(position_2, step, null, 0);
                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 {
                var message = ("path '" + path + "' does not exist and may not be constructed");
                throw (new Error(message));
            }
        }
    }
    lib_object.path_write = path_write;
    /**
     * @desc prüft ob ein Objekt einem bestimmten Muster entspricht
     * @param {Object} object das zu prüfende Objekt
     * @param {Object} pattern das einzuhaltende Muster
     * @param {Function} connlate eine Funktion zum Feststellen der Gleichheit von Einzelwerten
     * @author fenris
     */
    function matches(object, pattern, collate) {
        if (collate === void 0) { collate = instance_collate; }
        return Object.keys(pattern).every(function (key) { return collate(pattern[key], object[key]); });
    }
    lib_object.matches = matches;
    /**
     * @desc erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt
     * @param {string} [separator] welches Zeichen als Trenner zwischen zwei Pfad-Schritten verwendet werden soll
     * @author fenris
     */
    function flatten(value, separator, key_for_element) {
        if (separator === void 0) { separator = "."; }
        if (key_for_element === void 0) { key_for_element = (function (index) { return ("element_" + index.toFixed(0)); }); }
        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_1 = flatten(value_);
                    Object.keys(result_1)
                        .forEach(function (key__) {
                        var value__ = result_1[key__];
                        var key_new = (key_ + separator + key__);
                        result[key_new] = value__;
                    });
                }
            }
        };
        if ((value === null) || (value === undefined)) {
            return null;
        }
        else {
            var result_2 = {};
            if (typeof (value) != "object") {
                result_2["value"] = value;
            }
            else {
                if (value instanceof Array) {
                    var array = (value);
                    array
                        .forEach(function (element, index) {
                        integrate(result_2, key_for_element(index), element);
                    });
                }
                else {
                    var object_1 = (value);
                    Object.keys(object_1)
                        .forEach(function (key) {
                        integrate(result_2, key, object_1[key]);
                    });
                }
            }
            return result_2;
        }
    }
    lib_object.flatten = flatten;
    /**
     * @author fenris
     */
    function clash(x, y, _a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["overwrite"], overwrite = _c === void 0 ? true : _c, _d = _b["hooks"], _e = (_d === void 0 ? {} : _d)["existing"], hook_existing = _e === void 0 ? null : _e;
        if (hook_existing == null) {
            (function (key, value_old, value_new) { return console.warn("field " + key + " already defined"); });
        }
        var z = {};
        Object.keys(x).forEach(function (key) {
            z[key] = x[key];
        });
        Object.keys(y).forEach(function (key) {
            if (key in z) {
                if (hook_existing != null) {
                    hook_existing(key, z[key], y[key]);
                }
                if (overwrite) {
                    z[key] = y[key];
                }
            }
            else {
                z[key] = y[key];
            }
        });
        return z;
    }
    lib_object.clash = clash;
    /**
     * @author fenris
     */
    function patch(core, mantle, deep, path) {
        if (deep === void 0) { deep = true; }
        if (path === void 0) { path = null; }
        if (mantle == null) {
            console.warn("mantle is null; core was", core);
        }
        else {
            Object.keys(mantle).forEach(function (key) {
                var path_ = ((path == null) ? key : path + "." + key);
                var value_mantle = mantle[key];
                if (!(key in core)) {
                    if ((typeof (value_mantle) == "object") && (value_mantle != null) && 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, 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) && deep) {
                            patch(core[key], value_mantle, deep, path_);
                        }
                        else {
                            core[key] = value_mantle;
                        }
                    }
                    else {
                        if ((value_core != null) && (value_mantle != null)) {
                            var message = "objects have different shapes at path '" + path_ + "'; core has type '" + typeof (value_core) + "' and mantle has type '" + typeof (value_mantle) + "'";
                            console.warn(message);
                        }
                        core[key] = value_mantle;
                        // throw (new Error(message));
                    }
                }
            });
        }
    }
    lib_object.patch = patch;
    /**
     * @author fenris
     */
    function patched(core, mantle, deep) {
        if (deep === void 0) { deep = undefined; }
        var result = {};
        patch(result, core, deep);
        patch(result, mantle, deep);
        return result;
    }
    lib_object.patched = patched;
    /**
     * @author fenris
     */
    function attached(object, key, value) {
        var mantle = {};
        mantle[key] = value;
        return patched(object, mantle, false);
    }
    lib_object.attached = attached;
    /**
     * @author fenris
     */
    function copy(object) {
        return patched({}, object);
    }
    lib_object.copy = copy;
})(lib_object || (lib_object = {}));
/**
 * @desc adapters for old syntax
 * @author fenris
 */
var object_fetch = lib_object.fetch;
var object_map = lib_object.map;
var object_a2o = lib_object.from_array;
var object_o2a = lib_object.to_array;
var object_matches = lib_object.matches;
var object_clash = lib_object.clash;
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/*
This file is part of »bacterio-plankton:path«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:path« 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:path« 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:path«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_path;
(function (lib_path) {
    /**
     * @author fenris
     */
    var class_step = /** @class */ (function () {
        function class_step() {
        }
        return class_step;
    }());
    lib_path.class_step = class_step;
    /**
     * @author fenris
     */
    var class_step_stay = /** @class */ (function (_super) {
        __extends(class_step_stay, _super);
        function class_step_stay() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        /**
         * @author fenris
         */
        class_step_stay.prototype.invert = function () {
            return (new class_step_stay());
        };
        /**
         * @author fenris
         */
        class_step_stay.prototype.toString = function () {
            return ".";
        };
        return class_step_stay;
    }(class_step));
    lib_path.class_step_stay = class_step_stay;
    /**
     * @author fenris
     */
    var class_step_back = /** @class */ (function (_super) {
        __extends(class_step_back, _super);
        function class_step_back() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        /**
         * @author fenris
         */
        class_step_back.prototype.invert = function () {
            throw (new Error("impossible"));
        };
        /**
         * @author fenris
         */
        class_step_back.prototype.toString = function () {
            return "..";
        };
        return class_step_back;
    }(class_step));
    lib_path.class_step_back = class_step_back;
    /**
     * @author fenris
     */
    var class_step_regular = /** @class */ (function (_super) {
        __extends(class_step_regular, _super);
        /**
         * @author fenris
         */
        function class_step_regular(name) {
            var _this = _super.call(this) || this;
            _this.name = name;
            return _this;
        }
        /**
         * @author fenris
         */
        class_step_regular.prototype.invert = function () {
            return (new class_step_back());
        };
        /**
         * @author fenris
         */
        class_step_regular.prototype.toString = function () {
            return this.name;
        };
        return class_step_regular;
    }(class_step));
    lib_path.class_step_regular = class_step_regular;
    /**
     * @author fenris
     */
    function step_read(s) {
        switch (s) {
            case ".": {
                return (new class_step_stay());
                // break;
            }
            case "..": {
                return (new class_step_back());
                // break;
            }
            default: {
                return (new class_step_regular(s));
                // break;
            }
        }
    }
    lib_path.step_read = step_read;
})(lib_path || (lib_path = {}));
/*
This file is part of »bacterio-plankton:path«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:path« 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:path« 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:path«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_path;
(function (lib_path) {
    /**
     * @author fenris
     */
    var class_chain = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_chain(steps) {
            if (steps === void 0) { steps = []; }
            this.steps = steps;
        }
        /**
         * @author fenris
         */
        class_chain.splitter = function (system) {
            if (system === void 0) { system = "linux"; }
            return (object_fetch({
                "linux": "/",
                "bsd": "/",
                "win": "\\"
            }, system, "/", 2));
        };
        /**
         * @desc removes superfluent steps from the chain, e.g. infix ".."
         * @author fenris
         */
        class_chain.prototype.normalize = function () {
            var steps = this.steps;
            // filter "stay"
            {
                steps = steps.filter(function (step) { return (!(step instanceof lib_path.class_step_stay)); });
            }
            // filter "regular-back"
            {
                var _loop_1 = function () {
                    if (steps.length < 1) {
                        return "break";
                    }
                    else {
                        var last_1 = steps[0];
                        var found = steps.slice(1).some(function (step, index) {
                            if (step instanceof lib_path.class_step_back) {
                                if (last_1 instanceof lib_path.class_step_regular) {
                                    steps.splice(index, 2);
                                    return true;
                                }
                            }
                            last_1 = step;
                            return false;
                        });
                        if (!found) {
                            return "break";
                        }
                    }
                };
                while (true) {
                    var state_1 = _loop_1();
                    if (state_1 === "break")
                        break;
                }
            }
            return (new class_chain(steps));
        };
        /**
         * @author fenris
         */
        class_chain.prototype.invert = function () {
            return (new class_chain(this.steps.map(function (step) { return step.invert(); })));
        };
        /**
         * @author fenris
         */
        class_chain.prototype.add = function (step) {
            return (new class_chain(this.steps.concat([step]))).normalize();
        };
        /**
         * @author fenris
         */
        class_chain.prototype.extend = function (chain) {
            return (new class_chain(this.steps.concat(chain.steps))).normalize();
        };
        /**
         * @author fenris
         */
        class_chain.prototype.as_string = function (system) {
            if (system === void 0) { system = "linux"; }
            var splitter = class_chain.splitter(system);
            return ((this.steps.length == 0) ? ("." + splitter) : this.steps.map(function (step) { return (step.toString() + splitter); }).join(""));
        };
        /**
         * @author fenris
         */
        class_chain.prototype.toString = function () {
            return this.as_string();
        };
        return class_chain;
    }());
    lib_path.class_chain = class_chain;
    /**
     * @author fenris
     */
    function chain_read(str, system) {
        if (system === void 0) { system = "linux"; }
        var splitter = class_chain.splitter(system);
        var parts = str.split(splitter);
        if (parts[parts.length - 1] == "")
            parts.pop();
        return (new class_chain(parts.map(lib_path.step_read)));
    }
    lib_path.chain_read = chain_read;
})(lib_path || (lib_path = {}));
/*
This file is part of »bacterio-plankton:path«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:path« 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:path« 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:path«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_path;
(function (lib_path) {
    /**
     * @author fenris
     */
    var class_location = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_location(anchor, chain) {
            this.anchor = anchor;
            this.chain = chain;
        }
        /**
         * @author fenris
         */
        class_location.anchorpattern = function (system) {
            if (system === void 0) { system = "linux"; }
            return (object_fetch({
                "linux": new RegExp("/"),
                "bsd": new RegExp("/"),
                "win": new RegExp("[A-Z]:\\\\>")
            }, system, new RegExp("/"), 1));
        };
        /**
         * @desc [accessor]
         * @author fenris
         */
        class_location.prototype.is_absolute = function () {
            return (this.anchor != null);
        };
        /**
         * @author fenris
         */
        class_location.prototype.normalize = function () {
            return (new class_location(this.anchor, this.chain.normalize()));
        };
        /**
         * @author fenris
         */
        class_location.prototype.extend = function (chain) {
            return (new class_location(this.anchor, this.chain.extend(chain)));
        };
        /**
         * @desc [accessor]
         * @author fenris
         */
        class_location.prototype.relocate = function (location) {
            if (this.is_absolute()) {
                return (new class_location(this.anchor, this.chain));
            }
            else {
                return location.extend(this.chain);
            }
        };
        /**
         * @author fenris
         */
        class_location.prototype.go_thither = function () {
            // console.error(">>", this.toString());
            process.chdir(this.toString());
        };
        /**
         * @author fenris
         */
        class_location.prototype.expedition = function (core) {
            var that = this;
            var current = location_read(process.cwd());
            function begin() {
                // (new class_message("changing directory to '" + that.toString() + "'")).stderr();
                that.go_thither();
            }
            function end() {
                // (new class_message("changing directory to '" + current.toString() + "'")).stderr();
                current.go_thither();
            }
            begin();
            core(end);
        };
        /**
         * @author fenris
         */
        class_location.prototype.as_string = function (system) {
            if (system === void 0) { system = "linux"; }
            return (((this.anchor != null) ? this.anchor : "") + this.chain.as_string(system));
        };
        /**
         * @author fenris
         */
        class_location.prototype.toString = function () {
            return this.as_string();
        };
        /**
         * @author fenris
         */
        class_location.current = function () {
            // return class_location.read(process.cwd());
            return location_read(process.cwd());
        };
        /**
         * @author fenris
         */
        class_location.tempfolder = function (system) {
            if (system === void 0) { system = "linux"; }
            return (object_fetch({
                "linux": new class_location("/", new lib_path.class_chain([new lib_path.class_step_regular("tmp")])),
                "bsd": new class_location("/", new lib_path.class_chain([new lib_path.class_step_regular("tmp")])),
                "win": new class_location(null, new lib_path.class_chain([new lib_path.class_step_regular("%TEMP%")]))
            }, system, null, 2));
        };
        return class_location;
    }());
    lib_path.class_location = class_location;
    /**
     * @author fenris
     */
    function location_read(str, system) {
        if (system === void 0) { system = "linux"; }
        var regexp = class_location.anchorpattern(system);
        var matching = regexp.exec(str);
        if ((matching == null) || (matching.index > 0)) {
            return (new class_location(null, lib_path.chain_read(str, system)));
        }
        else {
            return (new class_location(matching[0], lib_path.chain_read(str.slice(matching[0].length), system)));
        }
    }
    lib_path.location_read = location_read;
})(lib_path || (lib_path = {}));
/*
This file is part of »bacterio-plankton:path«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:path« 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:path« 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:path«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_path;
(function (lib_path) {
    /**
     * @author fenris
     */
    var class_filepointer = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_filepointer(location, filename) {
            this.location = location;
            this.filename = filename;
        }
        /**
         * @author fenris
         */
        class_filepointer.prototype.normalize = function () {
            return (new class_filepointer(this.location.normalize(), this.filename));
        };
        /**
         * @author fenris
         */
        class_filepointer.prototype.foo = function (filepointer) {
            return (new class_filepointer(this.location.extend(filepointer.location.chain), filepointer.filename));
        };
        /**
         * @desc [accessor]
         * @author fenris
         */
        class_filepointer.prototype.relocate = function (location) {
            return (new class_filepointer(this.location.relocate(location), this.filename));
        };
        /**
         * @author fenris
         */
        class_filepointer.prototype.as_string = function (system) {
            if (system === void 0) { system = "linux"; }
            return (this.location.as_string(system) /* + "/"*/ + ((this.filename == null) ? "" : this.filename));
        };
        /**
         * @author fenris
         */
        class_filepointer.prototype.toString = function () {
            return this.as_string();
        };
        return class_filepointer;
    }());
    lib_path.class_filepointer = class_filepointer;
    /**
     * @author fenris
     */
    function filepointer_read(str, system) {
        if (system === void 0) { system = "linux"; }
        var splitter = lib_path.class_chain.splitter(system);
        var parts = str.split(splitter);
        var last = parts[parts.length - 1];
        if (last == "") {
            return (new class_filepointer(lib_path.location_read(parts.join(splitter), system), null));
        }
        else {
            return (new class_filepointer(lib_path.location_read(parts.slice(0, parts.length - 1).join(splitter), system), last));
        }
    }
    lib_path.filepointer_read = filepointer_read;
})(lib_path || (lib_path = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.define("code", {
        "from": null,
        "to": null
    }, {
        "encode": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "from"
                        }
                    },
                    "shape_output": {
                        "name": "variable",
                        "parameters": {
                            "name": "to"
                        }
                    }
                }
            }
        },
        "decode": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "to"
                        }
                    },
                    "shape_output": {
                        "name": "variable",
                        "parameters": {
                            "name": "from"
                        }
                    }
                }
            }
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author Christian Fraß <frass@greenscale.de>
     */
    function custom_encode(function_, from) {
        return function_(from);
    }
    lib_code.custom_encode = custom_encode;
    /**
     * @author Christian Fraß <frass@greenscale.de>
     */
    function custom_decode(function_, to) {
        return function_(to);
    }
    lib_code.custom_decode = custom_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_custom {
        /**
         * @author fenris
         */
        constructor(encodefunc, decodefunc) {
            this.encodefunc = encodefunc;
            this.decodefunc = decodefunc;
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.custom_encode(this.encodefunc, x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.custom_decode(this.decodefunc, x);
        }
    }
    lib_code.class_code_custom = class_code_custom;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function inverse_encode(decode, to) {
        return decode(to);
    }
    lib_code.inverse_encode = inverse_encode;
    /**
     * @author fenris
     */
    function inverse_decode(encode, from) {
        return encode(from);
    }
    lib_code.inverse_decode = inverse_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "inverse", {
        "from": {
            "name": "any"
        },
        "to": {
            "name": "any"
        }
    }, {
        "encode": (domain_parameters) => (x) => {
            return (lib_code.inverse_encode(y_ => lib_trait.call("code", "decode", domain_parameters.domain_subject)(y_), x));
        },
        "decode": (domain_parameters) => (y) => {
            return (lib_code.inverse_decode(x_ => lib_trait.call("code", "encode", domain_parameters.domain_subject)(x_), y));
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_inverse {
        /**
         * @author fenris
         */
        constructor(subject) {
            this.subject = subject;
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(to) {
            return lib_code.inverse_encode(x => this.subject.decode(x), to);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(from) {
            return lib_code.inverse_decode(x => this.subject.encode(x), from);
        }
    }
    lib_code.class_code_inverse = class_code_inverse;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function pair_encode(encode_first, encode_second, from) {
        let between = encode_first(from);
        let to = encode_second(between);
        return to;
    }
    lib_code.pair_encode = pair_encode;
    /**
     * @author fenris
     */
    function pair_decode(decode_first, decode_second, to) {
        let between = decode_second(to);
        let from = decode_first(between);
        return from;
    }
    lib_code.pair_decode = pair_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "pair", {
        "from": {
            "name": "any"
        },
        "to": {
            "name": "any"
        }
    }, {
        "encode": (domain_parameters) => (x) => {
            return (lib_code.pair_encode(x_ => lib_trait.call("code", "encode", domain_parameters.domain_first)(x_), x_ => lib_trait.call("code", "encode", domain_parameters.domain_second)(x_), x));
        },
        "decode": (domain_parameters) => (y) => {
            return (lib_code.pair_decode(y_ => lib_trait.call("code", "decode", domain_parameters.domain_first)(y_), y_ => lib_trait.call("code", "decode", domain_parameters.domain_second)(y_), y));
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_pair {
        /**
         * @author fenris
         */
        constructor(first, second) {
            this.first = first;
            this.second = second;
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(from) {
            return lib_code.pair_encode(x => this.first.encode(x), x => this.second.encode(x), from);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(to) {
            return lib_code.pair_decode(x => this.first.decode(x), x => this.second.decode(x), to);
        }
    }
    lib_code.class_code_pair = class_code_pair;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function chain_encode(encode_links, from) {
        let value = from;
        encode_links
            .forEach((link) => {
            value = link(value);
        });
        return value;
    }
    lib_code.chain_encode = chain_encode;
    /**
     * @author fenris
     */
    function chain_decode(decode_links, to) {
        let value = to;
        decode_links
            .reverse()
            .forEach((link) => {
            value = link(value);
        });
        return value;
    }
    lib_code.chain_decode = chain_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_chain {
        /**
         * @author fenris
         */
        constructor(links) {
            this.links = links;
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(from) {
            return lib_code.chain_encode(this.links.map((link) => (x => link.encode(x))), from);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(to) {
            return lib_code.chain_decode(this.links.map((link) => (x => link.decode(x))), to);
        }
    }
    lib_code.class_code_chain = class_code_chain;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author Christian Fraß <frass@greenscale.de>
     */
    function flatten_encode(from, 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((line) => keys.map((name) => line[name])),
        };
    }
    lib_code.flatten_encode = flatten_encode;
    /**
     * @author Christian Fraß <frass@greenscale.de>
     */
    function flatten_decode(to) {
        return (to.data
            .map((dataset) => {
            let dataset_ = {};
            dataset
                .forEach((value, index) => {
                const name = to.keys[index];
                dataset_[name] = value;
            });
            return dataset_;
        }));
    }
    lib_code.flatten_decode = flatten_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_flatten {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.flatten_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.flatten_decode(x);
        }
    }
    lib_code.class_code_flatten = class_code_flatten;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    const _prefix = "DATE:";
    /**
     * @author fenris
     */
    function jsdate_encode(date) {
        let isostring = date.toISOString();
        let date_ = (_prefix + isostring);
        return date_;
    }
    lib_code.jsdate_encode = jsdate_encode;
    /**
     * @author fenris
     */
    function jsdate_decode(date_) {
        if ((typeof (date_) === "string") && (date_.startsWith(_prefix))) {
            let isostring = date_.slice(_prefix.length);
            let timestamp = Date.parse(isostring);
            if (!isNaN(timestamp)) {
                let date = (new Date(timestamp));
                return date;
            }
            else {
                let message = ("'" + isostring + "' does not seem to be an ISO-string of a date");
                throw (new Error(message));
            }
        }
        else {
            let message = ("expected an encoded date object to be a string starting with '" + _prefix + "'");
            throw (new Error(message));
        }
    }
    lib_code.jsdate_decode = jsdate_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "jsdate", {
        "from": {
            "name": "date"
        },
        "to": {
            "name": "string"
        }
    }, {
        "encode": () => (x) => {
            return lib_code.jsdate_encode(x);
        },
        "decode": () => (y) => {
            return lib_code.jsdate_decode(y);
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_jsdate {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.jsdate_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.jsdate_decode(x);
        }
    }
    lib_code.class_code_jsdate = class_code_jsdate;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function json_encode(x, formatted = false) {
        return JSON.stringify(x, undefined, formatted ? "\t" : undefined);
    }
    lib_code.json_encode = json_encode;
    /**
     * @author fenris
     */
    function json_decode(x) {
        return JSON.parse(x);
    }
    lib_code.json_decode = json_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "json", {
        "from": {
            "name": "any"
        },
        "to": {
            "name": "string"
        }
    }, {
        "encode": () => (x) => {
            return lib_code.json_encode(x);
        },
        "decode": () => (y) => {
            return lib_code.json_decode(y);
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_json {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.json_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.json_decode(x);
        }
    }
    lib_code.class_code_json = class_code_json;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author Christian Fraß <frass@greenscale.de>
     * @todo escaping
     */
    function csv_encode(from, { "delimiter": delimiter = ",", "linebreak": linebreak = "\n", } = {}) {
        return (([]
            .concat((from.head !== null)
            ? [from.head]
            : [])
            .concat(from.data))
            .map((dataset) => dataset.join(delimiter))
            .join(linebreak));
    }
    lib_code.csv_encode = csv_encode;
    /**
     * @author Christian Fraß <frass@greenscale.de>
     */
    function csv_decode(to, { "delimiter": delimiter = ",", "linebreak": linebreak = "\n", "with_head": with_head = true, } = {}) {
        const array = (to.split(linebreak)
            .map((line) => line.split(delimiter)));
        return (with_head
            ? ({
                "head": array[0],
                "data": array.slice(1),
            })
            : ({
                "head": null,
                "data": array,
            }));
    }
    lib_code.csv_decode = csv_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_csv {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.csv_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.csv_decode(x);
        }
    }
    lib_code.class_code_csv = class_code_csv;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function uri_encode(x) {
        return encodeURIComponent(x);
    }
    lib_code.uri_encode = uri_encode;
    /**
     * @author fenris
     */
    function uri_decode(x) {
        return decodeURIComponent(x);
    }
    lib_code.uri_decode = uri_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "uri", {
        "from": {
            "name": "string"
        },
        "to": {
            "name": "string"
        }
    }, {
        "encode": () => (x) => {
            return lib_code.uri_encode(x);
        },
        "decode": () => (y) => {
            return lib_code.uri_decode(y);
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_uri {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.uri_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.uri_decode(x);
        }
    }
    lib_code.class_code_uri = class_code_uri;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    function base64_encode(x) {
        return (new Buffer(x)).toString("base64");
    }
    lib_code.base64_encode = base64_encode;
    /**
     * @author fenris
     */
    function base64_decode(x) {
        return (new Buffer(x, "base64")).toString();
    }
    lib_code.base64_decode = base64_decode;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    lib_trait.attend("code", "base64", {
        "from": {
            "name": "string"
        },
        "to": {
            "name": "string"
        }
    }, {
        "encode": () => (x) => {
            return lib_code.base64_encode(x);
        },
        "decode": () => (y) => {
            return lib_code.base64_decode(y);
        }
    });
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:code«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_code;
(function (lib_code) {
    /**
     * @author fenris
     */
    class class_code_base64 {
        /**
         * @author fenris
         */
        constructor() {
        }
        /**
         * @implementation
         * @author fenris
         */
        encode(x) {
            return lib_code.base64_encode(x);
        }
        /**
         * @implementation
         * @author fenris
         */
        decode(x) {
            return lib_code.base64_decode(x);
        }
    }
    lib_code.class_code_base64 = class_code_base64;
})(lib_code || (lib_code = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    lib_trait.define("comm-client", {
        "state": null,
        "message_in": null,
        "message_out": null
    }, {
        "setup": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "state"
                        }
                    },
                    "shape_output": {
                        "name": "promise",
                        "parameters": {
                            "shape_result": {
                                "name": "variable",
                                "parameters": {
                                    "name": "state"
                                }
                            },
                            "shape_reason": {
                                "name": "any"
                            }
                        }
                    }
                }
            }
        },
        "send": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "state"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "message_out"
                                }
                            },
                            "shape_output": {
                                "name": "promise",
                                "parameters": {
                                    "shape_result": {
                                        "name": "variable",
                                        "parameters": {
                                            "name": "message_in"
                                        }
                                    },
                                    "shape_reason": {
                                        "name": "any"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    });
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    lib_comm.default_parameters_client_http = {
        "protocol": "http",
        "host": null,
        "port": null,
        "path": null,
        "omit_protocol": false,
        "content_type": "plain/text; charset=utf-8",
        "with_credentials": false,
    };
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    const _modulenamemap = {
        "http": "http",
        "https": "https",
    };
    /**
     * @author fenris
     */
    function client_http_construct(parameters = {}, method = "POST", headers = {}) {
        return {
            "parameters": lib_object.patched(lib_comm.default_parameters_client_http, parameters),
            "method": method,
            "headers": headers,
            "nm_http": null,
        };
    }
    lib_comm.client_http_construct = client_http_construct;
    /**
     * @author fenris
     */
    function client_http_setup(subject) {
        return (lib_call.promise_make((resolve, reject) => {
            let modulename = null;
            if (subject.parameters.protocol == undefined) {
                modulename = "http";
            }
            else {
                if (subject.parameters.protocol in _modulenamemap) {
                    modulename = _modulenamemap[subject.parameters.protocol];
                }
                else {
                    modulename = null;
                }
            }
            if (modulename != null) {
                subject.nm_http = require(modulename);
                resolve(undefined);
            }
            else {
                reject(new Error(`no module for protocol '${subject.parameters.protocol}'`));
            }
        }));
    }
    lib_comm.client_http_setup = client_http_setup;
    /**
     * @author fenris
     */
    function client_http_send(subject, message) {
        return (lib_call.promise_make((resolve, reject) => {
            let request = subject.nm_http.request({
                "host": subject.parameters.host,
                "port": subject.parameters.port,
                "path": subject.parameters.path,
                "method": subject.method.toUpperCase(),
            }, (response) => {
                let content = "";
                // let buffer : Buffer = Buffer["from"]([]);
                response.on("data", (chunk) => {
                    content += chunk;
                    // buffer = Buffer["concat"]([buffer, chunk]);
                });
                response.on("end", () => {
                    const answer = {
                        "code": response.statusCode,
                        "text": content,
                    };
                    resolve(answer);
                });
            });
            lib_object.to_array(subject.headers).forEach(({ "key": key, "value": value }) => {
                request.setHeader(key, value);
            });
            request.write(message);
            request.on("error", (error) => {
                reject(error);
            });
            request.end();
        }));
    }
    lib_comm.client_http_send = client_http_send;
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    lib_trait.attend("comm-client", "http", {
        "state": {
            "name": "any"
        },
        "message_in": {
            "name": "string"
        },
        "message_out": {
            "name": "any" // type_response_http
        }
    }, {
        "setup": () => (state) => {
            return lib_comm.client_http_setup(state).then(_ => lib_call.promise_resolve(state));
        },
        "send": () => (state) => (message) => {
            return lib_comm.client_http_send(state, message);
        }
    });
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    class class_client_http {
        /**
         * @author fenris
         */
        constructor(parameters = lib_comm.default_parameters_client_http, method = "POST", headers = {}) {
            this.subject = lib_comm.client_http_construct(parameters, method, headers);
        }
        /**
         * @author fenris
         * @implementation
         */
        setup() {
            return lib_comm.client_http_setup(this.subject);
        }
        /**
         * @author fenris
         * @implementation
         */
        send(message) {
            return lib_comm.client_http_send(this.subject, message);
        }
    }
    lib_comm.class_client_http = class_client_http;
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @author fenris
     */
    class class_client_mhttp {
        /**
         * @author fenris
         */
        constructor(parameters = lib_comm.default_parameters_client_http) {
            this.core = new lib_comm.class_client_http(parameters);
        }
        /**
         * @author fenris
         * @implementation
         */
        setup() {
            return this.core.setup();
        }
        /**
         * @author fenris
         * @implementation
         */
        send(message) {
            return (this.core.send(message)
                .then((answer) => {
                switch (answer.code) {
                    case 200: {
                        return lib_call.promise_resolve(answer.text /*.toString()*/);
                        break;
                    }
                    default: {
                        return lib_call.promise_reject(new Error(`XMLHttpRequest failed; status was ${answer.code.toFixed(0)}`));
                        break;
                    }
                }
            }));
        }
    }
    lib_comm.class_client_mhttp = class_client_mhttp;
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:comm-client«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:comm-client« 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:comm-client« 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:comm-client«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_comm;
(function (lib_comm) {
    /**
     * @desc wrapper for string-based clients
     * @author fenris
     */
    class class_client_complex {
        /**
         * @author fenris
         */
        constructor(core, code = new lib_code.class_code_pair(new lib_code.class_code_json(), new lib_code.class_code_uri())) {
            this.core = core;
            this.code = code;
        }
        /**
         * @author fenris
         * @implementation
         */
        setup() {
            return this.core.setup();
        }
        /**
         * @author fenris
         * @implementation
         */
        send(message) {
            const message_out_raw = this.code.encode(message);
            return (this.core.send(message_out_raw)
                .then((message_in_raw) => {
                const message_in = this.code.decode(message_in_raw);
                return lib_call.promise_resolve(message_in);
            }));
        }
    }
    lib_comm.class_client_complex = class_client_complex;
})(lib_comm || (lib_comm = {}));
/*
This file is part of »bacterio-plankton:file«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_file;
(function (lib_file) {
    /**
     * @author fenris
     */
    function read_regular_promise(path) {
        const nm_fs = require("fs");
        return (lib_call.promise_make((resolve, reject) => {
            nm_fs.readFile(path, {
                "encoding": "utf8",
                "flag": "r",
            }, (error, content) => {
                if (error == null) {
                    resolve(content);
                }
                else {
                    reject(error);
                }
            });
        }));
    }
    /**
     * @author fenris
     */
    function read_http_promise(path) {
        return (lib_call.promise_make((resolve, reject) => {
            const nm_url = require("url");
            const parsed_url = nm_url.parse(path, false, true);
            const client = ((parsed_url.protocol === "https:")
                ? require("https")
                : require("http"));
            const default_port = ((parsed_url.protocol == "https:")
                ? 443
                : 80);
            const options = {
                "hostname": parsed_url.hostname,
                "port": (parsed_url.port || default_port),
                "path": parsed_url.path,
                "method": "GET"
            };
            let req = client.request(options, (res) => {
                let data = ""; // @todo
                res.on("data", (chunk) => {
                    data += chunk;
                });
                res.on("end", () => {
                    resolve(data);
                });
            });
            req.end();
            req.on("error", (error) => {
                reject(error);
            });
        }));
    }
    /**
     * @author fenris
     */
    function write_regular_promise(path, content) {
        const nm_fs = require("fs");
        return (lib_call.promise_make((resolve, reject) => {
            nm_fs.writeFile(path, content, {
                "encoding": "utf8",
                "flag": "w",
            }, (error) => {
                if (error == null) {
                    resolve(undefined);
                }
                else {
                    reject(error);
                }
            });
        }));
    }
    /**
     * @author maspr,fenris
     */
    function determine_handler(path) {
        if (new RegExp("^https?:\/\/").test(path)) {
            return "http";
        }
        else {
            return "file";
        }
    }
    /**
     * @author fenris,maspr
     * @todo clear up if http(s)-handling belongs here or not ...
     */
    function read_promise(path) {
        switch (determine_handler(path)) {
            case "file": {
                return read_regular_promise(path);
                break;
            }
            case "http": {
                return read_http_promise(path);
                break;
            }
            default: {
                const message = "unhandled protocol";
                return lib_call.promise_reject(new Error(message));
                break;
            }
        }
    }
    lib_file.read_promise = read_promise;
    /**
     * @author fenris
     */
    function write_promise(path, content) {
        return write_regular_promise(path, content);
    }
    lib_file.write_promise = write_promise;
})(lib_file || (lib_file = {}));
/*
This file is part of »bacterio-plankton:file«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»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_file;
(function (lib_file) {
    /**
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     */
    function read_json_promise(path) {
        return (lib_call.promise_resolve(undefined)
            .then(_ => lib_file.read_promise(path))
            .then(content => lib_call.promise_make((resolve, reject) => {
            let error;
            let data;
            try {
                data = JSON.parse(content);
                error = null;
            }
            catch (exception) {
                let message = `invalid json '${path}'`;
                error = new class_error(message, [exception]);
            }
            if (error == null) {
                resolve(data);
            }
            else {
                reject(error);
            }
        })));
    }
    lib_file.read_json_promise = read_json_promise;
    /**
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     */
    function write_json_promise(path, data) {
        return lib_file.write_promise(path, JSON.stringify(data, undefined, "\t"));
    }
    lib_file.write_json_promise = write_json_promise;
    /**
     * @author fenris
     * @deprecated use promises instead of executors
     */
    function read_executor(path) {
        return lib_call.promise_to_executor(lib_file.read_promise(path));
    }
    lib_file.read_executor = read_executor;
    /**
     * @author fenris
     * @deprecated use promises instead of executors
     */
    function write_executor(path, content) {
        return lib_call.promise_to_executor(lib_file.write_promise(path, content));
    }
    lib_file.write_executor = write_executor;
    /**
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     * @deprecated use promises instead of executors
     */
    function read_json_executor(path) {
        return lib_call.promise_to_executor(read_json_promise(path));
    }
    lib_file.read_json_executor = read_json_executor;
    /**
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     * @deprecated use promises instead of executors
     */
    function write_json_executor(path, data) {
        return lib_call.promise_to_executor(write_json_promise(path, data));
    }
    lib_file.write_json_executor = write_json_executor;
    /**
     * @desc reads a file
     * @author fenris
     * @todo replace with promise version
     */
    function read(path) {
        return read_executor(path);
    }
    lib_file.read = read;
    /**
     * @desc writes a file
     * @author fenris
     * @todo replace with promise version
     */
    function write(path, content) {
        return write_executor(path, content);
    }
    lib_file.write = write;
    /**
     * @desc reads a json file
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     */
    function read_json(path) {
        return read_json_executor(path);
    }
    lib_file.read_json = read_json;
    /**
     * @desc writes a json file
     * @author fenris
     * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead
     */
    function write_json(path, data) {
        return write_json_executor(path, data);
    }
    lib_file.write_json = write_json;
})(lib_file || (lib_file = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function map_clear(map_forEach, map_delete) {
        map_forEach((value, key) => {
            map_delete(key);
        });
    }
    lib_structures.map_clear = map_clear;
    /**
     * @author fenris
     */
    function map_keys(map_forEach) {
        let keys = [];
        map_forEach((value, key) => {
            keys.push(key);
        });
        return keys;
    }
    lib_structures.map_keys = map_keys;
    /**
     * @author fenris
     */
    function map_values(map_forEach) {
        let values = [];
        map_forEach((value, key) => {
            values.push(value);
        });
        return values;
    }
    lib_structures.map_values = map_values;
    /**
     * @author fenris
     */
    function map_pairs(map_forEach) {
        let pairs = [];
        map_forEach((value, key) => {
            let pair = { "key": key, "value": value };
            pairs.push(pair);
        });
        return pairs;
    }
    lib_structures.map_pairs = map_pairs;
    /**
     * @author fenris
     */
    function map_toString(map_forEach, show_key = instance_show, show_value = instance_show) {
        return ("["
            +
                (map_pairs(map_forEach)
                    .map(({ "key": key, "value": value }) => (show_key(key)
                    +
                        " -> "
                    +
                        show_value(value)))
                    .join(", "))
            +
                "]");
    }
    lib_structures.map_toString = map_toString;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.define("map", {
        "subject": [],
        "key": [],
        "value": []
    }, {
        "has": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "key"
                                }
                            },
                            "shape_output": {
                                "name": "boolean"
                            }
                        }
                    }
                }
            }
        },
        "get": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "key"
                                }
                            },
                            "shape_output": {
                                "name": "variable",
                                "parameters": {
                                    "name": "value"
                                }
                            }
                        }
                    }
                }
            }
        },
        "set": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "key"
                                }
                            },
                            "shape_output": {
                                "name": "function",
                                "parameters": {
                                    "shape_input": {
                                        "name": "variable",
                                        "parameters": {
                                            "name": "value"
                                        }
                                    },
                                    "shape_output": {
                                        "name": "variable",
                                        "parameters": {
                                            "name": "subject"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "delete": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "key"
                                }
                            },
                            "shape_output": {
                                "name": "variable",
                                "parameters": {
                                    "name": "subject"
                                }
                            }
                        }
                    }
                }
            }
        },
        "forEach": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "function",
                                "parameters": {
                                    "shape_input": {
                                        "name": "variable",
                                        "parameters": {
                                            "name": "value"
                                        }
                                    },
                                    "shape_output": {
                                        "name": "void"
                                    }
                                }
                            },
                            "shape_output": {
                                "name": "void"
                            }
                        }
                    }
                }
            }
        },
        "clear": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        },
                    },
                    "shape_output": {
                        "name": "void"
                    }
                }
            },
            "implementation": (call_) => (lib_structures.map_clear((procedure) => call_("forEach")(procedure), (key) => call_("delete")(key))),
        },
        "keys": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "variable",
                                "parameters": {
                                    "name": "key"
                                }
                            }
                        }
                    }
                }
            },
            "implementation": (call_) => ((subject) => lib_structures.map_keys((procedure) => call_("forEach")(subject)(procedure))),
        },
        "values": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "variable",
                                "parameters": {
                                    "name": "value"
                                }
                            }
                        }
                    }
                }
            },
            "implementation": (call_) => ((subject) => lib_structures.map_values((procedure) => call_("forEach")(subject)(procedure))),
        },
        "pairs": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "object",
                                "parameters": {
                                    "fields": [
                                        {
                                            "name": "key",
                                            "shape": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "key"
                                                }
                                            }
                                        },
                                        {
                                            "name": "value",
                                            "shape": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "value"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "implementation": (call_) => ((subject) => lib_structures.map_pairs((procedure) => call_("forEach")(subject)(procedure))),
        },
        "toString": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            // show_key
                            "shape_input": {
                                "name": "function",
                                "parameters": {
                                    "shape_input": {
                                        "name": "variable",
                                        "parameters": {
                                            "name": "key"
                                        }
                                    },
                                    "shape_output": {
                                        "name": "string"
                                    }
                                }
                            },
                            "shape_output": {
                                "name": "function",
                                "parameters": {
                                    // show_value
                                    "shape_input": {
                                        "name": "function",
                                        "parameters": {
                                            "shape_input": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "value"
                                                }
                                            },
                                            "shape_output": {
                                                "name": "string"
                                            }
                                        }
                                    },
                                    "shape_output": {
                                        "name": "array",
                                        "parameters": {
                                            "shape_element": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "value"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "implementation": (call_) => ((subject) => (show_key) => (show_value) => lib_structures.map_toString((procedure) => call_("forEach")(subject)(procedure), show_key, show_value)),
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_mapbase {
        /**
         * @author fenris
         * @desc [constructor]
         */
        constructor() {
        }
        /**
         * @desc [mutator]
         * @author fenris
         */
        clear() {
            return (lib_structures.map_clear((procedure) => this.forEach(procedure), (key) => this.delete(key)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        keys() {
            return (lib_structures.map_keys((procedure) => this.forEach(procedure)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        values() {
            return (lib_structures.map_values((procedure) => this.forEach(procedure)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        pairs() {
            return (lib_structures.map_pairs((procedure) => this.forEach(procedure)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        toString(show_key = instance_show, show_value = instance_show) {
            return (lib_structures.map_toString((procedure) => this.forEach(procedure), show_key, show_value));
        }
    }
    lib_structures.class_mapbase = class_mapbase;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.define("memory", {
        "subject": [],
        "element": []
    }, {
        "size": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "int"
                    }
                }
            }
        },
        "scan": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "variable",
                        "parameters": {
                            "name": "element"
                        }
                    }
                }
            }
        },
        "give": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "element"
                                }
                            },
                            "shape_output": {
                                "name": "variable",
                                "parameters": {
                                    "name": "subject"
                                }
                            }
                        }
                    }
                }
            }
        },
        "take": {
            "shape": {
                "name": "function",
                "parameters": {
                    "shape_input": {
                        "name": "variable",
                        "parameters": {
                            "name": "subject"
                        }
                    },
                    "shape_output": {
                        "name": "function",
                        "parameters": {
                            "shape_input": {
                                "name": "variable",
                                "parameters": {
                                    "name": "element"
                                }
                            },
                            "shape_output": {
                                "name": "object",
                                "parameters": {
                                    "fields": [
                                        {
                                            "name": "subject",
                                            "shape": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "subject"
                                                }
                                            }
                                        },
                                        {
                                            "name": "element",
                                            "shape": {
                                                "name": "variable",
                                                "parameters": {
                                                    "name": "element"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_pair {
        /**
         * @author fenris
         */
        constructor(first, second) {
            this.first = first;
            this.second = second;
        }
        /**
         * @desc [accessor] [getter]
         * @author fenris
         */
        first_get() {
            return this.first;
        }
        /**
         * @desc [accessor] [getter]
         * @author fenris
         */
        second_get() {
            return this.second;
        }
        /**
         * @desc [mutator] [setter]
         * @author fenris
         */
        first_set(first) {
            this.first = first;
        }
        /**
         * @desc [mutator] [setter]
         * @author fenris
         */
        second_set(second) {
            this.second = second;
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        swap() {
            return (new class_pair(this.second, this.first));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        transform(transform_first, transform_second) {
            return (new class_pair(transform_first(this.first), transform_second(this.second)));
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _clone() {
            return (new class_pair(instance_clone(this.first), instance_clone(this.second)));
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _hash() {
            return ("pair_" + instance_hash(this.first) + "_" + instance_hash(this.second) + "");
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _collate(pair) {
            return (instance_collate(this.first, pair.first)
                &&
                    instance_collate(this.second, pair.second));
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _show() {
            return ("(" + instance_show(this.first) + "," + instance_show(this.second) + ")");
        }
    }
    lib_structures.class_pair = class_pair;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function set_construct(collation, elements = []) {
        let subject = {
            "elements": []
        };
        elements.forEach(element => set_add(collation, subject, element));
        return subject;
    }
    lib_structures.set_construct = set_construct;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_size(subject) {
        return subject.elements.length;
    }
    lib_structures.set_size = set_size;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_has(collation, subject, element) {
        return subject.elements.some(element_ => collation(element, element_));
    }
    lib_structures.set_has = set_has;
    /**
     * @desc [mutator]
     * @author fenris
     */
    function set_add(collation, subject, element) {
        if (!set_has(collation, subject, element)) {
            subject.elements.push(element);
        }
    }
    lib_structures.set_add = set_add;
    /**
     * @desc [mutator]
     * @author fenris
     */
    function set_pop(subject) {
        if (subject.elements.length == 0) {
            return (new class_nothing());
        }
        else {
            return (new class_just(subject.elements.pop()));
        }
    }
    lib_structures.set_pop = set_pop;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_forEach(subject, function_) {
        subject.elements.forEach(element => function_(element));
    }
    lib_structures.set_forEach = set_forEach;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_map(collation, subject, transformator) {
        return (set_construct(collation, subject.elements.map(element_from => transformator(element_from))));
    }
    lib_structures.set_map = set_map;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_filter(subject, predicate) {
        return (set_construct((x, y) => false, subject.elements.filter(element => predicate(element))));
    }
    lib_structures.set_filter = set_filter;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_dump(subject) {
        return subject.elements;
    }
    lib_structures.set_dump = set_dump;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_subset(collation, subject, object) {
        return subject.elements.every(element => set_has(collation, object, element));
    }
    lib_structures.set_subset = set_subset;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_superset(collation, subject, object) {
        return object.elements.every(element => set_has(collation, subject, element));
    }
    lib_structures.set_superset = set_superset;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_equals(collation, subject, object) {
        return (set_subset(collation, subject, object)
            &&
                set_superset(collation, subject, object));
    }
    lib_structures.set_equals = set_equals;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_toString(show_element, subject) {
        return ("{" + subject.elements.map(element => show_element(element)).join(",") + "}");
    }
    lib_structures.set_toString = set_toString;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_empty(subject) {
        return (subject.elements.length == 0);
    }
    lib_structures.set_empty = set_empty;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_union(collation, subject, object) {
        let result = set_construct(collation, []);
        subject.elements.forEach(element => set_add(collation, result, element));
        object.elements.forEach(element => set_add(collation, result, element));
        return result;
    }
    lib_structures.set_union = set_union;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_intersection(collation, subject, object) {
        let result = set_construct(collation, []);
        subject.elements.forEach(element => {
            if (set_has(collation, object, element)) {
                set_add(collation, result, element);
            }
        });
        return result;
    }
    lib_structures.set_intersection = set_intersection;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_difference(collation, subject, object) {
        let result = set_construct(collation, []);
        subject.elements.forEach(element => {
            if (!set_has(collation, object, element)) {
                set_add(collation, result, element);
            }
        });
        return result;
    }
    lib_structures.set_difference = set_difference;
    /**
     * @desc [accessor]
     * @author fenris
     */
    function set_symmetric_difference(collation, subject, object) {
        // X $ Y = (X ∪ Y) \ (X ∩ Y)
        return (set_difference(collation, set_union(collation, subject, object), set_intersection(collation, subject, object)));
    }
    lib_structures.set_symmetric_difference = set_symmetric_difference;
    /**
     * @author fenris
     */
    function set_union_all(collation, sets) {
        return (sets.reduce((x, y) => ((x == null) ? y : set_union(collation, x, y)), null));
    }
    lib_structures.set_union_all = set_union_all;
    /**
     * @author fenris
     */
    function set_intersection_all(collation, sets) {
        return (sets.reduce((x, y) => ((x == null) ? y : set_intersection(collation, x, y)), null));
    }
    lib_structures.set_intersection_all = set_intersection_all;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function set_instance(value) {
        return lib_trait.domain_instance({
            "kind": "set"
        }, value);
    }
    lib_structures.set_instance = set_instance;
    /**
     * @author fenris
     */
    lib_trait.attend("collatable", "set", {
        "value": {
            "name": "any"
        }
    }, {
        "collate": ({ "collate_element": collate_element }) => (instance) => (other) => {
            return (lib_structures.set_equals(collate_element, instance, other));
        },
    });
    /**
     * @author fenris
     */
    lib_trait.attend("showable", "set", {
        "value": {
            "name": "any"
        }
    }, {
        "show": () => (instance) => {
            return (lib_structures.set_toString(lib_trait._show, instance));
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_set {
        /**
         * @author fenris
         */
        constructor(elements = [], equality = instance_collate /*<type_element>*/) {
            this.equality = equality;
            this.subject = lib_structures.set_construct(equality, elements);
        }
        /**
         * @author fenris
         */
        static from_subject(equality = instance_collate /*<type_element>*/, subject) {
            let set = new class_set([], equality);
            set.subject = subject;
            return set;
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        size() {
            return lib_structures.set_size(this.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        has(element) {
            return lib_structures.set_has(this.equality, this.subject, element);
        }
        /**
         * @desc [mutator]
         * @author fenris
         */
        add(element) {
            return lib_structures.set_add(this.equality, this.subject, element);
        }
        /**
         * @desc [mutator]
         * @author fenris
         */
        pop() {
            return lib_structures.set_pop(this.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        forEach(function_) {
            return lib_structures.set_forEach(this.subject, function_);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        map(transformator, equality = instance_collate /*<type_element_>*/) {
            return (class_set.from_subject(equality, lib_structures.set_map(equality, this.subject, transformator)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        filter(predicate) {
            return (class_set.from_subject(this.equality, lib_structures.set_filter(this.subject, predicate)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        dump() {
            return lib_structures.set_dump(this.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        subset(set) {
            return lib_structures.set_subset(this.equality, this.subject, set.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        superset(set) {
            return lib_structures.set_superset(this.equality, this.subject, set.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        equals(set) {
            return lib_structures.set_equals(this.equality, this.subject, set.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        toString() {
            return lib_structures.set_toString(instance_show, this.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        empty() {
            return lib_structures.set_empty(this.subject);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        union(set) {
            return (class_set.from_subject(this.equality, lib_structures.set_union(this.equality, this.subject, set.subject)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        intersection(set) {
            return (class_set.from_subject(this.equality, lib_structures.set_intersection(this.equality, this.subject, set.subject)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        difference(set) {
            return (class_set.from_subject(this.equality, lib_structures.set_difference(this.equality, this.subject, set.subject)));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        symmetric_difference(set) {
            return (class_set.from_subject(this.equality, lib_structures.set_symmetric_difference(this.equality, this.subject, set.subject)));
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _collate(set) {
            return lib_structures.set_equals(this.equality, this.subject, set.subject);
        }
        /**
         * @desc [accessor] [implementation]
         * @author fenris
         */
        _show() {
            return lib_structures.set_toString(instance_show, this.subject);
        }
        /**
         * @author fenris
         */
        static union_all(sets) {
            if (sets.length === 0) {
                let message = "empty union";
                // console.warn("--", message);
                return (new class_set());
            }
            else {
                return (class_set.from_subject(sets[0].equality, lib_structures.set_union_all(sets[0].equality, sets.map(set => set.subject))));
            }
        }
        /**
         * @author fenris
         */
        static intersection_all(sets) {
            if (sets.length === 0) {
                let message = "empty intersection is not defined";
                throw (new Error(message));
            }
            else {
                return (class_set.from_subject(sets[0].equality, lib_structures.set_intersection_all(sets[0].equality, sets.map(set => set.subject))));
            }
        }
    }
    lib_structures.class_set = class_set;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function stack_construct() {
        return {
            "elements": []
        };
    }
    lib_structures.stack_construct = stack_construct;
    /**
     * @author fenris
     */
    function stack_size(subject) {
        return subject.elements.length;
    }
    lib_structures.stack_size = stack_size;
    /**
     * @author fenris
     */
    function stack_scan(subject) {
        if (stack_size(subject) == 0) {
            let message = "empty";
            throw (new Error(message));
        }
        else {
            return subject.elements[subject.elements.length - 1];
        }
    }
    lib_structures.stack_scan = stack_scan;
    /**
     * @author fenris
     */
    function stack_take(subject) {
        let element = stack_scan(subject);
        subject.elements.pop();
        return element;
    }
    lib_structures.stack_take = stack_take;
    /**
     * @author fenris
     */
    function stack_give(subject, element) {
        subject.elements.push(element);
    }
    lib_structures.stack_give = stack_give;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.attend("memory", "stack", {
        "subject": {
            "name": "any"
        },
        "element": {
            "name": "any"
        }
    }, {
        "size": () => (subject) => {
            return lib_structures.stack_size(subject);
        },
        "scan": () => (subject) => {
            return lib_structures.stack_scan(subject);
        },
        "take": () => (subject) => {
            let element = lib_structures.stack_take(subject);
            return { "subject": subject, "element": element };
        },
        "give": () => (subject) => (element) => {
            lib_structures.stack_give(subject, element);
            return subject;
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_stack {
        /**
         * @author fenris
         */
        constructor() {
            this.subject = lib_structures.stack_construct();
        }
        /**
         * @override
         * @author fenris
         */
        size() {
            return lib_structures.stack_size(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        scan() {
            return lib_structures.stack_scan(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        take() {
            return lib_structures.stack_take(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        give(element) {
            return lib_structures.stack_give(this.subject, element);
        }
    }
    lib_structures.class_stack = class_stack;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function queue_construct() {
        return {
            "elements": []
        };
    }
    lib_structures.queue_construct = queue_construct;
    /**
     * @author fenris
     */
    function queue_size(subject) {
        return subject.elements.length;
    }
    lib_structures.queue_size = queue_size;
    /**
     * @author fenris
     */
    function queue_scan(subject) {
        if (queue_size(subject) == 0) {
            let message = "empty";
            throw (new Error(message));
        }
        else {
            return subject.elements[0];
        }
    }
    lib_structures.queue_scan = queue_scan;
    /**
     * @author fenris
     */
    function queue_take(subject) {
        let element = queue_scan(subject);
        subject.elements.shift();
        return element;
    }
    lib_structures.queue_take = queue_take;
    /**
     * @author fenris
     */
    function queue_give(subject, element) {
        subject.elements.push(element);
    }
    lib_structures.queue_give = queue_give;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.attend("memory", "queue", {
        "subject": {
            "name": "any"
        },
        "element": {
            "name": "any"
        }
    }, {
        "size": () => (subject) => {
            return lib_structures.queue_size(subject);
        },
        "scan": () => (subject) => {
            return lib_structures.queue_scan(subject);
        },
        "take": () => (subject) => {
            let element = lib_structures.queue_take(subject);
            return { "subject": subject, "element": element };
        },
        "give": () => (subject) => (element) => {
            lib_structures.queue_give(subject, element);
            return subject;
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_queue {
        /**
         * @author fenris
         */
        constructor() {
            this.subject = lib_structures.queue_construct();
        }
        /**
         * @override
         * @author fenris
         */
        size() {
            return lib_structures.queue_size(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        scan() {
            return lib_structures.queue_scan(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        take() {
            return lib_structures.queue_take(this.subject);
        }
        /**
         * @override
         * @author fenris
         */
        give(element) {
            return lib_structures.queue_give(this.subject, element);
        }
    }
    lib_structures.class_queue = class_queue;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function simplemap_construct() {
        return {
            "memory": {}
        };
    }
    lib_structures.simplemap_construct = simplemap_construct;
    /**
     * @author fenris
     */
    function simplemap_has(subject, key) {
        return (key in subject.memory);
    }
    lib_structures.simplemap_has = simplemap_has;
    /**
     * @author fenris
     */
    function simplemap_get(subject, key, fallback = (new class_nothing())) {
        if (key in subject.memory) {
            return subject.memory[key];
        }
        else {
            if (fallback.is_nothing()) {
                let message = "key not found";
                throw (new Error(message));
            }
            else {
                return fallback.cull();
            }
        }
    }
    lib_structures.simplemap_get = simplemap_get;
    /**
     * @author fenris
     */
    function simplemap_set(subject, key, value) {
        subject.memory[key] = value;
    }
    lib_structures.simplemap_set = simplemap_set;
    /**
     * @author fenris
     */
    function simplemap_delete(subject, key) {
        delete subject.memory[key];
    }
    lib_structures.simplemap_delete = simplemap_delete;
    /**
     * @author fenris
     */
    function simplemap_clear(subject) {
        // subject.memory = {};
        Object.keys(subject.memory).forEach(key => { delete subject.memory[key]; });
    }
    lib_structures.simplemap_clear = simplemap_clear;
    /**
     * @author fenris
     */
    function simplemap_forEach(subject, function_) {
        Object.keys(subject.memory).forEach(key => {
            let value = subject.memory[key];
            function_(value, key);
        });
    }
    lib_structures.simplemap_forEach = simplemap_forEach;
    /**
     * @author fenris
     */
    function simplemap_from_object(object) {
        let subject = simplemap_construct();
        Object.keys(object).forEach((key) => {
            let value = object[key];
            subject.memory[key] = value;
        });
        return subject;
    }
    lib_structures.simplemap_from_object = simplemap_from_object;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.attend("map", "simplemap", {
        "subject": {
            "name": "any"
        },
        "key": {
            "name": "string"
        },
        "value": {
            "name": "any"
        }
    }, {
        "has": () => (instance) => (key) => {
            return lib_structures.simplemap_has(instance, key);
        },
        "get": () => (instance) => (key) => {
            let fallback = new class_nothing();
            return lib_structures.simplemap_get(instance, key, fallback);
        },
        "set": () => (instance) => (key) => (value) => {
            lib_structures.simplemap_set(instance, key, value);
            return instance;
        },
        "delete": () => (instance) => (key) => {
            lib_structures.simplemap_delete(instance, key);
            return instance;
        },
        "forEach": () => (instance) => (function_) => {
            lib_structures.simplemap_forEach(instance, function_);
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_simplemap extends lib_structures.class_mapbase {
        /**
         * @author fenris
         * @desc [constructor]
         */
        constructor(subject = lib_structures.simplemap_construct()) {
            super();
            this.subject = subject;
        }
        /**
         * @author fenris
         */
        static make() {
            const subject = lib_structures.simplemap_construct();
            return (new class_simplemap(subject));
        }
        /**
         * @author fenris
         */
        static from_object(object) {
            return (new class_simplemap(lib_structures.simplemap_from_object(object)));
        }
        /**
         * @author fenris
         * @implementation
         */
        has(key) {
            return lib_structures.simplemap_has(this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        get(key, fallback = (new class_nothing())) {
            return lib_structures.simplemap_get(this.subject, key, fallback);
        }
        /**
         * @author fenris
         * @implementation
         */
        set(key, value) {
            return lib_structures.simplemap_set(this.subject, key, value);
        }
        /**
         * @author fenris
         * @implementation
         */
        delete(key) {
            return lib_structures.simplemap_delete(this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        forEach(procedure) {
            return lib_structures.simplemap_forEach(this.subject, procedure);
        }
    }
    lib_structures.class_simplemap = class_simplemap;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function hashmap_construct(hashing) {
        return {
            "core": lib_structures.simplemap_construct(),
            "hashing": hashing,
        };
    }
    lib_structures.hashmap_construct = hashmap_construct;
    /**
     * @author fenris
     */
    function hashmap_has(subject, key) {
        let key_ = subject.hashing(key);
        return lib_structures.simplemap_has(subject.core, key_);
    }
    lib_structures.hashmap_has = hashmap_has;
    /**
     * @author fenris
     */
    function hashmap_get(subject, key, fallback = (new class_nothing())) {
        /*
        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
         */
        let fallback_ = (fallback
            .propagate((value) => (new class_just({ "key": key, "value": value }))));
        let key_ = subject.hashing(key);
        return lib_structures.simplemap_get(subject.core, key_, fallback_).value;
    }
    lib_structures.hashmap_get = hashmap_get;
    /**
     * @author fenris
     */
    function hashmap_set(subject, key, value) {
        let key_ = subject.hashing(key);
        return (lib_structures.simplemap_set(subject.core, key_, { "key": key, "value": value }));
    }
    lib_structures.hashmap_set = hashmap_set;
    /**
     * @author fenris
     */
    function hashmap_delete(subject, key) {
        let key_ = subject.hashing(key);
        return (lib_structures.simplemap_delete(subject.core, key_));
    }
    lib_structures.hashmap_delete = hashmap_delete;
    /**
     * @author fenris
     */
    function hashmap_clear(subject) {
        return lib_structures.simplemap_clear(subject.core);
    }
    lib_structures.hashmap_clear = hashmap_clear;
    /**
     * @author fenris
     */
    function hashmap_forEach(subject, procedure) {
        return (lib_structures.simplemap_forEach(subject.core, ({ "key": key, "value": value }, key_) => {
            procedure(value, key);
        }));
    }
    lib_structures.hashmap_forEach = hashmap_forEach;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.attend("map", "hashmap", {
        "subject": {
            "name": "any"
        },
        "key": {
            "name": "string"
        },
        "value": {
            "name": "any"
        }
    }, {
        "has": () => (instance) => (key) => {
            return lib_structures.hashmap_has(instance, key);
        },
        "get": () => (instance) => (key) => {
            let fallback = new class_nothing();
            return lib_structures.hashmap_get(instance, key, fallback);
        },
        "set": () => (instance) => (key) => (value) => {
            lib_structures.hashmap_set(instance, key, value);
            return instance;
        },
        "delete": () => (instance) => (key) => {
            lib_structures.hashmap_delete(instance, key);
            return instance;
        },
        "forEach": () => (instance) => (procedure) => {
            lib_structures.hashmap_forEach(instance, procedure);
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_hashmap extends lib_structures.class_mapbase {
        /**
         * @author fenris
         * @desc [constructor]
         */
        constructor(hashing = instance_hash) {
            super();
            this.subject = lib_structures.hashmap_construct(hashing);
        }
        /**
         * @author fenris
         * @implementation
         */
        has(key) {
            return lib_structures.hashmap_has(this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        get(key, fallback = (new class_nothing())) {
            return lib_structures.hashmap_get(this.subject, key, fallback);
        }
        /**
         * @author fenris
         * @implementation
         */
        set(key, value) {
            return lib_structures.hashmap_set(this.subject, key, value);
        }
        /**
         * @author fenris
         * @implementation
         */
        delete(key) {
            return lib_structures.hashmap_delete(this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        forEach(procedure) {
            return lib_structures.hashmap_forEach(this.subject, procedure);
        }
    }
    lib_structures.class_hashmap = class_hashmap;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    function collatemap_construct() {
        return {
            "pairs": [],
        };
    }
    lib_structures.collatemap_construct = collatemap_construct;
    /**
     * @author fenris
     */
    function collatemap_has(collation, subject, key) {
        return subject.pairs.some((pair) => collation(key, pair.key));
    }
    lib_structures.collatemap_has = collatemap_has;
    /**
     * @author fenris
     */
    function collatemap_get(collation, subject, key, fallback) {
        let value;
        let found = (subject.pairs
            .some((pair) => {
            if (collation(key, pair.key)) {
                value = pair.value;
                return true;
            }
            else {
                return false;
            }
        }));
        if (found) {
            return value;
        }
        else {
            if (fallback.is_nothing()) {
                let message = "key not found";
                throw (new Error(message));
            }
            else {
                return fallback.cull();
            }
        }
    }
    lib_structures.collatemap_get = collatemap_get;
    /**
     * @author fenris
     */
    function collatemap_set(collation, subject, key, value) {
        let found = (subject.pairs
            .some((pair) => {
            if (collation(key, pair.key)) {
                pair.value = value;
                return true;
            }
            else {
                return false;
            }
        }));
        if (found) {
            // nothing
        }
        else {
            let pair = { "key": key, "value": value };
            subject.pairs.push(pair);
        }
    }
    lib_structures.collatemap_set = collatemap_set;
    /**
     * @author fenris
     */
    function collatemap_delete(collation, subject, key) {
        let index;
        let found = (subject.pairs
            .some((pair, index_) => {
            if (collation(key, pair.key)) {
                index = index_;
                return true;
            }
            else {
                return false;
            }
        }));
        if (found) {
            subject.pairs.splice(index, 1);
        }
        else {
            // do nothing
        }
    }
    lib_structures.collatemap_delete = collatemap_delete;
    /**
     * @author fenris
     */
    function collatemap_forEach(
    // collation : (key1 : type_key, key2 : type_key)=>boolean,
    subject, function_) {
        subject.pairs
            .forEach((pair) => {
            function_(pair.value, pair.key);
        });
    }
    lib_structures.collatemap_forEach = collatemap_forEach;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_trait.attend("map", "collatemap", {
        "subject": {
            "name": "any"
        },
        "key": {
            "name": "string"
        },
        "value": {
            "name": "any"
        }
    }, {
        "has": ({ "collation": collation }) => (instance) => (key) => {
            return lib_structures.collatemap_has(collation, instance, key);
        },
        "get": ({ "collation": collation }) => (instance) => (key) => {
            let fallback = new class_nothing();
            return lib_structures.collatemap_get(collation, instance, key, fallback);
        },
        "set": ({ "collation": collation }) => (instance) => (key) => (value) => {
            lib_structures.collatemap_set(collation, instance, key, value);
            return instance;
        },
        "delete": ({ "collation": collation }) => (instance) => (key) => {
            lib_structures.collatemap_delete(collation, instance, key);
            return instance;
        },
        "forEach": ({ "collation": collation }) => (instance) => (function_) => {
            lib_structures.collatemap_forEach(instance, function_);
        },
    });
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_collatemap extends lib_structures.class_mapbase {
        /**
         * @author fenris
         * @desc [constructor]
         */
        constructor(collation = instance_collate) {
            super();
            this.subject = lib_structures.collatemap_construct();
            this.collation = collation;
        }
        /**
         * @author fenris
         * @implementation
         */
        has(key) {
            return lib_structures.collatemap_has(this.collation, this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        get(key, fallback = (new class_nothing())) {
            return lib_structures.collatemap_get(this.collation, this.subject, key, fallback);
        }
        /**
         * @author fenris
         * @implementation
         */
        set(key, value) {
            return lib_structures.collatemap_set(this.collation, this.subject, key, value);
        }
        /**
         * @author fenris
         * @implementation
         */
        delete(key) {
            return lib_structures.collatemap_delete(this.collation, this.subject, key);
        }
        /**
         * @author fenris
         * @implementation
         */
        forEach(procedure) {
            return lib_structures.collatemap_forEach(this.subject, procedure);
        }
    }
    lib_structures.class_collatemap = class_collatemap;
    /**
     * @author fenris
     * @deprecated
     */
    lib_structures.class_map = class_collatemap;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_graph {
        /**
         * @author fenris
         */
        constructor(equality = null, nodes = [], edges = []) {
            if (equality == null) {
                // equality = ((node1, node2) => lib_trait.call("collatable", "collate", {"kind": "auto"}, {"first": node1, "second": node2}));
                equality = instance_collate /*<type_node>*/;
            }
            this.equality = equality;
            this.nodes = nodes;
            this.edges = edges;
        }
        /**
         * @desc [accessor] [getter]
         * @author fenris
         */
        nodes_get() {
            return this.nodes;
        }
        /**
         * @desc [mutator]
         * @author fenris
         */
        add_node(node) {
            this.nodes.push(node);
        }
        /**
         * @desc [accessor] [getter]
         * @author fenris
         */
        edges_get() {
            return this.edges;
        }
        /**
         * @desc [mutator]
         * @author fenris
         */
        add_edge(edge) {
            this.edges.push(edge);
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        has(node) {
            return this.nodes.some(node_ => this.equality(node, node_));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        outgoing(node) {
            return this.edges.filter(edge => this.equality(edge.from, node));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        incoming(node) {
            return this.edges.filter(edge => this.equality(edge.to, node));
        }
        /**
         * @desc [accessor]
         * @author fenris
         */
        without(pivot) {
            return (new class_graph(this.equality, this.nodes.filter(node => (!this.equality(node, pivot))), this.edges.filter(edge => ((!this.equality(edge.from, pivot)) && (!this.equality(edge.to, pivot))))));
        }
        /**
         * @desc [accessor] returns the topologic sorting of the nodes (if it exists)
         * @author fenris
         */
        topsort() {
            let graph = this;
            if (graph.nodes.length == 0) {
                return [];
            }
            else {
                let pivot;
                let found = graph.nodes.some(node => {
                    let count = graph.edges.filter(edge => this.equality(edge.to, node)).length;
                    if (count == 0) {
                        pivot = node;
                        return true;
                    }
                    else {
                        // console.info("'" + String(node) + "' has " + count.toString() + " incoming edges");
                        return false;
                    }
                });
                if (found) {
                    return [pivot].concat(graph.without(pivot).topsort());
                }
                else {
                    throw (new Error("circular dependencies found"));
                }
            }
        }
        /**
         * @desc [accessor] returns the reduced version of a graph representing an order relation (implicit transitivity)
         * @author fenris
         */
        hasse() {
            return (new class_graph(this.equality, this.nodes, this.edges.filter((edge) => {
                let reachable = (this.outgoing(edge.from)
                    .map((edge_) => edge_.to)
                    .map((node) => this.outgoing(node).map((edge_) => edge_.to))
                    .reduce((x, y) => x.concat(y), []));
                return (!reachable.some(node => this.equality(node, edge.to)));
            })));
        }
        /**
         * @author fenris
         */
        output_dot({ "extract_id": extract_id = null, "extract_label": extract_label = null, "rotate": rotate = false, } = {}) {
            let index = node => {
                let i = -1;
                let found = this.nodes.some((node_, i_) => {
                    if (this.equality(node, node_)) {
                        i = i_;
                        return true;
                    }
                    else {
                        return false;
                    }
                });
                return i;
            };
            if (extract_id == null) {
                // instance_hash
                extract_id = (node => index(node).toFixed(0));
            }
            if (extract_label == null) {
                extract_label = instance_show;
            }
            let nodeid = (node) => {
                return ("node_" + extract_id(node));
            };
            return ({
                "common": {
                    "fontname": "Monospace",
                    "rankdir": (rotate ? "LR" : "TB"),
                },
                "nodes": {
                    "head": {
                        "fontname": "Monospace",
                        "style": "filled",
                        "fillcolor": "0.35+0.6+0.8",
                    },
                    "list": this.nodes_get()
                        .map((node, index) => {
                        return {
                            "id": nodeid(node),
                            "attributes": {
                                "label": extract_label(node),
                            }
                        };
                    }),
                },
                "edges": {
                    "head": {
                        "fontname": "Monospace"
                    },
                    "list": this.edges_get()
                        .map((edge, index) => {
                        return {
                            "id_from": nodeid(edge.from),
                            "id_to": nodeid(edge.to),
                            "attributes": {}
                        };
                    }),
                }
            });
        }
    }
    lib_structures.class_graph = class_graph;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    lib_structures.relation_le = "le";
    lib_structures.relation_ge = "ge";
    lib_structures.relation_lt = "lt";
    lib_structures.relation_gt = "gt";
    lib_structures.relation_eq = "eq";
    /**
     * @author fenris
     */
    function binnode_construct(data) {
        return {
            "data": data,
            "left": null,
            "right": null,
            "depth": 1,
        };
    }
    /**
     * @author fenris
     */
    function binnode_isdef(subject) {
        return (!(subject === null));
    }
    /**
     * @author fenris
     */
    function binnode_child_get(subject, left) {
        if (left) {
            return subject.left;
        }
        else {
            return subject.right;
        }
    }
    /**
     * @author fenris
     */
    function binnode_child_set(subject, left, value) {
        if (left) {
            subject.left = value;
        }
        else {
            subject.right = value;
        }
    }
    /**
     * @author fenris
     * @todo remove later on
     */
    function binnode_update_depth(subject) {
        subject.depth = (1
            +
                Math.max((binnode_isdef(subject.left) ? subject.left.depth : 0), (binnode_isdef(subject.right) ? subject.right.depth : 0)));
    }
    /**
     * @author fenris
     * @todo remove later
     */
    function binnode_depth(subject) {
        return (1
            +
                Math.max((binnode_isdef(subject.left) ? binnode_depth(subject.left) : 0), (binnode_isdef(subject.right) ? binnode_depth(subject.right) : 0)));
    }
    /**
     * @author fenris
     * @todo remove later on
     */
    function binnode_check_depths(subject) {
        return ((binnode_isdef(subject.left) ? binnode_check_depths(subject.left) : true)
            &&
                (binnode_isdef(subject.right) ? binnode_check_depths(subject.right) : true)
            &&
                (subject.depth === binnode_depth(subject)));
    }
    /**
     * @author fenris
     */
    function binnode_imbalance(subject) {
        if (true) {
            return ((binnode_isdef(subject.right) ? subject.right.depth : 0)
                -
                    (binnode_isdef(subject.left) ? subject.left.depth : 0));
        }
        else {
            return ((binnode_isdef(subject.right) ? binnode_depth(subject.right) : 0)
                -
                    (binnode_isdef(subject.left) ? binnode_depth(subject.left) : 0));
        }
    }
    /**
     * @author fenris
     */
    function binnode_insert(compare, subject, data) {
        let node;
        const left = compare(data, subject.data);
        if (binnode_child_get(subject, left) == null) {
            node = binnode_construct(data);
            binnode_child_set(subject, left, node);
        }
        else {
            node = binnode_insert(compare, binnode_child_get(subject, left), data);
        }
        binnode_update_depth(subject);
        return node;
    }
    /**
     * @author fenris
     */
    function binnode_update_parent(subject, parent, child) {
        if (binnode_isdef(parent)) {
            if (parent.left === subject) {
                parent.left = child;
            }
            else if (parent.right === subject) {
                parent.right = child;
            }
            else {
                console.warn("-- updating parent failed :/");
            }
        }
    }
    /**
     * @author fenris
     */
    function binnode_drag(subject, left, parent = null) {
        let child = binnode_child_get(subject, !left);
        let grandchild = binnode_child_get(child, left);
        binnode_child_set(subject, !left, grandchild);
        binnode_child_set(child, left, subject);
        binnode_update_parent(subject, parent, child);
        return child;
    }
    /**
     * @author fenris
     */
    function binnode_rebalance(subject, parent = null) {
        // rebalance children first
        {
            if (binnode_isdef(subject.left)) {
                binnode_rebalance(subject.left, subject);
                if (binnode_isdef(parent))
                    binnode_update_depth(parent);
            }
            if (binnode_isdef(subject.right)) {
                binnode_rebalance(subject.right, subject);
                if (binnode_isdef(parent))
                    binnode_update_depth(parent);
            }
        }
        // now rebalance the current node
        {
            const imbalance = binnode_imbalance(subject);
            if (Math.abs(imbalance) >= 2) {
                const left = (imbalance < 0);
                let child = binnode_child_get(subject, left);
                const imbalance_ = binnode_imbalance(child);
                if (imbalance * imbalance_ < 0) {
                    // sub dragging
                    let child_ = binnode_drag(child, left, subject);
                    binnode_update_depth(binnode_child_get(child_, left));
                    binnode_update_depth(child_);
                }
                // core dragging
                let subject_ = binnode_drag(subject, !left, parent);
                binnode_update_depth(subject);
                binnode_update_depth(subject_);
                if (parent != null)
                    binnode_update_depth(parent);
                return subject_;
            }
            else {
                return subject;
            }
        }
    }
    /**
     * @author fenris
     * @desc see misc/foo.py for some interesting facts explaining the handlers
     * @desc lists all nodes that match the given piece of the data with the given relation
     */
    function binnode_search(compare, subject, data, relation = "eq") {
        const x = subject.data;
        const y = data;
        const situation_le = compare(x, y);
        const situation_ge = compare(y, x);
        const situation_lt = (situation_le && (!situation_ge));
        const situation_gt = ((!situation_le) && situation_ge);
        const situation_eq = (situation_le && situation_ge);
        // recursive call
        const deepen = (left) => {
            const child = binnode_child_get(subject, left);
            if (binnode_isdef(child)) {
                return binnode_search(compare, child, data, relation);
            }
            else {
                return [];
            }
        };
        /*
        handlers that describe how the search is to be executed;
        if "subject", the current node is added to the search results (~ situation)
        if "left", the left subtree is regarded as well
        if "right", the right subtree is regarded as well
         */
        const handlers = {
            "lt": {
                "subject": (situation_lt),
                "left": (true),
                "right": (situation_lt),
            },
            "le": {
                "subject": (situation_le),
                "left": (true),
                "right": (situation_lt),
            },
            "eq": {
                "subject": (situation_eq),
                "left": (!situation_lt),
                "right": (situation_lt),
            },
            "ge": {
                "subject": (situation_ge),
                "left": (!situation_lt),
                "right": (true),
            },
            "gt": {
                "subject": (situation_gt),
                "left": (situation_gt),
                "right": (true),
            },
        };
        if (relation in handlers) {
            let result = [];
            const handler = handlers[relation];
            if (handler.subject) {
                result = result.concat([subject]);
            }
            if (handler.left) {
                result = result.concat(deepen(true));
            }
            if (handler.right) {
                result = result.concat(deepen(false));
            }
            return result;
        }
        else {
            const message = `unhandled relation '${relation}'`;
            throw (new Error(message));
        }
    }
    /**
     * @author fenris
     * @desc returns the first found node, which matches the given data or "null" if not found
     */
    function binnode_find(compare, subject, data) {
        const le = compare(data, subject.data);
        const ge = compare(subject.data, data);
        if (le && ge) {
            return subject;
        }
        else {
            const child = binnode_child_get(subject, le);
            return ((binnode_isdef(child))
                ? binnode_find(compare, child, data)
                : null);
        }
    }
    /**
     * @author fenris
     */
    function binnode_traverse(subject) {
        return ([]
            .concat((binnode_isdef(subject.left) ? binnode_traverse(subject.left) : []))
            .concat([subject.data])
            .concat((binnode_isdef(subject.right) ? binnode_traverse(subject.right) : [])));
    }
    /**
     * @author fenris
     */
    function binnode_show(show_data, subject, depth = 0) {
        const indent = (n, sequence = "  ") => sequence["repeat"](n);
        let str = "";
        {
            str += indent(depth);
            str += show_data(subject.data);
            str += (" " + "[" + binnode_imbalance(subject).toFixed(0) + "]");
            str += (" " + "{" + binnode_depth(subject).toFixed(0) + "/" + subject.depth.toFixed(0) + "}");
            str += "\n";
        }
        if (binnode_isdef(subject.left) || binnode_isdef(subject.right)) {
            // left
            {
                if (binnode_isdef(subject.left)) {
                    str += binnode_show(show_data, subject.left, depth + 1);
                }
                else {
                    str += (indent(depth + 1) + "~" + "\n");
                }
            }
            // right
            {
                if (binnode_isdef(subject.right)) {
                    str += binnode_show(show_data, subject.right, depth + 1);
                }
                else {
                    str += (indent(depth + 1) + "~" + "\n");
                }
            }
        }
        return str;
    }
    /**
     * @author fenris
     */
    function bintree_construct() {
        return {
            "root": null,
        };
    }
    lib_structures.bintree_construct = bintree_construct;
    /**
     * @author fenris
     */
    function bintree_depth(subject) {
        return ((binnode_isdef(subject.root))
            ? binnode_depth(subject.root)
            : 0);
    }
    lib_structures.bintree_depth = bintree_depth;
    /**
     * @author fenris
     * @todo remove later on
     */
    function bintree_check_depths(subject) {
        return ((binnode_isdef(subject.root))
            ? binnode_check_depths(subject.root)
            : true);
    }
    lib_structures.bintree_check_depths = bintree_check_depths;
    /**
     * @author fenris
     */
    function bintree_insert(compare, subject, data, rebalance = true) {
        // basic insertion
        {
            if (binnode_isdef(subject.root)) {
                binnode_insert(compare, subject.root, data);
            }
            else {
                subject.root = binnode_construct(data);
            }
        }
        // rebalancing
        {
            if (rebalance) {
                subject.root = binnode_rebalance(subject.root);
            }
        }
    }
    lib_structures.bintree_insert = bintree_insert;
    /**
     * @author fenris
     */
    function bintree_search(compare, subject, data, relation = undefined) {
        const binnodes = ((binnode_isdef(subject.root))
            ? binnode_search(compare, subject.root, data, relation)
            : []);
        return binnodes.map(binnode => binnode.data);
    }
    lib_structures.bintree_search = bintree_search;
    /**
     * @author fenris
     * @deprecated only used for AVL-Tree-Index atm.
     */
    function bintree_find(compare, subject, data) {
        const binnode = ((binnode_isdef(subject.root))
            ? binnode_find(compare, subject.root, data)
            : null);
        if (binnode == null) {
            const message = "not found";
            throw (new Error(message));
        }
        else {
            return binnode.data;
        }
    }
    lib_structures.bintree_find = bintree_find;
    /**
     * @author fenris
     */
    function bintree_traverse(subject) {
        return ((binnode_isdef(subject.root))
            ? binnode_traverse(subject.root)
            : []);
    }
    lib_structures.bintree_traverse = bintree_traverse;
    /**
     * @author fenris
     */
    function bintree_show(show_data, subject) {
        return ((binnode_isdef(subject.root))
            ? binnode_show(show_data, subject.root)
            : "--");
    }
    lib_structures.bintree_show = bintree_show;
    /**
     * @author fenris
     * @todo tidy up or remove
     */
    function binnode_gather(subject, result = { "nodes": [], "edges": [], "lastid": 0 }) {
        result.lastid += 1;
        const node = { "id": result.lastid, "subject": subject };
        result.nodes.push(node);
        if (binnode_isdef(subject.left)) {
            // result.lastid += 1;
            const node_ = { "id": result.lastid + 1, "subject": subject.left };
            result.edges.push({ "from": node, "to": node_ });
            result = binnode_gather(subject.left, result);
        }
        if (binnode_isdef(subject.right)) {
            // result.lastid += 1;
            const node_ = { "id": result.lastid + 1, "subject": subject.right };
            result.edges.push({ "from": node, "to": node_ });
            result = binnode_gather(subject.right, result);
        }
        return result;
    }
    /**
     * @author fenris
     * @todo tidy up or remove
     */
    function bintree_to_graph(subject) {
        const gathering = binnode_gather(subject.root);
        const graph = new lib_structures.class_graph((x, y) => (x.data == y.data), gathering.nodes, gathering.edges);
        return graph;
    }
    lib_structures.bintree_to_graph = bintree_to_graph;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:structures«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:structures« 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:structures« 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:structures«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_structures;
(function (lib_structures) {
    /**
     * @author fenris
     */
    class class_bintree {
        /**
         * @author fenris
         */
        constructor(compare = instance_compare) {
            this.subject = lib_structures.bintree_construct();
            this.compare = compare;
        }
        /**
         * @author fenris
         */
        depth() {
            return lib_structures.bintree_depth(this.subject);
        }
        /**
         * @author fenris
         */
        insert(data, rebalance = true) {
            return lib_structures.bintree_insert(this.compare, this.subject, data, rebalance);
        }
        /**
         * @author fenris
         */
        delete(data) {
            let message = "not implemented";
            throw (new Error(message));
        }
        /**
         * @author fenris
         */
        search(relation, data) {
            return lib_structures.bintree_search(this.compare, this.subject, data, relation);
        }
        /**
         * @author fenris
         */
        traverse() {
            return lib_structures.bintree_traverse(this.subject);
        }
        /**
         * @author fenris
         */
        show() {
            return lib_structures.bintree_show(instance_show /*<type_data>*/, this.subject);
        }
    }
    lib_structures.class_bintree = class_bintree;
})(lib_structures || (lib_structures = {}));
/*
This file is part of »bacterio-plankton:dot«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:dot« 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:dot« 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:dot«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_dot;
(function (lib_dot) {
    /**
     * @author fenris
     */
    function transform_attributes(attributes, transformations = {}) {
        let attributes_ = {};
        Object.keys(attributes)
            .forEach((name) => {
            if (attributes.hasOwnProperty(name) && (attributes[name] !== null)) {
                const value = attributes[name];
                const transformation = (transformations.hasOwnProperty(name)
                    ? transformations[name]
                    : (x => String(x)));
                const value_ = transformation(value);
                attributes_[name] = value_;
            }
            else {
                // do nothing
            }
        });
        return attributes_;
    }
    /**
     * @author fenris
     */
    function make_entity(head, attributes) {
        const attributes_ = transform_attributes(attributes);
        let str = "";
        str += ("\t" + head + " " + "[" + "\n");
        Object.keys(attributes_)
            .forEach((key) => {
            const value = attributes_[key];
            if (value !== null) {
                str += ("\t\t" + ((key) + "=" + ("\"" + value + "\"")) + "," + "\n");
            }
            else {
                // do nothing
            }
        });
        str += ("\t" + "]" + ";" + "\n");
        return str;
    }
    /**
     * @author fenris
     */
    function generate_graph(definition_graph) {
        return (([make_entity("graph", definition_graph)]
            .concat([]))
            .join(""));
    }
    /**
     * @author fenris
     */
    function generate_nodes(definition_nodeset) {
        return (([make_entity("node", definition_nodeset.head)]
            .concat(definition_nodeset.list
            .map((node) => make_entity(node.id, node.attributes))))
            .join(""));
    }
    /**
     * @author fenris
     */
    function generate_edges(definition_edgeset, directed) {
        const connector = (directed ? "->" : "--");
        return (([make_entity("edge", definition_edgeset.head)]
            .concat(definition_edgeset.list
            .map((edge) => make_entity(edge.id_from + " " + connector + " " + edge.id_to, edge.attributes))))
            .join(""));
    }
    /**
     * @author fenris
     */
    function generate({ "name": name = null, "directed": directed = true, "graph": definition_graph = {}, "nodeset": definition_nodeset, "edgeset": definition_edgeset, } = {}) {
        let output = "";
        output += ((directed ? "digraph" : "graph") + ((name == null) ? "" : (" " + name)) + " " + "{" + "\n");
        output += generate_graph(definition_graph);
        output += `\t\n`;
        output += generate_nodes(definition_nodeset);
        output += `\t\n`;
        output += generate_edges(definition_edgeset, directed);
        output += `}\n`;
        return output;
    }
    lib_dot.generate = generate;
})(lib_dot || (lib_dot = {}));
/*
This file is part of »bacterio-plankton:args«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:args« 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:args« 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:args«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_args;
(function (lib_args) {
    /**
     * @author fenris
     */
    var class_argument = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_argument(_a) {
            var name = _a["name"], _b = _a["type"], type = _b === void 0 ? "string" : _b, _c = _a["default"], default_ = _c === void 0 ? null : _c, _d = _a["info"], info = _d === void 0 ? null : _d, _e = _a["mode"], mode = _e === void 0 ? "replace" : _e, _f = _a["kind"], kind = _f === void 0 ? "positional" : _f, _g = _a["parameters"], parameters = _g === void 0 ? {} : _g, _h = _a["hidden"], hidden = _h === void 0 ? false : _h;
            this.name = name;
            this.type = type;
            this.default_ = default_;
            this.info = info;
            this.mode = mode;
            this.kind = kind;
            this.parameters = parameters;
            this.hidden = hidden;
            if (!this.check()) {
                throw (new Error("invalid argument-setup"));
            }
        }
        /**
         * @author fenris
         */
        class_argument.prototype.check = function () {
            var _this = this;
            return [
                function () { return ((!(_this.kind == "volatile")) || (("indicators_long" in _this.parameters) && (_this.parameters["indicators_long"]["length"] >= 0))); },
            ].every(function (condition) { return condition(); });
        };
        /**
         * @author fenris
         */
        class_argument.prototype.name_get = function () {
            return this.name;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.type_get = function () {
            return this.type;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.default_get = function () {
            return this.default_;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.kind_get = function () {
            return this.kind;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.parameters_get = function () {
            return this.parameters;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.hidden_get = function () {
            return this.hidden;
        };
        /**
         * @author fenris
         */
        class_argument.prototype.toString = function () {
            return "<" + this.name + ">";
        };
        /**
         * @author fenris
         */
        class_argument.prototype.indicator_main = function () {
            if (this.kind == "volatile") {
                return this.parameters["indicators_long"][0];
            }
            else {
                return null;
            }
        };
        /**
         * @author fenris
         */
        class_argument.prototype.pattern_value = function () {
            switch (this.type) {
                case "boolean": {
                    return "false|true";
                    break;
                }
                case "int": {
                    return "[0-9]+";
                    break;
                }
                case "float": {
                    return "\\d*(?:\\.\\d+)?";
                    break;
                }
                case "string": {
                    return "\\S+";
                    break;
                }
                default: {
                    throw (new Error("unhandled type " + this.type));
                    break;
                }
            }
        };
        /**
         * @author fenris
         */
        class_argument.prototype.extract = function (raw) {
            switch (this.type) {
                case "boolean": {
                    return (raw != "false");
                    break;
                }
                case "int": {
                    return parseInt(raw);
                    break;
                }
                case "float": {
                    return parseFloat(raw);
                    break;
                }
                case "string": {
                    return raw;
                    break;
                }
                default: {
                    throw (new Error("unhandled type " + this.type));
                    break;
                }
            }
        };
        /**
         * @author fenris
         */
        class_argument.prototype.assign = function (data, raw) {
            var value = this.extract(raw);
            switch (this.mode) {
                case "replace": {
                    data[this.name] = value;
                    break;
                }
                case "accumulate": {
                    /*
                    if (! (this.name in data)) {
                        data[this.name] = [];
                    }
                     */
                    data[this.name].push(value);
                    break;
                }
                default: {
                    throw (new Error("unhandled mode " + this.mode));
                }
            }
        };
        /**
         * @author fenris
         */
        class_argument.prototype.make = function (data) {
            var value = data[this.name];
            return value.toString();
        };
        /**
         * @author fenris
         */
        class_argument.prototype.generate_help = function () {
            var output = "";
            {
                var line = "";
                line += "\t";
                line += "<" + this.name + ">";
                line += "\n";
                output += line;
            }
            {
                var line = "";
                line += "\t\t";
                var infotext = ((this.info == null) ? "(no info available)" : this.info);
                line += infotext;
                if ((this.type != "boolean") && (this.default_ != null)) {
                    line += "; default: " + this.default_.toString();
                }
                line += "\n";
                output += line;
            }
            return output;
        };
        return class_argument;
    }());
    lib_args.class_argument = class_argument;
})(lib_args || (lib_args = {}));
/*
This file is part of »bacterio-plankton:args«.

Copyright 2016-2018 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>

»bacterio-plankton:args« 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:args« 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:args«. If not, see <http://www.gnu.org/licenses/>.
 */
var lib_args;
(function (lib_args) {
    /**
     * @author fenris
     */
    var settings = {
        "environment": {
            "cli": {
                "symbols": {
                    "delimiter": " ",
                    "prefix": "--",
                    "assignment": "="
                }
            },
            "url": {
                "symbols": {
                    "delimiter": "&",
                    "prefix": "",
                    "assignment": "="
                }
            }
        }
    };
    /**
     * @author fenris
     */
    lib_args.verbosity = 0;
    /**
     * @author fenris
     * @todo check validity
     */
    var class_handler = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_handler(arguments_) {
            this.arguments_ = arguments_;
        }
        /**
         * @author fenris
         */
        class_handler.prototype.filter = function (kind) {
            return this.arguments_.filter(function (argument) { return (argument.kind_get() == kind); });
        };
        /**
         * @author fenris
         */
        class_handler.prototype.read = function (environment, input, data) {
            var _this = this;
            if (data === void 0) { data = {}; }
            switch (environment) {
                case "cli":
                case "url": {
                    // default values
                    {
                        this.arguments_.forEach(function (argument) {
                            data[argument.name_get()] = argument.default_get();
                        });
                    }
                    // preprocessing
                    {
                        // short indicators (lil hacky ...)
                        {
                            if (environment == "cli") {
                                this.filter("volatile").forEach(function (argument) {
                                    // console.info(argument.parameters_get()["indicators_short"].join("|"));
                                    var pattern_from = "";
                                    {
                                        pattern_from += "(?:^|" + settings["environment"][environment]["symbols"]["delimiter"] + ")";
                                        pattern_from += "-" + argument.parameters_get()["indicators_short"].join("|");
                                        pattern_from += "(?:$|" + settings["environment"][environment]["symbols"]["delimiter"] + ")";
                                    }
                                    var pattern_to = "";
                                    {
                                        pattern_to += settings["environment"][environment]["symbols"]["delimiter"];
                                        pattern_to += settings["environment"][environment]["symbols"]["prefix"];
                                        pattern_to += argument.indicator_main();
                                        if (argument.type_get() == "boolean") {
                                            pattern_to += settings["environment"][environment]["symbols"]["delimiter"];
                                        }
                                        else {
                                            pattern_to += settings["environment"][environment]["symbols"]["assignment"];
                                        }
                                    }
                                    var result = input.replace(new RegExp(pattern_from, "g"), pattern_to);
                                    if (lib_args.verbosity >= 3)
                                        console.info("--", "replacing \"" + pattern_from + "\" by \"" + pattern_to + "\" in \"" + input + "\" to \"" + result + "\"");
                                    input = result;
                                });
                            }
                        }
                        if (lib_args.verbosity >= 3)
                            console.info("--", "input is now \"" + input + "\"");
                    }
                    // parsing
                    {
                        var parts = input
                            .split(settings["environment"][environment]["symbols"]["delimiter"])
                            .filter(function (x) { return (x != ""); });
                        var index_expected_1 = 0;
                        parts.forEach(function (part) {
                            if (lib_args.verbosity >= 2)
                                console.info("--", "analyzing \"" + part + "\"");
                            var found = [
                                function () {
                                    if (lib_args.verbosity >= 3)
                                        console.info("--", "probing as volatile");
                                    return (_this.filter("volatile")
                                        .some(function (argument) {
                                        if (lib_args.verbosity >= 4)
                                            console.info("--", "trying as " + argument.toString());
                                        var pattern = "";
                                        {
                                            var pattern_front = "";
                                            pattern_front += "" + settings["environment"][environment]["symbols"]["prefix"];
                                            pattern_front += "(?:" + argument.parameters_get()["indicators_long"].join("|") + ")";
                                            pattern += pattern_front;
                                        }
                                        {
                                            var pattern_back = "";
                                            pattern_back += "" + settings["environment"][environment]["symbols"]["assignment"];
                                            pattern_back += "(" + argument.pattern_value() + ")";
                                            if (argument.type_get() == "boolean") {
                                                pattern_back = "(?:" + pattern_back + ")?";
                                            }
                                            pattern += pattern_back;
                                        }
                                        if (lib_args.verbosity >= 5)
                                            console.info("--", "pattern: \"" + pattern + "\"");
                                        var regexp = new RegExp(pattern);
                                        var matching = regexp.exec(part);
                                        if (lib_args.verbosity >= 5)
                                            console.info("--", "matching:", matching);
                                        if (matching == null) {
                                            return false;
                                        }
                                        else {
                                            argument.assign(data, matching[1]);
                                            return true;
                                        }
                                    }));
                                },
                                function () {
                                    if (lib_args.verbosity >= 3)
                                        console.info("--", "probing as positional");
                                    var positional = _this.filter("positional");
                                    if (index_expected_1 >= positional.length) {
                                        if (lib_args.verbosity >= 4)
                                            console.info("--", "no positional arguments left");
                                        return false;
                                    }
                                    else {
                                        var argument = positional[index_expected_1];
                                        if (lib_args.verbosity >= 4)
                                            console.info("--", "trying as " + argument.toString());
                                        var pattern = "";
                                        {
                                            var pattern_back = "";
                                            pattern_back += "(" + argument.pattern_value() + ")";
                                            pattern += pattern_back;
                                        }
                                        if (lib_args.verbosity >= 5)
                                            console.info("--", "pattern: \"" + pattern + "\"");
                                        var regexp = new RegExp(pattern);
                                        var matching = regexp.exec(part);
                                        if (lib_args.verbosity >= 5)
                                            console.info("--", "matching:", matching);
                                        if (matching == null) {
                                            return false;
                                        }
                                        else {
                                            argument.assign(data, matching[1]);
                                            index_expected_1 += 1;
                                            return true;
                                        }
                                    }
                                },
                            ].some(function (x) { return x(); });
                            if (!found) {
                                if (lib_args.verbosity >= 1)
                                    console.warn("--", "couldn't parse \"" + part + "\"");
                            }
                        });
                    }
                    return data;
                    break;
                }
                default: {
                    throw (new Error("unhandled environment " + environment));
                    break;
                }
            }
        };
        /**
         * @author fenris
         * @todo handle if the data object doesn't have the required field or the type is wrong or sth.
         */
        class_handler.prototype.write = function (environment, data) {
            switch (environment) {
                case "cli":
                case "url": {
                    return (([]
                        .concat(this.filter("volatile").map(function (argument) {
                        var raw = "";
                        {
                            var raw_front = "";
                            raw_front += settings["environment"][environment]["symbols"]["prefix"];
                            raw_front += argument.parameters_get()["indicators_long"][0];
                            raw += raw_front;
                        }
                        {
                            var raw_back = "";
                            raw_back += settings["environment"][environment]["symbols"]["assignment"];
                            raw_back += argument.make(data);
                            raw += raw_back;
                        }
                        return raw;
                    }))
                        .concat(this.filter("positional").map(function (argument) {
                        var raw = "";
                        {
                            var raw_back = "";
                            raw_back += argument.make(data);
                            raw += raw_back;
                        }
                        return raw;
                    })))
                        .join(settings["environment"][environment]["symbols"]["delimiter"]));
                    break;
                }
                default: {
                    throw (new Error("unhandled environment " + environment));
                    break;
                }
            }
        };
        /**
         * @desc manpage-like info-sheet
         * @author fenris
         */
        class_handler.prototype.generate_help = function (_a) {
            var _b = _a["programname"], programname = _b === void 0 ? null : _b, _c = _a["author"], author = _c === void 0 ? null : _c, _d = _a["description"], description = _d === void 0 ? null : _d, _e = _a["executable"], executable = _e === void 0 ? null : _e;
            var environment = "cli";
            var output = "";
            {
                var section = "";
                {
                    var line = "";
                    line += "";
                    line += "INFO";
                    line += "\n";
                    section += line;
                }
                {
                    var line = "";
                    line += "\t";
                    line += programname + " -- " + description;
                    line += "\n";
                    section += line;
                }
                section += "\n";
                output += section;
            }
            {
                if (author != null) {
                    var section = "";
                    {
                        var line = "";
                        line += "";
                        line += "AUTHOR";
                        line += "\n";
                        section += line;
                    }
                    {
                        var line = "";
                        line += "\t";
                        line += "" + author;
                        line += "\n";
                        section += line;
                    }
                    section += "\n";
                    output += section;
                }
            }
            {
                var section = "";
                {
                    var line = "";
                    line += "";
                    line += "SYNOPSIS";
                    line += "\n";
                    section += line;
                }
                {
                    var line = "";
                    line += "\t";
                    line += executable;
                    line += settings["environment"][environment]["symbols"]["delimiter"];
                    line += this.filter("positional")
                        .map(function (argument) {
                        var part = "";
                        part += "<" + argument.name_get() + ">";
                        return part;
                    })
                        .join(settings["environment"][environment]["symbols"]["delimiter"]);
                    line += settings["environment"][environment]["symbols"]["delimiter"];
                    line += this.filter("volatile")
                        .filter(function (argument) { return (!argument.hidden_get()); })
                        .map(function (argument) {
                        var part = "";
                        part += settings["environment"][environment]["symbols"]["prefix"];
                        part += argument.parameters_get()["indicators_long"][0];
                        if (argument.type_get() != "boolean") {
                            part += settings["environment"][environment]["symbols"]["assignment"];
                            part += "<" + argument.name_get() + ">";
                        }
                        part = "[" + part + "]";
                        return part;
                    })
                        .join(settings["environment"][environment]["symbols"]["delimiter"]);
                    line += "\n";
                    section += line;
                }
                section += "\n";
                output += section;
            }
            {
                var section = "";
                {
                    var line = "";
                    line += "";
                    line += "OPTIONS";
                    line += "\n";
                    section += line;
                }
                {
                    section += (this.arguments_
                        .filter(function (argument) { return (!argument.hidden_get()); })
                        .map(function (argument) { return argument.generate_help(); })
                        .join("\n"));
                }
                section += "\n";
                output += section;
            }
            return output;
        };
        return class_handler;
    }());
    lib_args.class_handler = class_handler;
})(lib_args || (lib_args = {}));

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var nm_child_process = require("child_process");
var nm_fs = require("fs");
/**
 * @author fenris
 */
var globalvars = {
    "configuration": {}
};
/**
 * @author fenris
 */
function name_mark(name) {
    return (globalvars.configuration.name_prefix + name);
}
/**
 * @author fenris
 */
function dirwrap(location, core) {
    if (location == null) {
        return core;
    }
    else {
        return "cd ".concat(location.as_string(globalvars.configuration.system), " > /dev/null && ").concat(core, " ; cd - > /dev/null");
    }
}
/**
 * @author fenris
 */
function filepointer_adjust(filepointer, location) {
    return ((location == null) ? filepointer : filepointer.relocate(location));
}
/**
 * @author fenris
 */
function path_augment(path, step, aggregate) {
    if (aggregate === void 0) { aggregate = true; }
    if (aggregate) {
        return path.concat([step]);
    }
    else {
        return [step];
    }
}
/**
 * @author fenris
 */
function path_dump(path) {
    return path.join(globalvars.configuration.name_splitter);
}
/**
 * @author fenris
 */
var class_message = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_message(content, parameters) {
        if (parameters === void 0) { parameters = {}; }
        /**
         * @author fenris
         */
        this.depth = 0;
        this.content = content;
        this.type = lib_object.fetch(parameters, "type", null, 0);
        this.depth = lib_object.fetch(parameters, "depth", 0, 0);
        this.prefix = lib_object.fetch(parameters, "prefix", null, 0);
        this.linebreak = lib_object.fetch(parameters, "linebreak", false, 0);
    }
    /**
     * @author fenris
     */
    class_message.prototype.generate = function (with_type) {
        if (with_type === void 0) { with_type = true; }
        var output = "";
        if (with_type) {
            if (this.type != null) {
                output += ("[" + this.type + "]" + " ");
            }
        }
        if (this.prefix != null) {
            output += ("<" + this.prefix + ">" + " ");
        }
        output += lib_string.repeat("\t", this.depth);
        output += this.content;
        if (this.linebreak) {
            output += "\n";
        }
        return output;
    };
    /**
     * @author fenris
     */
    class_message.prototype.stdout = function () {
        console.log(this.generate(true));
    };
    /**
     * @author fenris
     */
    class_message.prototype.stderr = function () {
        console.error(this.generate(true));
    };
    /**
     * @author fenris
     */
    class_message.prototype.console = function () {
        switch (this.type) {
            case "log": {
                console.log(this.generate(false));
                break;
            }
            case "information": {
                console.info(this.generate(false));
                break;
            }
            case "warning": {
                console.warn(this.generate(false));
                break;
            }
            case "error": {
                console.error(this.generate(false));
                break;
            }
            default: {
                throw (new Error("unhandled type '" + this.type + "'"));
            }
        }
    };
    return class_message;
}());
/**
 * @author fenris
 */
var class_cliout = /** @class */ (function () {
    function class_cliout() {
    }
    /**
     * @author fenris
     */
    class_cliout.stdout = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        console.log(lib_string.repeat("\t", depth) + content);
    };
    /**
     * @author fenris
     */
    class_cliout.stderr = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        console.error(lib_string.repeat("\t", depth) + content);
    };
    /**
     * @author fenris
     */
    class_cliout.log = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        this.stderr("-- " + content, depth);
    };
    /**
     * @author fenris
     */
    class_cliout.info = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        this.stderr(">> " + content, depth);
    };
    /**
     * @author fenris
     */
    class_cliout.warn = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        this.stderr(">> " + content, depth);
    };
    /**
     * @author fenris
     */
    class_cliout.error = function (content, depth) {
        if (depth === void 0) { depth = 0; }
        this.stderr(">> " + content, depth);
    };
    return class_cliout;
}());
/**
 * @author fenris
 */
var lib_gnumake;
(function (lib_gnumake) {
    /**
     * @author fenris
     */
    function macro_command(_a) {
        var _b = _a["interpreter"], interpreter = _b === void 0 ? null : _b, path = _a["path"], _c = _a["args"], args = _c === void 0 ? [] : _c, _d = _a["output"], output = _d === void 0 ? null : _d, _e = _a["system"], system = _e === void 0 ? "linux" : _e;
        switch (system) {
            case "bsd":
            case "linux": {
                var command = path;
                {
                    if (interpreter != null) {
                        command = "".concat(interpreter, " ").concat(command);
                    }
                }
                {
                    var parts_1 = [];
                    args.forEach(function (arg) { return parts_1.push(arg); });
                    command = "".concat(command, " ").concat(parts_1.join(" "));
                }
                {
                    if (output != null) {
                        command = "".concat(command, " > ").concat(output);
                    }
                }
                return command;
                break;
            }
            case "win": {
                var command = "cmd //c";
                {
                    command = "".concat(command, " ").concat(path);
                }
                {
                    if (interpreter != null) {
                        command = "".concat(command, " ").concat(interpreter);
                    }
                }
                {
                    var parts_2 = [];
                    args.forEach(function (arg) { return parts_2.push(arg); });
                    command = "".concat(command, " ").concat(parts_2.join(" "));
                }
                {
                    if (output != null) {
                        command = "".concat(command, " > ").concat(output);
                    }
                }
                return command;
                break;
            }
            default: {
                throw (new Error("unhandled system '".concat(system, "'")));
                break;
            }
        }
    }
    lib_gnumake.macro_command = macro_command;
    /**
     * @author fenris
     */
    var class_rule = /** @class */ (function () {
        /**
         * @author fenris
         */
        // public constructor(name : string, dependencies : Array<string>, actions : Array<string>, phony : boolean = false) {
        function class_rule(parameters) {
            if (parameters === void 0) { parameters = {}; }
            this.name = object_fetch(parameters, "name", null, 2);
            this.dependencies = object_fetch(parameters, "dependencies", [], 0);
            this.actions = object_fetch(parameters, "actions", [], 0);
            this.phony = object_fetch(parameters, "phony", false, 0);
        }
        /**
         * @author fenris
         */
        class_rule.prototype.actions_get = function () {
            return this.actions;
        };
        /**
         * @author fenris
         */
        class_rule.prototype.compile = function (silent) {
            if (silent === void 0) { silent = false; }
            var output = "";
            output += ("".concat(this.name, ": ").concat(this.dependencies.map(function (dependency) { return (" " + dependency); }).join(""), "\n"));
            this.actions.forEach(function (action) { return (output += "\t".concat((silent ? "@ " : "")).concat(action, "\n")); });
            if (this.phony) {
                output += (".PHONY: ".concat(this.name, "\n"));
            }
            return output;
        };
        return class_rule;
    }());
    lib_gnumake.class_rule = class_rule;
    /**
     * @author fenris
     */
    var class_sheet = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_sheet(rules, comments) {
            if (comments === void 0) { comments = []; }
            this.rules = rules;
            this.comments = comments;
        }
        /**
         * @author fenris
         */
        class_sheet.prototype.compile = function (silent) {
            if (silent === void 0) { silent = false; }
            return ([]
                .concat(this.comments.map(function (comment) { return ("# " + comment); }))
                .concat([""])
                .concat(this.rules.map(function (rule) { return rule.compile(silent); }))
                .join("\n"));
        };
        return class_sheet;
    }());
    lib_gnumake.class_sheet = class_sheet;
})(lib_gnumake || (lib_gnumake = {}));
/**
 * @author fenris
 */
var lib_ant;
(function (lib_ant) {
    /**
     * @author fenris
     */
    var class_comment = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_comment(content) {
            this.content = content;
        }
        /**
         * @author fenris
         */
        class_comment.prototype.compile = function () {
            return (new lib_xml.class_node_comment(this.content));
        };
        return class_comment;
    }());
    lib_ant.class_comment = class_comment;
    /**
     * @author fenris
     */
    var class_action = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_action(representation) {
            this.representation = representation;
        }
        /**
         * @author fenris
         */
        class_action.prototype.compile = function () {
            return this.representation;
        };
        /**
         * @author fenris
         */
        class_action.macro_exec = function (_a) {
            var _b = _a["interpreter"], interpreter = _b === void 0 ? null : _b, path = _a["path"], _c = _a["args"], args = _c === void 0 ? [] : _c, _d = _a["output"], output = _d === void 0 ? null : _d, _e = _a["system"], system = _e === void 0 ? "linux" : _e;
            switch (system) {
                case "linux":
                case "bsd": {
                    var attributes = {};
                    var args_ = [];
                    if (interpreter == null) {
                        attributes["executable"] = path;
                    }
                    else {
                        attributes["executable"] = interpreter;
                        args.push(path);
                    }
                    if (output != null) {
                        attributes["output"] = output;
                    }
                    args_ = args_.concat(args);
                    return (new lib_ant.class_action(new lib_xml.class_node_complex("exec", attributes, args_.map(function (arg) { return new lib_xml.class_node_complex("arg", { "value": arg }); }))));
                    break;
                }
                case "win": {
                    var attributes = {};
                    var args_ = [];
                    attributes["executable"] = "cmd";
                    args_.push("/c");
                    if (interpreter == null) {
                    }
                    else {
                        args_.push(interpreter);
                    }
                    args_.push(path);
                    args_ = args_.concat(args);
                    if (output != null) {
                        attributes["output"] = output;
                    }
                    return (new lib_ant.class_action(new lib_xml.class_node_complex("exec", attributes, args_.map(function (arg) { return new lib_xml.class_node_complex("arg", { "value": arg }); }))));
                    break;
                }
                default: {
                    throw (new Error("unhandled system ".concat(system)));
                    break;
                }
            }
        };
        /**
         * @author fenris
         */
        class_action.macro_command = function (cmdparams) { return this.macro_exec(cmdparams); };
        return class_action;
    }());
    lib_ant.class_action = class_action;
    /**
     * @author fenris
     */
    var class_target = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_target(parameters) {
            if (parameters === void 0) { parameters = {}; }
            this.name = object_fetch(parameters, "name", null, 2);
            this.dependencies = object_fetch(parameters, "dependencies", [], 1);
            this.actions = object_fetch(parameters, "actions", [], 0);
        }
        /**
         * @author fenris
         */
        class_target.prototype.actions_get = function () {
            return this.actions;
        };
        /**
         * @author fenris
         */
        class_target.prototype.compile = function () {
            return (new lib_xml.class_node_complex("target", {
                "name": this.name,
                "depends": this.dependencies.join(",")
            }, this.actions.map(function (action) { return action.compile(); })));
        };
        return class_target;
    }());
    lib_ant.class_target = class_target;
    /**
     * @author fenris
     */
    var class_project = /** @class */ (function () {
        /**
         * @author fenris
         */
        function class_project(parameters) {
            if (parameters === void 0) { parameters = {}; }
            this.name = object_fetch(parameters, "name", null, 2);
            this.default_ = object_fetch(parameters, "default", null, 2);
            this.targets = object_fetch(parameters, "targets", [], 1);
            this.comments = object_fetch(parameters, "comments", [], 0);
        }
        /**
         * @author fenris
         */
        class_project.prototype.compile = function () {
            return (new lib_xml.class_node_complex("project", {
                "name": this.name,
                "default": this.default_
            }, ([]
                .concat(this.comments.map(function (comment) { return comment.compile(); }))
                .concat([
                new lib_xml.class_node_complex("property", {
                    "environment": "env"
                }),
            ])
                .concat(this.targets.map(function (target) { return target.compile(); })))));
        };
        return class_project;
    }());
    lib_ant.class_project = class_project;
})(lib_ant || (lib_ant = {}));
var lib_markdown;
(function (lib_markdown) {
    /**
     * @author fenris
     */
    function italic(content) {
        return ("_" + content + "_");
    }
    lib_markdown.italic = italic;
    /**
     * @author fenris
     */
    function bold(content) {
        return ("__" + content + "__");
    }
    lib_markdown.bold = bold;
    /**
     * @author fenris
     */
    function code(content) {
        return ("`" + content + "`");
    }
    lib_markdown.code = code;
    /**
     * @author fenris
     */
    function section(level, title) {
        return ("#".repeat(level) + " " + title + "\n");
    }
    lib_markdown.section = section;
    /**
     * @author fenris
     */
    function paragraph(content) {
        if (content === void 0) { content = ""; }
        return (content + "\n");
    }
    lib_markdown.paragraph = paragraph;
    /**
     * @author fenris
     */
    function listitem(level, content) {
        return ("    ".repeat(level - 1) + "* " + content + "\n");
    }
    lib_markdown.listitem = listitem;
})(lib_markdown || (lib_markdown = {}));
/**
 * @author fenris
 */
var class_action = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_action() {
    }
    return class_action;
}());
/**
 * @author fenris
 */
var class_action_adhoc = /** @class */ (function (_super) {
    __extends(class_action_adhoc, _super);
    /**
     * @author fenris
     */
    function class_action_adhoc() {
        return _super.call(this) || this;
    }
    return class_action_adhoc;
}(class_action));
/**
 * @author fenris
 */
var class_action_exec = /** @class */ (function (_super) {
    __extends(class_action_exec, _super);
    /**
     * @author fenris
     */
    function class_action_exec(_a) {
        var inputs = _a["inputs"], outputs = _a["outputs"], path = _a["path"], interpreter = _a["interpreter"], workdir = _a["workdir"];
        var _this = _super.call(this) || this;
        _this.paths_input = inputs;
        _this.paths_output = outputs;
        _this.path_script = path;
        _this.path_interpreter = interpreter;
        _this.workdir = workdir;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_exec.prototype.compilation = function (output_identifier) {
        switch (output_identifier) {
            case "gnumake": {
                switch (globalvars.configuration.system) {
                    case "linux":
                    case "bsd":
                    case "win": {
                        var command = "";
                        {
                            command = lib_gnumake.macro_command({
                                "interpreter": ((this.path_interpreter != null) ? this.path_interpreter.as_string(globalvars.configuration.system) : null),
                                "path": this.path_script.as_string(globalvars.configuration.system),
                                "args": [
                                    ("'" + this.paths_input.map(function (filepointer) { return filepointer.as_string(globalvars.configuration.system); }).join(",") + "'"),
                                    ("'" + this.paths_output.map(function (filepointer) { return filepointer.as_string(globalvars.configuration.system); }).join(",") + "'"),
                                ],
                                "system": globalvars.configuration.system
                            });
                        }
                        {
                            if (this.workdir != null) {
                                // command = `pushd ${this.workdir.as_string(globalvars.configuration.system)} && ${command} ; popd`
                                command = "cd ".concat(this.workdir.as_string(globalvars.configuration.system), " && ").concat(command, " ; cd -");
                            }
                        }
                        return command;
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                break;
            }
            case "ant": {
                return (lib_ant.class_action.macro_exec({
                    "interpreter": ((this.path_interpreter != null) ? this.path_interpreter.as_string(globalvars.configuration.system) : null),
                    "path": this.path_script.as_string("linux"),
                    "args": [
                        ("'" + this.paths_input.map(function (filepointer) { return filepointer.as_string("linux"); }).join(",") + "'"),
                        ("'" + this.paths_output.map(function (filepointer) { return filepointer.as_string("linux"); }).join(",") + "'"),
                    ],
                    "system": globalvars.configuration.system
                }));
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_exec;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_echo = /** @class */ (function (_super) {
    __extends(class_action_echo, _super);
    /**
     * @author fenris
     */
    function class_action_echo(message) {
        var _this = _super.call(this) || this;
        _this.message = message;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @todo escape message
     * @author fenris
     */
    class_action_echo.prototype.compilation = function (target_identifier) {
        switch (target_identifier) {
            case "gnumake": {
                switch (globalvars.configuration["system"]) {
                    case "linux":
                    case "bsd":
                    case "win": {
                        return (lib_gnumake.macro_command({
                            "path": "echo",
                            "args": ["\"" + this.message + "\""]
                        }));
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                break;
            }
            case "ant": {
                return (new lib_ant.class_action(new lib_xml.class_node_complex("echo", { "message": this.message })));
                break;
            }
            default: {
                throw (new Error("unhandled target '" + target_identifier + "'"));
                break;
            }
        }
    };
    return class_action_echo;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_mkdir = /** @class */ (function (_super) {
    __extends(class_action_mkdir, _super);
    /**
     * @author fenris
     */
    function class_action_mkdir(location) {
        var _this = _super.call(this) || this;
        _this.location = location;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_mkdir.prototype.compilation = function (target_identifier) {
        switch (target_identifier) {
            case "gnumake": {
                var parts = [];
                parts.push("mkdir");
                switch (globalvars.configuration["system"]) {
                    case "linux": {
                        parts.push("--parents");
                        break;
                    }
                    case "bsd": {
                        parts.push("-p");
                        break;
                    }
                    case "win": {
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                parts.push(this.location.as_string(globalvars.configuration["system"]));
                return parts.join(" ");
                // break;
            }
            case "ant": {
                return (new lib_ant.class_action(new lib_xml.class_node_complex("mkdir", { "dir": this.location.as_string("linux") })));
                // break;
            }
            default: {
                throw (new Error("unhandled target '" + target_identifier + "'"));
                // break;
            }
        }
    };
    return class_action_mkdir;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_touch = /** @class */ (function (_super) {
    __extends(class_action_touch, _super);
    /**
     * @author fenris
     */
    function class_action_touch(filepointer) {
        var _this = _super.call(this) || this;
        _this.filepointer = filepointer;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_touch.prototype.compilation = function (target_identifier) {
        switch (target_identifier) {
            case "gnumake": {
                switch (globalvars.configuration["system"]) {
                    case "bsd":
                    case "linux": {
                        var parts = [];
                        parts.push("touch");
                        parts.push(this.filepointer.toString());
                        return parts.join(" ");
                        // break;
                    }
                    case "win": {
                        var parts = [];
                        parts.push("echo.");
                        parts.push(">");
                        parts.push(this.filepointer.toString());
                        return parts.join(" ");
                        // break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        // break;
                    }
                }
                // break;
            }
            case "ant": {
                return (new lib_ant.class_action(new lib_xml.class_node_complex("touch", { "file": this.filepointer.toString() })));
                // break;
            }
            default: {
                throw (new Error("unhandled target '" + target_identifier + "'"));
                break;
            }
        }
    };
    return class_action_touch;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_copy = /** @class */ (function (_super) {
    __extends(class_action_copy, _super);
    /**
     * @author fenris
     */
    function class_action_copy(filepointer_from, filepointer_to, folder) {
        var _this = _super.call(this) || this;
        _this.filepointer_from = filepointer_from;
        _this.filepointer_to = filepointer_to;
        _this.folder = folder;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_copy.prototype.compilation = function (target_identifier) {
        switch (target_identifier) {
            case "gnumake": {
                switch (globalvars.configuration.system) {
                    case "linux": {
                        var args = [];
                        if (this.folder) {
                            args.push("--recursive");
                            args.push("--update");
                            args.push("--verbose");
                            args.push((new lib_path.class_filepointer(this.filepointer_from.location, "*")).as_string(globalvars.configuration.system));
                        }
                        else {
                            args.push(this.filepointer_from.as_string(globalvars.configuration.system));
                        }
                        args.push(this.filepointer_to.as_string(globalvars.configuration.system));
                        return (lib_gnumake.macro_command({
                            "path": "cp",
                            "args": args
                        }));
                        break;
                    }
                    case "bsd": {
                        var args = [];
                        if (this.folder) {
                            args.push("-r");
                            // args.push("-u");
                            args.push("-v");
                            args.push((new lib_path.class_filepointer(this.filepointer_from.location, "*")).as_string(globalvars.configuration.system));
                        }
                        else {
                            args.push(this.filepointer_from.as_string(globalvars.configuration.system));
                        }
                        args.push(this.filepointer_to.as_string(globalvars.configuration.system));
                        return (lib_gnumake.macro_command({
                            "path": "cp",
                            "args": args
                        }));
                        break;
                    }
                    case "win": {
                        throw (new Error("not implemented"));
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                break;
            }
            case "ant": {
                if (!this.folder) {
                    return (new lib_ant.class_action(new lib_xml.class_node_complex("copy", {
                        "file": this.filepointer_from.as_string("linux"),
                        "tofile": this.filepointer_to.as_string("linux")
                    })));
                }
                else {
                    return (new lib_ant.class_action(new lib_xml.class_node_complex("copy", {
                        "todir": this.filepointer_to.as_string("linux")
                    }, [
                        new lib_xml.class_node_complex("fileset", {
                            "dir": this.filepointer_from.as_string("linux")
                        })
                    ])));
                }
                break;
            }
            default: {
                throw (new Error("unhandled target '" + target_identifier + "'"));
                break;
            }
        }
    };
    return class_action_copy;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_move = /** @class */ (function (_super) {
    __extends(class_action_move, _super);
    /**
     * @author fenris
     */
    function class_action_move(_a) {
        var from = _a["from"], to = _a["to"];
        var _this = _super.call(this) || this;
        _this.from = from;
        _this.to = to;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_move.prototype.compilation = function (output_identifier) {
        switch (output_identifier) {
            case "gnumake": {
                switch (globalvars.configuration.system) {
                    case "linux":
                    case "bsd":
                    case "win": {
                        var from = this.from.as_string(globalvars.configuration.system);
                        var to = this.to.as_string(globalvars.configuration.system);
                        var command = "";
                        {
                            command = lib_gnumake.macro_command({
                                "path": "mv",
                                // "args": ["--verbose", from, to],
                                "args": [from, to],
                                "system": globalvars.configuration.system
                            });
                        }
                        {
                            command = "[ \"".concat(from, "\" -ef \"").concat(to, "\" ] || ").concat(command);
                        }
                        return command;
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                break;
            }
            case "ant": {
                return (new lib_ant.class_action(new lib_xml.class_node_complex("move", {
                    "file": this.from.as_string("linux"),
                    "tofile": this.to.as_string("linux")
                })));
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_move;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_concat = /** @class */ (function (_super) {
    __extends(class_action_concat, _super);
    /**
     * @author fenris
     */
    function class_action_concat(sources, destination) {
        var _this = _super.call(this) || this;
        _this.sources = sources;
        _this.destination = destination;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_concat.prototype.compilation = function (output_identifier) {
        switch (output_identifier) {
            case "gnumake": {
                if (this.sources.length > 0) {
                    return (lib_gnumake.macro_command({
                        "path": {
                            "linux": "cat",
                            "bsd": "cat",
                            "win": "type"
                        }[globalvars.configuration.system],
                        "args": this.sources.map(function (source) { return source.as_string(globalvars.configuration.system); }),
                        "output": this.destination.as_string(globalvars.configuration.system)
                    }));
                }
                else {
                    return (lib_gnumake.macro_command({
                        "path": "touch",
                        "args": [this.destination.as_string(globalvars.configuration.system)]
                    }));
                }
                break;
            }
            case "ant": {
                return (new lib_ant.class_action(new lib_xml.class_node_complex("concat", { "destfile": this.destination.as_string("linux") }, [
                    new lib_xml.class_node_complex("filelist", { "dir": "." }, this.sources.map(function (source) {
                        return (new lib_xml.class_node_complex("file", { "name": source.as_string("linux") }));
                    }))
                ])));
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_concat;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_lessc = /** @class */ (function (_super) {
    __extends(class_action_lessc, _super);
    /**
     * @author fenris
     */
    function class_action_lessc(filepointer_from, filepointer_to) {
        var _this = _super.call(this) || this;
        _this.filepointer_from = filepointer_from;
        _this.filepointer_to = filepointer_to;
        return _this;
    }
    /**
     * @override
     * @author fenris
     */
    class_action_lessc.prototype.compilation = function (output_identifier) {
        var args = [];
        args.push(this.filepointer_from.as_string(globalvars.configuration.system));
        var cmdparams = {
            "path": globalvars.configuration.programpaths.lessc,
            "args": args,
            "output": this.filepointer_to.as_string(globalvars.configuration.system)
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_lessc;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_sass = /** @class */ (function (_super) {
    __extends(class_action_sass, _super);
    /**
     * @author fenris
     */
    function class_action_sass(filepointer_from, filepointer_to) {
        var _this = _super.call(this) || this;
        _this.filepointer_from = filepointer_from;
        _this.filepointer_to = filepointer_to;
        return _this;
    }
    /**
     * @override
     * @author fenris
     */
    class_action_sass.prototype.compilation = function (output_identifier) {
        var args = [];
        args.push(this.filepointer_from.as_string(globalvars.configuration.system));
        var cmdparams = {
            "path": globalvars.configuration.programpaths.sass,
            "args": args,
            "output": this.filepointer_to.as_string(globalvars.configuration.system)
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_sass;
}(class_action_adhoc));
/**
 * @author neu3no
 */
var class_action_babel = /** @class */ (function (_super) {
    __extends(class_action_babel, _super);
    /**
     * @author neu3no
     */
    function class_action_babel(sources, destination, presets, plugins, minify) {
        var _this = _super.call(this) || this;
        _this.sources = sources;
        _this.destination = destination;
        _this.presets = presets;
        _this.plugins = plugins;
        _this.minify = minify;
        return _this;
    }
    /**
     * @override
     * @author neu3no,fenris
     * @todo get rid of "/dev/null"
     */
    class_action_babel.prototype.compilation = function (output_identifier) {
        var args = [];
        args.push("--no-babelrc");
        // input
        {
            this.sources.forEach(function (filepointer) { return args.push(filepointer.as_string(globalvars.configuration.system)); });
        }
        // output
        {
            args.push("--out-file");
            args.push((this.destination == null) ? "/dev/null" : this.destination.as_string(globalvars.configuration.system));
        }
        // presets
        {
            if ((this.presets !== null) && (this.presets.length > 0)) {
                args.push("--presets");
                args.push(this.presets.join(","));
            }
        }
        // plugins
        {
            if ((this.plugins != null) && (this.plugins.length > 0)) {
                args.push("--plugins");
                args.push(this.plugins.join(","));
            }
        }
        // minify
        {
            if (this.minify) {
                args.push("--minified");
            }
        }
        // remove comments
        {
            args.push("--no-comments");
        }
        var cmdparams = {
            "path": globalvars.configuration.programpaths.babel,
            "args": args
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled target '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_babel;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_tsc = /** @class */ (function (_super) {
    __extends(class_action_tsc, _super);
    /**
     * @author fenris
     */
    function class_action_tsc(paths_input, path_output, target, allowUnreachableCode, removeComments, declaration) {
        var _this = _super.call(this) || this;
        _this.paths_input = paths_input;
        _this.path_output = path_output;
        _this.target = target;
        _this.allowUnreachableCode = allowUnreachableCode;
        _this.removeComments = removeComments;
        _this.declaration = declaration;
        return _this;
    }
    /**
     * @author fenris
     * @todo handle declarion-path
     */
    class_action_tsc.prototype.compilation = function (output_identifier) {
        var args = [];
        {
            if (this.allowUnreachableCode) {
                args.push("--allowUnreachableCode");
            }
        }
        {
            if (this.removeComments) {
                args.push("--removeComments");
            }
        }
        {
            if (this.target != null) {
                args.push("--target");
                args.push(this.target);
            }
        }
        {
            this.paths_input.forEach(function (filepointer) { return args.push(filepointer.as_string(globalvars.configuration.system)); });
        }
        {
            if (this.declaration != null) {
                args.push("--declaration");
            }
        }
        {
            args.push("--outFile");
            args.push(this.path_output.as_string(globalvars.configuration.system));
        }
        var cmdparams = {
            "path": globalvars.configuration.programpaths.tsc,
            "args": args,
            "system": globalvars.configuration.system
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_tsc;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_php = /** @class */ (function (_super) {
    __extends(class_action_php, _super);
    /**
     * @author fenris
     */
    function class_action_php(filepointers_from, filepointer_to, only_last, args) {
        var _this = _super.call(this) || this;
        _this.filepointers_from = filepointers_from;
        _this.filepointer_to = filepointer_to;
        _this.only_last = only_last;
        _this.args = args;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_php.prototype.compilation = function (output_identifier) {
        var args = [];
        {
            if (this.only_last) {
                this.filepointers_from.slice(-1).forEach(function (filepointer) { return args.push(filepointer.as_string(globalvars.configuration.system)); });
            }
            else {
                this.filepointers_from.forEach(function (filepointer) { return args.push(filepointer.as_string(globalvars.configuration.system)); });
            }
        }
        args = args.concat(this.args);
        var cmdparams = {
            "path": globalvars.configuration.programpaths.php,
            "args": args,
            "system": globalvars.configuration.system,
            "output": this.filepointer_to.as_string(globalvars.configuration.system)
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled output '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_php;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_gitpull = /** @class */ (function (_super) {
    __extends(class_action_gitpull, _super);
    /**
     * @author fenris
     */
    function class_action_gitpull(url) {
        var _this = _super.call(this) || this;
        _this.url = url;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @todo escape message
     * @author fenris
     */
    class_action_gitpull.prototype.compilation = function (target_identifier) {
        switch (target_identifier) {
            case "gnumake": {
                switch (globalvars.configuration["system"]) {
                    case "linux":
                    case "win": {
                        var parts = [];
                        parts.push("git pull");
                        parts.push(this.url);
                        return parts.join(" ");
                        break;
                    }
                    default: {
                        throw (new Error("not implemented"));
                        break;
                    }
                }
                break;
            }
            /*
            case "ant": {
                return (
                    new lib_ant.class_action(
                        new lib_xml.class_node_complex(
                            "echo",
                            {"message": this.message}
                        )
                    )
                );
                break;
            }
             */
            default: {
                throw (new Error("unhandled target '" + target_identifier + "'"));
                break;
            }
        }
    };
    return class_action_gitpull;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_schwamm = /** @class */ (function (_super) {
    __extends(class_action_schwamm, _super);
    /**
     * @author fenris
     */
    function class_action_schwamm(includes, inputs, save, dump_group, dump_filepointer) {
        if (dump_group === void 0) { dump_group = null; }
        if (dump_filepointer === void 0) { dump_filepointer = null; }
        var _this = _super.call(this) || this;
        _this.includes = includes;
        _this.inputs = inputs;
        _this.save = save;
        _this.dump_group = dump_group;
        _this.dump_filepointer = dump_filepointer;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_schwamm.prototype.compilation = function (target_identifier) {
        var args = [];
        this.includes.forEach(function (include) {
            args.push("--include=".concat(include.as_string(globalvars.configuration["system"])));
        });
        lib_object.to_array(this.inputs).forEach(function (pair) {
            pair.value.forEach(function (member) {
                var filepointer = member;
                args.push("--input=".concat(filepointer.as_string(globalvars.configuration["system"]), ":").concat(pair.key));
            });
        });
        // args.push(`--file=${this.output.as_string(globalvars.configuration["system"])}`);
        // args.push(`--dir=${((this.dir != null) ? this.dir : this.output.location).as_string("system")}`);
        var target;
        if (this.save != undefined) {
            args.push("--output=native");
            target = this.save;
        }
        else if (this.dump_group != null) {
            args.push("--output=dump:".concat(this.dump_group));
            target = this.dump_filepointer;
        }
        else {
            console.warn("output missing?");
        }
        var cmdparams = {
            "path": globalvars.configuration.programpaths.schwamm,
            "args": args,
            "output": target.as_string(globalvars.configuration["system"])
        };
        switch (target_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled target '".concat(target_identifier, "'")));
                break;
            }
        }
    };
    return class_action_schwamm;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_schwamm_create = /** @class */ (function (_super) {
    __extends(class_action_schwamm_create, _super);
    /**
     * @author fenris
     */
    function class_action_schwamm_create(includes, adhoc, output, dir) {
        var _this = _super.call(this) || this;
        _this.includes = includes;
        _this.adhoc = adhoc;
        _this.output = output;
        _this.dir = dir;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_schwamm_create.prototype.compilation = function (target_identifier) {
        var _this = this;
        var args = [];
        this.includes.forEach(function (include) {
            args.push("--include=".concat(include.as_string(globalvars.configuration["system"])));
        });
        Object.keys(this.adhoc).forEach(function (group) {
            _this.adhoc[group].forEach(function (member) {
                var filepointer = member;
                args.push("--input=".concat(filepointer.as_string(globalvars.configuration["system"]), ":").concat(group));
            });
        });
        args.push("--output=native");
        // args.push(`--file=${this.output.as_string(globalvars.configuration["system"])}`);
        // args.push(`--dir=${((this.dir != null) ? this.dir : this.output.location).as_string("linux")}`);
        var cmdparams = {
            "path": "schwamm",
            "args": args,
            "output": this.output.as_string(globalvars.configuration["system"])
        };
        switch (target_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled target '".concat(target_identifier, "'")));
                break;
            }
        }
    };
    return class_action_schwamm_create;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_schwamm_apply = /** @class */ (function (_super) {
    __extends(class_action_schwamm_apply, _super);
    /**
     * @author fenris
     */
    function class_action_schwamm_apply(path, output_group, output_filepointer) {
        var _this = _super.call(this) || this;
        _this.path = path;
        _this.output_group = output_group;
        _this.output_filepointer = output_filepointer;
        return _this;
    }
    /**
     * @desc for defining directly how the action is to be converted into a target-piece
     * @author fenris
     */
    class_action_schwamm_apply.prototype.compilation = function (target_identifier) {
        var args = [];
        args.push("--include=".concat(this.path.as_string(globalvars.configuration["system"])));
        args.push("--output=dump:".concat(this.output_group));
        var filepointer = lib_path.filepointer_read(globalvars.configuration["path"]).foo(this.output_filepointer);
        var cmdparams = {
            "path": "schwamm",
            "args": args,
            "output": filepointer.as_string(globalvars.configuration["system"])
        };
        switch (target_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled target '".concat(target_identifier, "'")));
                break;
            }
        }
    };
    return class_action_schwamm_apply;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_action_locmerge = /** @class */ (function (_super) {
    __extends(class_action_locmerge, _super);
    /**
     * @author fenris
     */
    function class_action_locmerge(inputs, output) {
        var _this = _super.call(this) || this;
        _this.inputs = inputs;
        _this.output = output;
        return _this;
    }
    /**
     * @override
     * @author fenris
     */
    class_action_locmerge.prototype.compilation = function (output_identifier) {
        var args = [];
        // inputs
        {
            this.inputs.forEach(function (input) { return args.push(input.as_string(globalvars.configuration.system)); });
        }
        var cmdparams = {
            "path": globalvars.configuration.programpaths.locmerge,
            "args": args,
            "output": this.output.as_string(globalvars.configuration.system)
        };
        switch (output_identifier) {
            case "gnumake": {
                return lib_gnumake.macro_command(cmdparams);
                break;
            }
            case "ant": {
                return lib_ant.class_action.macro_command(cmdparams);
                break;
            }
            default: {
                throw (new Error("unhandled target '".concat(output_identifier, "'")));
                break;
            }
        }
    };
    return class_action_locmerge;
}(class_action_adhoc));
/**
 * @author fenris
 */
var class_task = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_task(_a) {
        var _b = _a["name"], name = _b === void 0 ? null : _b, _c = _a["active"], active = _c === void 0 ? true : _c, _d = _a["sub"], sub = _d === void 0 ? [] : _d, _e = _a["inputs"], _inputs = _e === void 0 ? [] : _e, _f = _a["outputs"], _outputs = _f === void 0 ? [] : _f, _g = _a["actions"], _actions = _g === void 0 ? [] : _g;
        this.name = name;
        this.sub = sub;
        this.active = active;
        this._inputs = _inputs;
        this._outputs = _outputs;
        this._actions = _actions;
        this.context = null;
    }
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_task.prototype.name_get = function () {
        return this.name;
    };
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_task.prototype.sub_get = function () {
        return this.sub;
    };
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_task.prototype.active_get = function () {
        return this.active;
    };
    /**
     * @desc [mutator] [setter]
     * @author fenris
     */
    class_task.prototype.context_set = function (context) {
        this.context = context;
    };
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_task.prototype.context_get = function () {
        return this.context;
    };
    /**
     * @returns the subgraph of all active tasks
     * @author fenris
     */
    class_task.prototype.clean = function (root) {
        if (root === void 0) { root = true; }
        if (root && (!this.active)) {
            throw (new Error("cant't clean inactive root"));
        }
        else {
            this.sub = this.sub.filter(function (task_) { return task_.active; });
            this.sub.forEach(function (task_) { return task_.clean(false); });
        }
    };
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_task.prototype.values = function (raw) {
        return null;
    };
    /**
     * @desc [accessor] [getter] a list of paths which represent input-files of the task
     * @author fenris
     */
    class_task.prototype.inputs = function () {
        return this._inputs;
    };
    /**
     * @desc [accessor] [getter] a list of paths which represent output-files of the task
     * @author fenris
     */
    class_task.prototype.outputs = function () {
        return this._outputs;
    };
    /**
     * @desc [accessor] [getter] generates all actions which have to be executed in order to fulfil the task
     * @author fenris
     */
    class_task.prototype.actions = function () {
        return this._actions;
    };
    return class_task;
}());
/**
 * @author fenris
 */
var class_taskparameter = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_taskparameter(_a) {
        var name = _a["name"], extraction = _a["extraction"], _b = _a["shape"], shape = _b === void 0 ? lib_shape.make({ "name": "any" }) : _b, _c = _a["default"], default_ = _c === void 0 ? new class_nothing() : _c, _d = _a["description"], description = _d === void 0 ? null : _d;
        this.name = name;
        this.extraction = extraction;
        this.shape = shape;
        this.default_ = default_;
        this.description = description;
    }
    /**
     * @author fenris
     */
    class_taskparameter.input_single = function (_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["description"], description = _c === void 0 ? "the list of paths to the input files" : _c, _d = _b["default"], default_ = _d === void 0 ? new class_nothing() : _d;
        return (new class_taskparameter({
            "name": "input",
            "extraction": function (raw) { return ((typeof (raw) === "string")
                ? lib_path.filepointer_read(raw)
                : (function () { throw new Error("wrong type for 'input'"); })()); },
            "shape": lib_shape.make({
                "name": "string"
            }),
            "default": default_,
            "description": description
        }));
    };
    /**
     * @author fenris
     */
    class_taskparameter.input_list = function (_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["description"], description = _c === void 0 ? "the list of paths to the input files" : _c, _d = _b["default"], default_ = _d === void 0 ? new class_nothing() : _d;
        return (new class_taskparameter({
            "name": "inputs",
            "extraction": function (raw) { return raw.map(function (x) { return lib_path.filepointer_read(x); }); },
            "shape": lib_shape.make({
                "name": "array",
                "parameters": {
                    "shape_element": {
                        "name": "string"
                    }
                }
            }),
            "default": default_,
            "description": description
        }));
    };
    /**
     * @author fenris
     */
    class_taskparameter.input_schwamm = function (_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["description"], description = _c === void 0 ? "parameters for a schwamm which holds a list of files in a group" : _c, _d = _b["default"], default_ = _d === void 0 ? new class_nothing() : _d;
        return (new class_taskparameter({
            "name": "input_from_schwamm",
            "extraction": function (raw) {
                if (raw == null) {
                    return [];
                }
                else {
                    var regexp_1;
                    if (raw["filter"] != null) {
                        regexp_1 = new RegExp(raw["filter"]);
                    }
                    else {
                        regexp_1 = null;
                    }
                    var command = "".concat(globalvars.configuration.programpaths.schwamm, " --include=").concat(raw["path"], " --output=list:").concat(raw["group"]);
                    var result = nm_child_process.execSync(command);
                    var output = result.toString();
                    var paths = output.split("\n");
                    return (paths
                        .filter(function (path) { return (path.trim().length > 0); })
                        .filter(function (path) { return ((regexp_1 == null) ? true : regexp_1.test(path)); })
                        .map(function (path) { return lib_path.filepointer_read(path); }));
                }
            },
            "shape": lib_shape.make({
                "name": "object",
                "parameters": {
                    "fields": [
                        {
                            "name": "path",
                            "shape": {
                                "name": "string"
                            }
                        },
                        {
                            "name": "group",
                            "shape": {
                                "name": "string"
                            }
                        },
                        {
                            "name": "filter",
                            "shape": {
                                "name": "string",
                                "parameters": {
                                    "soft": true
                                }
                            }
                        },
                    ]
                }
            }),
            "default": default_,
            "description": description
        }));
    };
    /**
     * @author fenris
     */
    class_taskparameter.output_single = function (_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["description"], description = _c === void 0 ? "the list of paths to the input files" : _c;
        return (new class_taskparameter({
            "name": "output",
            "extraction": function (raw) { return lib_path.filepointer_read(raw); },
            "shape": lib_shape.make({
                "name": "string"
            }),
            "default": new class_nothing(),
            "description": description
        }));
    };
    /**
     * @author fenris
     */
    class_taskparameter.output_list = function (_a) {
        var _b = _a === void 0 ? {} : _a, _c = _b["description"], description = _c === void 0 ? "the list of paths to the output files" : _c, _d = _b["default"], default_ = _d === void 0 ? new class_just([]) : _d;
        return (new class_taskparameter({
            "name": "outputs",
            "extraction": function (raw) { return raw.map(function (x) { return lib_path.filepointer_read(x); }); },
            "shape": lib_shape.make({
                "name": "array",
                "parameters": {
                    "shape_element": {
                        "name": "string"
                    }
                }
            }),
            "default": default_,
            "description": description
        }));
    };
    return class_taskparameter;
}());
/**
 * @desc defines how a raw task is converted into a real task and provides information to the user how to form the raw task
 * @author fenris
 */
var class_tasktemplate = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_tasktemplate(_a) {
        var _b = _a["description"], description = _b === void 0 ? null : _b, _c = _a["parameters"], parameters = _c === void 0 ? [] : _c, factory = _a["factory"];
        this.description = description;
        this.parameters = parameters;
        this.factory = factory;
    }
    /**
     * @desc converts raw parameter values to real ones
     * @author fenris
     */
    class_tasktemplate.prototype.convert = function (object_raw, task_name) {
        var _this = this;
        var object_ready = {};
        this.parameters.forEach(function (parameter) {
            var value_raw;
            if ((object_raw != null) && (parameter.name in object_raw)) {
                value_raw = object_raw[parameter.name];
            }
            else {
                if (parameter.default_.is_nothing()) {
                    throw (new Error("mandatory parameter '".concat(parameter.name, "' is missing in task '").concat(task_name, "'")));
                }
                else {
                    value_raw = parameter.default_.cull();
                }
            }
            var messages = [];
            if (messages.length > 0) {
                var message = "";
                message += "given value '".concat(instance_show(value_raw), "'");
                message += " for parameter '".concat(parameter.name, "'");
                message += " with shape '".concat(instance_show(parameter.shape), "'");
                message += " is malformed";
                message += ": ".concat(messages.join("; "));
                throw (new Error(message));
            }
            else {
                var value_ready = parameter.extraction(value_raw);
                object_ready[parameter.name] = value_ready;
            }
        });
        if (object_raw != null) {
            Object.keys(object_raw)
                .filter(function (key) { return (!_this.parameters.some(function (parameter) { return (parameter.name == key); })); })
                .forEach(function (key) {
                (new class_message("unrecognized parameter '".concat(key, "' in task '").concat(task_name, "'"), { "type": "warning", "prefix": "koralle" })).stderr();
            });
        }
        return object_ready;
    };
    /**
     * @desc does the actual conversion to a real task
     * @author fenris
     */
    class_tasktemplate.prototype.create = function (rawtask, nameprefix) {
        if (nameprefix === void 0) { nameprefix = null; }
        var data = this.convert(rawtask.parameters, rawtask.name);
        var stuff = this.factory(data, rawtask);
        var name = "";
        {
            name = ((rawtask.name != undefined) ? rawtask.name : lib_string.generate("task_"));
            if (nameprefix != null) {
                name = "".concat(nameprefix, "-").concat(name);
            }
        }
        var active;
        {
            active = ((rawtask.active != undefined) ? rawtask.active : true);
        }
        var sub = [];
        {
            if (rawtask["sub"] != undefined) {
                sub = sub.concat(rawtask.sub.map(function (rawtask_) { return class_tasktemplate.create(rawtask_, nameprefix); }));
            }
            if (stuff["sub"] != undefined) {
                sub = sub.concat(stuff["sub"]);
            }
        }
        var inputs = (stuff["inputs"] || []);
        var outputs = (stuff["outputs"] || []);
        var actions = (stuff["actions"] || []);
        return (new class_task({
            "name": name,
            "active": active,
            "sub": sub,
            "inputs": inputs,
            "outputs": outputs,
            "actions": actions
        }));
    };
    /**
     * @desc adds a tasktemplate to the pool
     * @author fenris
     */
    class_tasktemplate.register = function (id, tasktemplate) {
        this.pool[id] = tasktemplate;
    };
    /**
     * @desc retrieves a registered tasktemplate from the pool
     * @author fenris
     */
    class_tasktemplate.get = function (id) {
        if (id in this.pool) {
            return this.pool[id];
        }
        else {
            throw (new Error("no task registered with name '".concat(id, "'")));
        }
    };
    /**
     * @desc searches for the corresponding registered tasktemplate and creates a real task
     * @author fenris
     */
    class_tasktemplate.create = function (rawtask, nameprefix) {
        if (nameprefix === void 0) { nameprefix = null; }
        var tasktemplate = this.get(rawtask.type);
        return tasktemplate.create(rawtask, nameprefix);
    };
    /**
     * @desc returns an overview over all available tasktemplates in markdown format
     * @author fenris
     */
    class_tasktemplate.list = function () {
        var str = "";
        lib_object.to_array(this.pool).forEach(function (_a) {
            var id = _a["key"], tasktemplate = _a["value"];
            str += lib_markdown.section(2, "Task '" + lib_markdown.code(id) + "'");
            {
                str += lib_markdown.section(3, "Description");
                str += lib_markdown.paragraph(((tasktemplate.description != null) ? tasktemplate.description : "(missing)"));
                str += lib_markdown.paragraph();
            }
            {
                str += lib_markdown.section(3, "Parameters");
                tasktemplate.parameters.forEach(function (taskparameter) {
                    var str_ = "";
                    {
                        // name
                        {
                            str_ += lib_markdown.paragraph(lib_markdown.code(taskparameter.name));
                        }
                        // shape
                        {
                            str_ += lib_markdown.listitem(2, "type: " + lib_markdown.italic(lib_shape.show(taskparameter.shape)));
                        }
                        // kind
                        {
                            var content = void 0;
                            if (taskparameter.default_.is_nothing()) {
                                content = "mandatory";
                            }
                            else {
                                content = ("optional (default: " + lib_markdown.code(instance_show(taskparameter.default_.cull())) + ")");
                            }
                            str_ += lib_markdown.listitem(2, "kind: " + content);
                        }
                        // description
                        {
                            str_ += lib_markdown.listitem(2, "description: " + ((taskparameter.description == null) ? "(missing)" : taskparameter.description));
                        }
                    }
                    str += lib_markdown.listitem(1, str_);
                });
                str += lib_markdown.paragraph();
            }
        });
        return str;
    };
    /**
     * @desc holds the registered tasktemplates
     * @author fenris
     */
    class_tasktemplate.pool = {};
    return class_tasktemplate;
}());
/**
 * @desc a tasktemplate for tasks which have a single input and a single output
 * @author fenris
 */
var class_tasktemplate_transductor = /** @class */ (function (_super) {
    __extends(class_tasktemplate_transductor, _super);
    /**
     * @author fenris
     */
    function class_tasktemplate_transductor(_a) {
        var _b = _a["description"], description = _b === void 0 ? null : _b, _c = _a["parameters_additional"], parameters_additional = _c === void 0 ? [] : _c, factory = _a["factory"];
        return _super.call(this, {
            "description": description,
            "parameters": ([
                class_taskparameter.input_single(),
                class_taskparameter.output_single(),
            ]
                .concat(parameters_additional)),
            "factory": factory
        }) || this;
    }
    return class_tasktemplate_transductor;
}(class_tasktemplate));
/**
 * @desc a tasktemplate for tasks which have a list of inputs and a single output
 * @author fenris
 */
var class_tasktemplate_aggregator = /** @class */ (function (_super) {
    __extends(class_tasktemplate_aggregator, _super);
    /**
     * @author fenris
     */
    function class_tasktemplate_aggregator(_a) {
        var _b = _a["description"], description = _b === void 0 ? null : _b, _c = _a["parameters_additional"], parameters_additional = _c === void 0 ? [] : _c, factory = _a["factory"];
        return _super.call(this, {
            "description": description,
            "parameters": ([
                class_taskparameter.input_single({ "default": new class_just("DUMMY") }),
                class_taskparameter.input_list({ "default": new class_just([]) }),
                class_taskparameter.input_schwamm({ "default": new class_just(null) }),
                class_taskparameter.output_single(),
            ]
                .concat(parameters_additional)),
            "factory": factory
        }) || this;
    }
    /**
     * @author fenris
     */
    class_tasktemplate_aggregator.inputs_all = function (data) {
        return ([]
            .concat((data["input"].as_string().includes("DUMMY"))
            ? []
            : [data["input"]])
            .concat(data["inputs"])
            .concat((data["input_from_schwamm"] == null)
            ? []
            : data["input_from_schwamm"]));
    };
    return class_tasktemplate_aggregator;
}(class_tasktemplate));
/**
 * @author fenris
 */
class_tasktemplate.register("group", new class_tasktemplate({
    "description": "does nothing but executing the sub tasks",
    "factory": function (data) {
        return {};
    }
}));
/**
 * @author fenris
 */
function task_each_generate_output(input_raw, output_description, index) {
    switch (output_description.kind) {
        case "replace": {
            var regexp = new RegExp(output_description.parameters["from"]);
            // let filter : boolean = ((output_description.parameters["filter"] == undefined) || (output_description.parameters["from"] == true));
            var execute = true;
            if (execute) {
                var output_raw = input_raw.replace(regexp, output_description.parameters["to"]);
                if (input_raw == output_raw) {
                    (new class_message("replacement for input '".concat(input_raw, "' resulted in the same string"), {
                        "type": "warning",
                        "prefix": "koralle"
                    })).stderr();
                }
                return output_raw;
            }
            else {
                return null;
            }
            break;
        }
        case "enumerate": {
            var folder = (output_description["parameters"]["folder"] || "build/");
            var prefix = (output_description["parameters"]["prefix"] || "output_");
            var suffix = (output_description["parameters"]["suffix"]);
            var output_raw = (folder + "/" + prefix + index.toString() + ((suffix == null) ? "" : ("." + suffix)));
            return output_raw;
            break;
        }
        default: {
            throw (new Error("unhandled kind '".concat(output_description.kind, "'")));
            break;
        }
    }
}
/**
 * @author fenris
 */
class_tasktemplate.register("each", new class_tasktemplate({
    "description": "executes a specific task for a list of inputs",
    "parameters": [
        class_taskparameter.input_list({ "default": new class_just([]) }),
        class_taskparameter.input_schwamm({ "default": new class_just(null) }),
        new class_taskparameter({
            "name": "element_type",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "string" }),
            "default": new class_nothing(),
            "description": "the type of the inner task"
        }),
        new class_taskparameter({
            "name": "element_parameters",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "any" }),
            "default": new class_just({}),
            "description": "the parameters for the inner task"
        }),
        new class_taskparameter({
            "name": "output_description",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "any" }),
            "default": new class_nothing(),
            "description": "how the output paths are generated"
        }),
    ],
    "factory": function (data, rawtask) {
        var inputs = data["inputs"].concat(data["input_from_schwamm"]);
        return {
            "sub": inputs.map(function (input, index) {
                var input_raw = input.as_string();
                var output_raw = task_each_generate_output(input_raw, data["output_description"], index);
                if (output_raw == null) {
                    return null;
                }
                else {
                    return (class_tasktemplate.create({
                        "name": index.toString(),
                        "type": data["element_type"],
                        "parameters": lib_object.patched(data["element_parameters"], {
                            "input": input_raw,
                            "output": output_raw
                        })
                    }, rawtask["name"]));
                }
            }).filter(function (x) { return (x != null); })
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("empty", new class_tasktemplate({
    "description": "creates an empty output file",
    "parameters": [
        new class_taskparameter({
            "name": "output",
            "extraction": function (raw) { return lib_path.filepointer_read(raw); },
            "shape": lib_shape.make({ "name": "string" }),
            "default": new class_nothing(),
            "description": "the path to the output file"
        })
    ],
    "factory": function (data) {
        return {
            "outputs": [data["output"]],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_touch(data["output"]),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("copy", new class_tasktemplate_transductor({
    "description": "copies a file",
    "parameters_additional": [
        new class_taskparameter({
            "name": "folder",
            "extraction": (function (raw) { return raw; }),
            "default": new class_just(false)
        }),
    ],
    "factory": function (data) {
        return {
            "inputs": [data["input"]],
            "outputs": /*[data["output"]]*/ [],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_copy(data["input"], data["output"], data["folder"]),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("concat", new class_tasktemplate_aggregator({
    "description": "concatenates a list of files",
    "factory": function (data) {
        var inputs = class_tasktemplate_aggregator.inputs_all(data);
        var output = data["output"];
        return {
            "inputs": inputs,
            "outputs": [output],
            "actions": [
                new class_action_mkdir(output.location),
                new class_action_concat(inputs, output),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("typescript", new class_tasktemplate_aggregator({
    "description": "compiles a list of typescript input files to a single javascript output file",
    "parameters_additional": [
        new class_taskparameter({
            "name": "declaration",
            "extraction": function (raw) { return ((raw == null) ? null : lib_path.filepointer_read(raw)); },
            "shape": lib_shape.make({ "name": "string", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the path of the file in which to write the declaration; if not set, no declaration-script will be created"
        }),
        new class_taskparameter({
            "name": "target",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "string", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the tsc-switch 'target'; value NULL means 'don't specify'"
        }),
        new class_taskparameter({
            "name": "allowUnreachableCode",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "boolean", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the tsc-switch 'allowUnreachableCode'; value NULL means 'don't specify'"
        }),
        new class_taskparameter({
            "name": "removeComments",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "boolean", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the tsc-switch 'removeComments'; value NULL means 'don't specify'"
        }),
    ],
    "factory": function (data) {
        var inputs = class_tasktemplate_aggregator.inputs_all(data);
        var outputs = [data["output"]];
        var actions = [
            new class_action_mkdir(data["output"].location),
            new class_action_tsc(inputs, data["output"], data["target"], data["allowUnreachableCode"], data["removeComments"], data["declaration"]),
        ];
        if (data["declaration"] != null) {
            outputs = outputs.concat([
                data["declaration"],
            ]);
            actions = actions.concat([
                new class_action_mkdir(data["declaration"].location),
                new class_action_move({
                    "from": new lib_path.class_filepointer(data["output"].location, data["output"].filename.replace(new RegExp(".js$"), ".d.ts")),
                    "to": data["declaration"]
                }),
            ]);
        }
        return {
            "inputs": inputs,
            "outputs": outputs,
            "actions": actions
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("lesscss", new class_tasktemplate_aggregator({
    "description": "compiles a list of lesscss input files to a single css output file",
    "factory": function (data) {
        var filepointer_temp = new lib_path.class_filepointer(lib_path.location_read(globalvars.configuration["tempfolder"]), "_.less");
        return {
            "inputs": class_tasktemplate_aggregator.inputs_all(data),
            "outputs": data["outputs"],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_concat(class_tasktemplate_aggregator.inputs_all(data), filepointer_temp),
                new class_action_lessc(filepointer_temp, data["output"]),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("sass", new class_tasktemplate_aggregator({
    "description": "compiles a list of sass input files to a single css output file",
    "factory": function (data) {
        var filepointer_temp = new lib_path.class_filepointer(lib_path.location_read(globalvars.configuration["tempfolder"]), "_.scss");
        return {
            "inputs": class_tasktemplate_aggregator.inputs_all(data),
            "outputs": data["outputs"],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_concat(class_tasktemplate_aggregator.inputs_all(data), filepointer_temp),
                new class_action_sass(filepointer_temp, data["output"]),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("php", new class_tasktemplate_aggregator({
    "description": "compiles a list of php input files to a single output file",
    "parameters_additional": [
        new class_taskparameter({
            "name": "only_last",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "boolean" }),
            "default": new class_just(false),
            "description": "only compile the last file in the list and use the others as dependencies"
        }),
        new class_taskparameter({
            "name": "args",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "array", "parameters": { "shape_element": { "name": "string" } } }),
            "default": new class_just([]),
            "description": "arguments passed to the php call"
        }),
    ],
    "factory": function (data) {
        var inputs = class_tasktemplate_aggregator.inputs_all(data);
        return {
            "inputs": inputs,
            "outputs": data["outputs"],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_php(inputs, data["output"], data["only_last"], data["args"]),
            ]
        };
    }
}));
/**
 * @author fenris,neu3no
 */
class_tasktemplate.register("babel", new class_tasktemplate_aggregator({
    "description": "executes the babel transpiler",
    "parameters_additional": [
        new class_taskparameter({
            "name": "preset",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "string" }),
            "default": new class_just(null),
            "description": "[deprecated] single plugin; use 'presets' parameter instead (you can still use this parameter; its value is added to the plugin list)"
        }),
        new class_taskparameter({
            "name": "presets",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "array", "parameters": { "shape_element": { "name": "string" } } }),
            "default": new class_just([]),
            "description": "a list of presets to use"
        }),
        new class_taskparameter({
            "name": "plugins",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "array", "parameters": { "shape_element": { "name": "string" } } }),
            "default": new class_just([]),
            "description": "a list of plugins to use"
        }),
        new class_taskparameter({
            "name": "minify",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "boolean" }),
            "default": new class_just(false),
            "description": "whether to pass the 'minify' argument to the babel command"
        }),
        new class_taskparameter({
            "name": "simulate",
            "extraction": (function (raw) { return raw; }),
            "shape": lib_shape.make({ "name": "boolean" }),
            "default": new class_just(false),
            "description": "whether to discard the output of babel and instead simply concatenate the input files"
        }),
    ],
    "factory": function (data) {
        var inputs = class_tasktemplate_aggregator.inputs_all(data);
        var actions = [
            new class_action_mkdir(data["output"].location),
            new class_action_babel(inputs, (data["simulate"] ? null : data["output"]), data["presets"].concat((data["preset"] == null) ? [] : [data["preset"]]), data["plugins"], data["minify"]),
        ];
        if (data["simulate"]) {
            actions.push(new class_action_concat(inputs, data["output"]));
        }
        return {
            "inputs": inputs,
            "outputs": [data["output"]],
            "actions": actions
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("schwamm", new class_tasktemplate({
    "description": null,
    "parameters": [
        new class_taskparameter({
            "name": "includes",
            "extraction": function (raw) { return raw.map(function (path) { return lib_path.filepointer_read(path); }); },
            "shape": lib_shape.make({
                "name": "array",
                "parameters": {
                    "shape_element": {
                        "name": "string"
                    }
                }
            }),
            "default": new class_just([])
        }),
        new class_taskparameter({
            "name": "inputs",
            "extraction": function (raw) { return lib_object.map(raw, function (paths) { return paths.map(function (path) { return lib_path.filepointer_read(path); }); }); },
            "shape": lib_shape.make({
                "name": "map",
                "parameters": {
                    "shape_key": {
                        "name": "string"
                    },
                    "shape_value": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "string"
                            }
                        }
                    }
                }
            }),
            "default": new class_just({})
        }),
        new class_taskparameter({
            "name": "output",
            "extraction": function (raw) {
                var result = {};
                if ("save" in raw) {
                    result["save"] = lib_path.filepointer_read(raw["save"]);
                }
                if ("dump" in raw) {
                    result["dump"] = lib_object.map(raw["dump"], function (path) { return lib_path.filepointer_read(path); });
                }
                return result;
            },
            "shape": lib_shape.make({
                "name": "object",
                "parameters": {
                    "fields": [
                        {
                            "name": "save",
                            "shape": {
                                "name": "string",
                                "parameters": {
                                    "soft": true
                                }
                            }
                        },
                        {
                            "name": "dump",
                            "shape": {
                                "name": "map",
                                "parameters": {
                                    "shape_key": {
                                        "name": "string"
                                    },
                                    "shape_value": {
                                        "name": "string"
                                    },
                                    "soft": true
                                }
                            }
                        }
                    ]
                }
            })
        }),
    ],
    "factory": function (data) {
        var inputs = [];
        var outputs = [];
        var actions = [];
        // includes
        {
            inputs = inputs.concat(data["includes"]);
        }
        // inputs
        {
            inputs = inputs.concat(lib_object.values(data["inputs"]).reduce(function (x, y) { return x.concat(y); }, []));
        }
        // output
        {
            if ("save" in data["output"]) {
                outputs = outputs.concat(data["output"]["save"]);
                actions = actions.concat([
                    new class_action_mkdir(data["output"]["save"].location),
                    new class_action_schwamm(data["includes"], data["inputs"], data["output"]["save"]),
                ]);
            }
            if ("dump" in data["output"]) {
                outputs = outputs.concat(lib_object.values(data["output"]["dump"]).reduce(function (x, y) { return x.concat(y); }, []));
                actions = actions.concat(lib_object.to_array(data["output"]["dump"])
                    .map(function (_a) {
                    var key = _a["key"], value = _a["value"];
                    return [
                        new class_action_mkdir(value.location),
                        new class_action_schwamm(data["includes"], data["inputs"], undefined, key, value),
                    ];
                })
                    .reduce(function (x, y) { return x.concat(y); }, []));
            }
        }
        return {
            "inputs": inputs,
            "outputs": outputs,
            "actions": actions
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("schwamm-create", new class_tasktemplate({
    "description": null,
    "parameters": [
        new class_taskparameter({
            "name": "includes",
            "extraction": function (raw) { return raw.map(function (path) { return lib_path.filepointer_read(path); }); },
            "shape": lib_shape.make({
                "name": "array",
                "parameters": {
                    "shape_element": {
                        "name": "string"
                    }
                }
            }),
            "default": new class_just([])
        }),
        new class_taskparameter({
            "name": "adhoc",
            "extraction": function (raw) { return lib_object.map(raw, function (paths) { return paths.map(function (path) { return lib_path.filepointer_read(path); }); }); },
            "shape": lib_shape.make({
                "name": "map",
                "parameters": {
                    "shape_key": {
                        "name": "string"
                    },
                    "shape_value": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "string"
                            }
                        }
                    }
                }
            }),
            "default": new class_just({})
        }),
        class_taskparameter.output_single(),
    ],
    "factory": function (data) {
        var inputs = [];
        var outputs = [];
        var actions = [];
        // includes
        {
            inputs = inputs.concat(data["includes"]);
        }
        // adhoc
        {
            inputs = inputs.concat(lib_object.values(data["adhoc"]).reduce(function (x, y) { return x.concat(y); }, []));
        }
        // output
        {
            outputs = outputs.concat([data["output"]]);
            actions = actions.concat([
                new class_action_mkdir(data["output"].location),
                new class_action_schwamm(data["includes"], data["adhoc"], data["output"]),
            ]);
        }
        return {
            "inputs": inputs,
            "outputs": outputs,
            "actions": actions
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("schwamm-apply", new class_tasktemplate({
    "description": null,
    "parameters": [
        new class_taskparameter({
            "name": "path",
            "extraction": function (raw) { return lib_path.filepointer_read(raw); },
            "shape": lib_shape.make({ "name": "string" })
        }),
        new class_taskparameter({
            "name": "outputs",
            "extraction": function (raw) { return lib_object.map(raw, function (paths) { return paths.map(function (path) { return lib_path.filepointer_read(path); }); }); },
            "shape": lib_shape.make({
                "name": "map",
                "parameters": {
                    "shape_key": {
                        "name": "string"
                    },
                    "shape_value": {
                        "name": "array",
                        "parameters": {
                            "shape_element": {
                                "name": "string"
                            }
                        }
                    }
                }
            }),
            "default": new class_just({})
        }),
    ],
    "factory": function (data) {
        var inputs = [];
        var outputs = [];
        var actions = [];
        // path
        {
            inputs = inputs.concat([data["path"]]);
        }
        // output
        {
            outputs = outputs.concat(lib_object.values(data["output"]).reduce(function (x, y) { return x.concat(y); }, []));
            actions = actions.concat(lib_object.to_array(data["output"])
                .map(function (_a) {
                var key = _a["key"], value = _a["value"];
                return [
                    new class_action_mkdir(value.location),
                    new class_action_schwamm([data["path"]], {}, undefined, key, value),
                ];
            })
                .reduce(function (x, y) { return x.concat(y); }, []));
        }
        return {
            "inputs": inputs,
            "outputs": outputs,
            "actions": actions
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("locmerge", new class_tasktemplate_aggregator({
    "description": "executes a locmerge command",
    "parameters_additional": [],
    "factory": function (data) {
        var inputs = class_tasktemplate_aggregator.inputs_all(data);
        return {
            "inputs": inputs,
            "outputs": [],
            "actions": [
                new class_action_mkdir(data["output"].location),
                new class_action_locmerge(inputs, data["output"]),
            ]
        };
    }
}));
/**
 * @author fenris
 */
class_tasktemplate.register("script", new class_tasktemplate({
    "description": "executes an external script",
    "parameters": [
        class_taskparameter.input_list({ "default": new class_just([]) }),
        class_taskparameter.output_list({ "default": new class_just([]) }),
        new class_taskparameter({
            "name": "path",
            "extraction": function (raw) { return lib_path.filepointer_read(raw); },
            "shape": lib_shape.make({ "name": "string" }),
            "default": new class_nothing(),
            "description": "the path to the script"
        }),
        new class_taskparameter({
            "name": "interpreter",
            "extraction": function (raw) { return ((raw == null) ? null : lib_path.filepointer_read(raw)); },
            "shape": lib_shape.make({ "name": "string", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the path to the interpreter to use; if value NULL is given, it is assumed that the script is self-executable"
        }),
        new class_taskparameter({
            "name": "workdir",
            "extraction": function (raw) { return ((raw == null) ? null : lib_path.location_read(raw)); },
            "shape": lib_shape.make({ "name": "string", "parameters": { "soft": true } }),
            "default": new class_just(null),
            "description": "the path to the directory from where the script shall be executed; if value NULL is given, the workdir is the location of the script"
        }),
    ],
    "factory": function (data) {
        return {
            "inputs": data["inputs"],
            "outputs": data["outputs"],
            "actions": ([]
                .concat(data["outputs"].map(function (output) { return new class_action_mkdir(output.location); }))
                .concat([
                new class_action_exec({
                    "inputs": data["inputs"],
                    "outputs": data["outputs"],
                    "path": data["path"],
                    "interpreter": data["interpreter"],
                    "workdir": data["workdir"]
                }),
            ]))
        };
    }
}));
/**
 * @author fenris
 */
var class_target = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_target() {
    }
    return class_target;
}());
/**
 * @author fenris
 */
var class_target_regular = /** @class */ (function (_super) {
    __extends(class_target_regular, _super);
    /**
     * @author fenris
     */
    function class_target_regular(identifier) {
        var _this = _super.call(this) || this;
        _this.identifier = identifier;
        return _this;
    }
    /**
     * @author fenris
     */
    class_target_regular.prototype.compile_action = function (action) {
        if (action instanceof class_action_adhoc) {
            var action_ = (action);
            return (action_.compilation(this.identifier));
        }
        else {
            throw (new Error("no delegation for action '" + JSON.stringify(action) + "'"));
        }
    };
    return class_target_regular;
}(class_target));
/**
 * @author fenris
 */
var class_target_ant = /** @class */ (function (_super) {
    __extends(class_target_ant, _super);
    /**
     * @author fenris
     */
    function class_target_ant() {
        return _super.call(this, "ant") || this;
    }
    /**
     * @override
     * @author fenris
     */
    class_target_ant.prototype.tempfolder = function () {
        switch (globalvars.configuration.system) {
            case "linux": {
                return "/tmp/";
                break;
            }
            case "bsd": {
                return "/tmp/";
                break;
            }
            case "win": {
                return "${env.TEMP}\\";
                break;
            }
            default: {
                throw (new Error("invalid system '".concat(globalvars.configuration.system, "'")));
                break;
            }
        }
    };
    /**
     * @author fenris
     */
    class_target_ant.prototype.compile_task = function (_a) {
        var _this = this;
        var task = _a["task"], _b = _a["path"], path = _b === void 0 ? [] : _b, _c = _a["context"], context = _c === void 0 ? null : _c;
        var aggregate = false;
        var path_ = path_augment(path, task.name_get(), aggregate);
        var targets_core = [
            new lib_ant.class_target({
                "name": path_dump(path_),
                "dependencies": (task.sub_get()
                    .filter(function (task_) { return task_.active_get(); })
                    .map(function (task_) { return path_dump(path_augment(path_, task_.name_get(), aggregate)); })),
                "actions": ([]
                    .concat((context == null)
                    ? ([]
                        .concat(task.actions()
                        // .concat([new class_action_echo(task.name_get())])
                        .map(function (action) { return _this.compile_action(action); })))
                    : [
                        new lib_ant.class_action(new lib_xml.class_node_complex("ant", {
                            "antfile": "${ant.file}",
                            "dir": context.as_string("linux"),
                            "target": path_dump(path_augment(path_, name_mark("inner"))),
                            "inheritAll": String(true),
                            "inheritRefs": String(true)
                        })),
                    ]))
            })
        ];
        var targets_sub = []
            .concat((context == null)
            ? []
            : [
                new lib_ant.class_target({
                    "name": path_dump(path_augment(path_, name_mark("inner"))),
                    "dependencies": [],
                    "actions": (task.actions()
                        // .concat([new class_action_echo(task.name_get())])
                        .map(function (action) { return _this.compile_action(action); }))
                })
            ])
            .concat(task.sub_get()
            .map(function (task_) { return _this.compile_task({
            "task": task_,
            "path": path_,
            "context": ((context == null) ? task_.context_get() : ((task_.context_get() == null) ? context : context.relocate(task_.context_get())))
        }); })
            .reduce(function (x, y) { return x.concat(y); }, []));
        return [].concat(targets_core).concat(targets_sub);
    };
    /**
     * @author fenris
     */
    class_target_ant.prototype.compile_project = function (project) {
        var comments = [
            "Project \"".concat(project.name_get(), "\""),
            "This build script was generated by Koralle ".concat(globalvars.configuration.version),
        ].map(function (x) { return new lib_ant.class_comment(x); });
        var targets = this.compile_task({ "task": project.roottask_get() });
        return (new lib_ant.class_project({
            "name": project.name_get(),
            "default": name_mark("root"),
            "comments": comments,
            "targets": targets
        }));
    };
    /**
     * @override
     * @author fenris
     */
    class_target_ant.prototype.compile_project_string = function (project) {
        return this.compile_project(project).compile().compile();
    };
    /**
     * @override
     * @author fenris
     */
    class_target_ant.prototype.execute = function (filepointer, workdir) {
        if (workdir === void 0) { workdir = "."; }
        return (function (resolve, reject) {
            var cp = nm_child_process.spawn("ant", [
                "-f",
                "".concat(filepointer.as_string(globalvars.configuration.system)),
            ], {});
            cp.stdout.on("data", [function (x) { return x.toString(); }, function (x) { return x.slice(0, x.length - 1); }, console.log].reduce(lib_call.compose));
            cp.stderr.on("data", [function (x) { return x.toString(); }, function (x) { return x.slice(0, x.length - 1); }, console.error].reduce(lib_call.compose));
            cp.on("error", function (error) { return reject(new class_error("subprocess not finish successfully", [error])); });
            cp.on("close", function (code) {
                if (code == 0) {
                    resolve(undefined);
                }
                else {
                    reject(new Error("unknown error while subprocess execution"));
                }
            });
        });
    };
    return class_target_ant;
}(class_target_regular));
/**
 * @author fenris
 */
var class_target_gnumake = /** @class */ (function (_super) {
    __extends(class_target_gnumake, _super);
    /**
     * @author fenris
     */
    function class_target_gnumake() {
        return _super.call(this, "gnumake") || this;
    }
    /**
     * @override
     * @author fenris
     */
    class_target_gnumake.prototype.tempfolder = function () {
        switch (globalvars.configuration.system) {
            case "linux": {
                return "/tmp/";
                break;
            }
            case "bsd": {
                return "/tmp/";
                break;
            }
            case "win": {
                return "%TEMP%\\";
                break;
            }
            default: {
                throw (new Error("invalid system '".concat(globalvars.configuration.system, "'")));
                break;
            }
        }
    };
    /**
     * @author fenris
     */
    class_target_gnumake.prototype.compile_task = function (_a) {
        var _this = this;
        var task = _a["task"], _b = _a["branch"], branch = _b === void 0 ? [] : _b, _c = _a["depth"], depth = _c === void 0 ? 0 : _c, _d = _a["context"], context = _d === void 0 ? null : _d, _e = _a["prefix"], prefix = _e === void 0 ? null : _e;
        var log_begin = true;
        var log_end = false;
        var aggregate = false;
        var branch_ = path_augment(branch, task.name_get(), aggregate);
        var logging_begin = new class_action_echo((new class_message(path_dump(branch_), { "type": "log", "depth": depth, "prefix": prefix })).generate());
        var logging_end = new class_action_echo((new class_message("✔", { "type": "log", "depth": depth, "prefix": prefix })).generate());
        var rules_core = [];
        {
            // meta rule
            rules_core.push(new lib_gnumake.class_rule({
                "name": path_dump(branch_),
                "dependencies": ([]
                    .concat(log_begin
                    ? [path_dump(path_augment(branch_, name_mark("logging"), true))]
                    : [])
                    .concat(task.sub_get()
                    .filter(function (task_) { return task_.active_get(); })
                    .map(function (task_) { return path_dump(path_augment(branch_, task_.name_get(), aggregate)); }))
                    .concat(task.outputs().map(function (filepointer) { return filepointer_adjust(filepointer, context).as_string(globalvars.configuration.system); }))),
                "actions": ([]
                    .concat((task.outputs().length == 0)
                    ? task.actions().map(function (action) { return dirwrap(context, _this.compile_action(action)); })
                    : [])
                    .concat((log_end
                    ? [logging_end]
                    : [])
                    .map(function (action) { return _this.compile_action(action); }))),
                "phony": true
            }));
            // logging
            if (log_begin) {
                rules_core.push(new lib_gnumake.class_rule({
                    "name": path_dump(path_augment(branch_, name_mark("logging"), true)),
                    "actions": [logging_begin].map(function (action) { return _this.compile_action(action); }),
                    "phony": true
                }));
            }
            // actual rule
            if (task.outputs().length > 0) {
                rules_core.push(new lib_gnumake.class_rule({
                    "name": task.outputs().map(function (filepointer) { return filepointer_adjust(filepointer, context).as_string(globalvars.configuration.system); }).join(" "),
                    "dependencies": task.inputs().map(function (filepointer) { return filepointer_adjust(filepointer, context).as_string(globalvars.configuration.system); }),
                    "actions": task.actions().map(function (action) { return _this.compile_action(action); }).map(function (x) { return dirwrap(context, x); }),
                    "phony": false
                }));
            }
        }
        var rules_sub = [];
        {
            rules_sub = task.sub_get()
                .map(function (task_) { return _this.compile_task({
                "task": task_,
                "branch": branch_,
                "depth": depth + 1,
                "context": ((context == null) ? task_.context_get() : ((task_.context_get() == null) ? context : context.relocate(task_.context_get()))),
                "prefix": prefix
            }); })
                .reduce(function (x, y) { return x.concat(y); }, []);
        }
        return [].concat(rules_core).concat(rules_sub);
    };
    /**
     * @author fenris
     */
    class_target_gnumake.prototype.compile_project = function (project) {
        var comments = [
            "Project \"".concat(project.name_get(), "\""),
            "This makefile was generated by Koralle ".concat(globalvars.configuration.version),
        ].map(function (x) { return x; });
        var rules = this.compile_task({
            "task": project.roottask_get(),
            "prefix": project.name_get()
        });
        return (new lib_gnumake.class_sheet(rules, comments));
    };
    /**
     * @override
     * @author fenris
     */
    class_target_gnumake.prototype.compile_project_string = function (project) {
        return (this.compile_project(project).compile(true));
    };
    /**
     * @override
     * @author fenris
     */
    class_target_gnumake.prototype.execute = function (filepointer, workdir) {
        if (workdir === void 0) { workdir = process.cwd(); }
        return (function (resolve, reject) {
            var cp = nm_child_process.spawn("make", [
                // `--directory=${workdir}`,
                // `--file=${filepointer.as_string(globalvars.configuration.system)}`,
                "-f",
                "".concat(filepointer.as_string(globalvars.configuration.system)),
            ], {});
            cp.stdout.on("data", [function (x) { return x.toString(); }, function (x) { return x.slice(0, x.length - 1); }, console.log].reduce(lib_call.compose));
            cp.stderr.on("data", [function (x) { return x.toString(); }, function (x) { return x.slice(0, x.length - 1); }, console.error].reduce(lib_call.compose));
            cp.on("error", function (error) { return reject(new class_error("subprocess not finish successfully", [error])); });
            cp.on("close", function (code) {
                if (code == 0) {
                    resolve(undefined);
                }
                else {
                    reject(new Error("unknown error while subprocess execution"));
                }
            });
        });
    };
    return class_target_gnumake;
}(class_target_regular));
/**
 * scans a project and its subprojects and constructs a dependency-graph (more precise: a depth first spanning tree)
 * @param {type_depgraphnode} node the filepointer to the project.json, relative to the current working directory
 * @author fenris
 */
function scan(node, graph, depth) {
    if (graph === void 0) { graph = null; }
    if (depth === void 0) { depth = 0; }
    log("exploring node " + JSON.stringify(node), 4);
    var make_node = function (filepointer, rawproject) {
        if (rawproject === void 0) { rawproject = null; }
        var node = {
            "filepointer": filepointer,
            "rawproject": rawproject
        };
        return node;
    };
    if (graph == null) {
        log("creating new graph", 4);
        graph = new lib_structures.class_graph(function (x, y) { return (x.filepointer.toString() == y.filepointer.toString()); });
        graph.add_node(node);
    }
    return (function (resolve, reject) {
        log("reading description file", 4);
        lib_file.read_json(node.filepointer.toString())(function (data) {
            log("got data", 4);
            node.rawproject = data;
            lib_call.executor_chain(graph, lib_object.fetch(lib_object.fetch(node, "rawproject", {}, 0), "dependencies", [], 0).map(function (path) { return function (graph_) { return function (resolve_, reject_) {
                log("looking through path " + path, 4);
                var node_ = make_node(node.filepointer.foo(lib_path.filepointer_read(path)));
                var edge = { "from": node_, "to": node };
                graph_.add_edge(edge);
                if (graph.has(node_)) {
                    // return lib_call.executor_resolve<class_graph<type_depgraphnode>, Error>(graph);
                    resolve_(graph_);
                }
                else {
                    graph.add_node(node_);
                    scan(node_, graph_, depth + 1)(function (graph_) {
                        resolve_(graph_ /*.hasse()*/);
                    }, reject_);
                }
            }; }; }))(resolve, reject);
        }, function (reason) {
            reject(reason);
        });
    });
}
/**
 * @author fenris
 */
var class_project = /** @class */ (function () {
    /**
     * @author fenris
     */
    function class_project(name, version, task) {
        this.name = name;
        this.version = version;
        this.task = task;
        this.graph = null;
    }
    /**
     * @author fenris
     */
    class_project.prototype.name_get = function () {
        return this.name;
    };
    /**
     * @author fenris
     */
    class_project.prototype.roottask_get = function () {
        return this.task;
    };
    /**
     * @desc [mutator] [setter]
     * @author fenris
     */
    class_project.prototype.graph_set = function (graph) {
        this.graph = graph;
    };
    /**
     * @desc [accessor] [getter]
     * @author fenris
     */
    class_project.prototype.graph_get = function () {
        return this.graph;
    };
    /**
     * @author fenris
     */
    /*
    public dependencytasks(output : string) : Array<class_task> {
        return (
            this.dependencies_all.map(
                function (path : string, index : int) : class_task_dependency {
                    return (
                        new class_task_dependency(
                            {
                                "name": `__dependency_${index.toString()}`,
                                "parameters": {
                                    "path": path,
                                    "output": output,
                                    "raw": true,
                                },
                            }
                        )
                    );
                }
            )
        );
    }
     */
    /**
     * @author fenris
     */
    class_project.create = function (filepointer, nameprefix) {
        if (nameprefix === void 0) { nameprefix = null; }
        return (function (resolve, reject) {
            var node = { "filepointer": filepointer, "rawproject": null };
            log("scanning dependencies", 3);
            scan(node)(function (graph) {
                log("got dependency graph", 3);
                var dependencynodes = null;
                var error = null;
                try {
                    log("applying topsort", 3);
                    dependencynodes = graph
                        .topsort()
                        .filter(function (node) { return (node.filepointer.toString() != filepointer.toString()); });
                    error = null;
                }
                catch (exception) {
                    error = new class_error("could not sort dependencies; probably circular structure", [exception]);
                }
                if (error == null) {
                    log("creating core task", 3);
                    var core = class_tasktemplate.create(node.rawproject.roottask);
                    log("creating dependency tasks", 3);
                    var dependencies = dependencynodes.map(function (node, index) {
                        var task = class_tasktemplate.create(node.rawproject.roottask, name_mark("dependency_" + (node.rawproject.name || lib_string.generate())));
                        task.context_set(node.filepointer.location);
                        return task;
                    });
                    log("creating root task", 3);
                    var task = new class_task({
                        "name": name_mark("root"),
                        "sub": [
                            new class_task({
                                "name": name_mark("dependencies"),
                                "sub": dependencies
                            }),
                            new class_task({
                                "name": name_mark("core"),
                                "sub": [core]
                            }),
                        ]
                    });
                    log("creating project", 3);
                    var project = new class_project(node.rawproject.name || "(nameless project)", node.rawproject.version || "0.0.0", task);
                    project.graph = graph;
                    resolve(project);
                }
                else {
                    reject(error);
                }
            }, function (reason) { return reject(new class_error("scanning dependencies failed", [reason])); });
        });
    };
    return class_project;
}());
globalvars.invocation = {
    "interpreter": null,
    "path": "koralle"
};
globalvars.configuration = {
    "version": "0.3.0",
    "tempfolder": null,
    "system": null,
    "execute": false,
    "output_target": null,
    "output_path": null,
    "sheet_path": null,
    "showgraph": false,
    "verbosity": 0,
    "name_splitter": "_",
    "name_prefix": "~",
    "programpaths": {
        "php": null,
        "tsc": null,
        "babel": null,
        "lessc": null,
        "sass": null,
        "schwamm": null,
        "locmerge": null
    }
};
/**
 * @author fenris
 */
function log(message, level) {
    if (level === void 0) { level = 0; }
    if (level <= globalvars.configuration.verbosity) {
        (new class_message(message, { "type": "log", "prefix": "koralle" })).stderr();
    }
}
/**
 * @author fenris
 */
function main(args) {
    log("starting", 2);
    var arghandler = new lib_args.class_handler([
        new lib_args.class_argument({
            "name": "path",
            "type": "string",
            "default": "project.json",
            "info": "the path of the project-description-file",
            "kind": "positional",
            "parameters": {}
        }),
        new lib_args.class_argument({
            "name": "verbosity",
            "type": "int",
            "info": "how much informational output shall be given",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["verbosity"],
                "indicators_short": ["b"]
            }
        }),
        new lib_args.class_argument({
            "name": "help",
            "type": "boolean",
            "info": "show this help and exit",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["help"],
                "indicators_short": ["h"]
            }
        }),
        new lib_args.class_argument({
            "name": "tasklist",
            "type": "boolean",
            "info": "show the list of available tasks and exit",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["tasklist"],
                "indicators_short": ["l"]
            }
        }),
        new lib_args.class_argument({
            "name": "version",
            "type": "boolean",
            "info": "print the version to stdout and exit",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["version"],
                "indicators_short": ["v"]
            }
        }),
        new lib_args.class_argument({
            "name": "output",
            "type": "string",
            "default": "gnumake",
            "info": "the output build system; valid values are 'gnumake', 'ant'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["output"],
                "indicators_short": ["o"]
            }
        }),
        new lib_args.class_argument({
            "name": "system",
            "type": "string",
            "default": "own",
            "info": "the target platform; valid values are 'own' (the system executing koralle), 'linux', 'bsd', 'win'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["system"],
                "indicators_short": ["s"]
            }
        }),
        new lib_args.class_argument({
            "name": "file",
            "type": "string",
            "default": null,
            "info": "the file in which the result build script shall be written",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["file"],
                "indicators_short": ["f"]
            }
        }),
        new lib_args.class_argument({
            "name": "execute",
            "type": "boolean",
            "info": "if set, the build script will be executed instead of being printed to stdout",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["execute"],
                "indicators_short": ["x"]
            }
        }),
        new lib_args.class_argument({
            "name": "showgraph",
            "type": "boolean",
            "info": "if set, the dot language description of the dependency graph is printed to stdout",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["showgraph"],
                "indicators_short": ["g"]
            }
        }),
        new lib_args.class_argument({
            "name": "path_php",
            "type": "string",
            "default": "php",
            "info": "the path to the program 'php'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-php"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_tsc",
            "type": "string",
            "default": "tsc",
            "info": "the path to the program 'tsc'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-tsc"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_babel",
            "type": "string",
            "default": "babel",
            "info": "the path to the program 'babel'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-babel"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_lessc",
            "type": "string",
            "default": "lessc",
            "info": "the path to the program 'lessc'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-lessc"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_sass",
            "type": "string",
            "default": "sass",
            "info": "the path to the program 'sass'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-sass"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_schwamm",
            "type": "string",
            "default": "schwamm",
            "info": "the path to the program 'schwamm'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-schwamm"],
                "indicators_short": []
            }
        }),
        new lib_args.class_argument({
            "name": "path_locmerge",
            "type": "string",
            "default": "locmerge",
            "info": "the path to the program 'locmerge'",
            "kind": "volatile",
            "parameters": {
                "indicators_long": ["path-locmerge"],
                "indicators_short": []
            }
        }),
    ]);
    // lib_args.verbosity = 5;
    log("reading command line arguments", 2);
    var argdata = arghandler.read("cli", args.join(" "));
    globalvars.configuration.sheet_path = argdata["path"];
    {
        // todo: auslagern (nach "plankton/base" vllt.)
        var systemmap = {
            "linux": "linux",
            "freebsd": "bsd",
            "openbsd": "bsd",
            "win32": "win"
        };
        globalvars.configuration.system = (argdata["system"] == "own") ? systemmap[process.platform] : argdata["system"];
    }
    globalvars.configuration.output_target = argdata["output"];
    globalvars.configuration.execute = argdata["execute"];
    globalvars.configuration.show_help = argdata["help"];
    globalvars.configuration.show_version = argdata["version"];
    globalvars.configuration.show_tasklist = argdata["tasklist"];
    globalvars.configuration.showgraph = argdata["showgraph"];
    globalvars.configuration.output_path = argdata["file"];
    globalvars.configuration.verbosity = argdata["verbosity"];
    globalvars.configuration.programpaths.php = argdata["path_php"];
    globalvars.configuration.programpaths.tsc = argdata["path_tsc"];
    globalvars.configuration.programpaths.babel = argdata["path_babel"];
    globalvars.configuration.programpaths.lessc = argdata["path_lessc"];
    globalvars.configuration.programpaths.sass = argdata["path_sass"];
    globalvars.configuration.programpaths.schwamm = argdata["path_schwamm"];
    globalvars.configuration.programpaths.locmerge = argdata["path_locmerge"];
    return (lib_call.promise_resolve({})
        // distinction
        .then(function (state) {
        // help
        if (globalvars.configuration.show_help) {
            var message = arghandler.generate_help({
                "programname": "Koralle Build System Abstractor",
                "executable": "koralle",
                "author": "Christian Fraß <frass@greenscale.de>",
                "description": "Koralle is not a build-system itself. Instead it generates scripts for existing build-systems (e.g. GNU Make, Apache Ant, …) on base of a common json-description-file (usually named 'project.json'). Koralle is designed for reducing the amount of text needed to define the build-process."
            });
            (new class_message(message)).stdout();
            return lib_call.promise_resolve(state);
        }
        // version
        else if (globalvars.configuration.show_version) {
            (new class_message(globalvars.configuration.version.toString())).stdout();
            return lib_call.promise_resolve(state);
        }
        // tasklist
        else if (globalvars.configuration.show_tasklist) {
            (new class_message(class_tasktemplate.list())).stdout();
            return lib_call.promise_resolve(state);
        }
        // regular
        else {
            return (lib_call.promise_resolve(state)
                // environment
                .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                log("setting up environment", 2);
                var sheet_filepointer = lib_path.filepointer_read(globalvars.configuration.sheet_path);
                // sheet_filepointer.location.go_thither();
                state.sheet_filepointer = sheet_filepointer;
                resolve(state);
            }); })
                // setup output
                .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                log("setting up output", 2);
                var mapping = {
                    "ant": new class_target_ant(),
                    "gnumake": new class_target_gnumake(),
                    "make": new class_target_gnumake()
                };
                var output_target = lib_object.fetch(mapping, globalvars.configuration.output_target, null, 0);
                if (output_target == null) {
                    reject(new class_error("no implementation found for output_target '".concat(globalvars.configuration.output_target, "'")));
                }
                else {
                    state.output_target = output_target;
                    resolve(state);
                }
            }); })
                // setup temp-folder
                .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                log("setting up temp-folder", 2);
                try {
                    globalvars.configuration.tempfolder = state.output_target.tempfolder();
                    resolve(state);
                }
                catch (exception) {
                    reject(new class_error("couldn't setup temp folder", [exception]));
                }
            }); })
                // setup project
                .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                log("setting up project", 2);
                class_project.create(state.sheet_filepointer)(function (project) {
                    state.project = project;
                    resolve(state);
                }, reject);
            }); })
                // core
                .then(function (state) {
                // graph
                if (globalvars.configuration.showgraph) {
                    return (lib_call.promise_resolve(state)
                        // output
                        .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                        log("showing graph", 2);
                        var output = (lib_dot.generate(state.project.graph_get()
                            .hasse()
                            .output_dot({
                            "extract_label": function (node) { return (node.rawproject.name || node.filepointer.toString()); },
                            "rotate": true
                        })));
                        (new class_message(output)).stdout();
                        resolve(state);
                    }); }));
                }
                // regular
                else {
                    return (lib_call.promise_resolve(state)
                        // generate
                        .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                        log("generating output", 2);
                        try {
                            var output_script = state.output_target.compile_project_string(state.project);
                            state.output_script = output_script;
                            resolve(state);
                        }
                        catch (exception) {
                            reject(new class_error("generating build script failed", [exception]));
                        }
                    }); })
                        // write
                        .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                        log("writing to file", 2);
                        var filepointer;
                        if (globalvars.configuration.output_path == null) {
                            if (!globalvars.configuration.execute) {
                                filepointer = null;
                            }
                            else {
                                filepointer = new lib_path.class_filepointer(
                                // new lib_path.class_location(null, new lib_path.class_path(["."])),
                                lib_path.location_read(globalvars.configuration.tempfolder, globalvars.configuration.system), 
                                // lib_path.class_location.tempfolder(globalvars.configuration.system),
                                "__koralle");
                            }
                        }
                        else {
                            filepointer = lib_path.filepointer_read(globalvars.configuration.output_path);
                        }
                        state.output_filepointer = filepointer;
                        if (filepointer == null) {
                            (new class_message(state.output_script)).stdout();
                            resolve(state);
                        }
                        else {
                            nm_fs.writeFile(filepointer.toString(), state.output_script, function (error) {
                                if (error == null) {
                                    resolve(state);
                                }
                                else {
                                    reject(new class_error("writing to file failed", [error]));
                                }
                            });
                        }
                    }); })
                        // execute
                        .then(function (state) { return lib_call.promise_make(function (resolve, reject) {
                        log("executing", 2);
                        if (!globalvars.configuration.execute) {
                            resolve(state);
                        }
                        else {
                            state.output_target.execute(state.output_filepointer)(function (result) { return resolve(state); }, function (reason) { return reject(new class_error("execution of build script failed", [reason])); });
                        }
                    }); }));
                }
            }));
        }
    }));
}
log("intro", 2);
globalvars.invocation = {
    "interpreter": process.argv[0],
    "path": process.argv[1]
};
main(process.argv.slice(2))
    .then(function (dummy) {
    // (new class_message("successfull", {"type": "information", "prefix": "koralle"})).stderr();
    process.exit(0);
}, function (reason) {
    // throw reason;
    console.error(reason);
    (new class_message("the following error occured: '".concat(reason.toString(), "'"), { "type": "error", "prefix": "koralle" })).stderr();
    process.exit(-1);
});
