From 9e077fe3629fe69575e479673d14135772c41114 Mon Sep 17 00:00:00 2001 From: Fenris Wolf Date: Wed, 18 Sep 2024 18:17:25 +0200 Subject: [PATCH] [mod] --- conf/example.json | 5 +- data/example.kal.json | 342 +- data/linke.json | 347 ++ lib/plankton/plankton.d.ts | 2014 +++------ lib/plankton/plankton.js | 5623 ++++++++++--------------- source/api/actions/calendar_list.ts | 25 +- source/api/actions/events.ts | 5 +- source/api/actions/session_begin.ts | 6 +- source/api/actions/session_oidc.ts | 13 +- source/api/actions/session_prepare.ts | 31 +- source/api/functions.ts | 2 + source/auth.ts | 93 + source/conf.ts | 427 +- source/main.ts | 136 +- source/repositories/auth_internal.ts | 77 + source/repositories/resource.ts | 140 + source/repositories/user.ts | 119 + source/services/auth_internal.ts | 40 + source/services/calendar.ts | 10 + source/services/resource.ts | 14 + source/services/user.ts | 24 + tools/makefile | 18 +- tools/update-plankton | 6 +- 23 files changed, 4156 insertions(+), 5361 deletions(-) create mode 100644 data/linke.json create mode 100644 source/auth.ts create mode 100644 source/repositories/auth_internal.ts create mode 100644 source/repositories/user.ts create mode 100644 source/services/auth_internal.ts create mode 100644 source/services/resource.ts create mode 100644 source/services/user.ts diff --git a/conf/example.json b/conf/example.json index bfe52ed..7cff1d0 100644 --- a/conf/example.json +++ b/conf/example.json @@ -2,5 +2,8 @@ "version": 1, "log": [ {"kind": "stdout", "data": {"threshold": "info"}} - ] + ], + "session_management": { + "in_memory": false + } } diff --git a/data/example.kal.json b/data/example.kal.json index c6ab387..0bb0608 100644 --- a/data/example.kal.json +++ b/data/example.kal.json @@ -2,120 +2,51 @@ "users": [ { "id": 1, - "object": { - "name": "christian.frass" - } + "name": "alice", + "email_address": "alice@example.org", + "password": "alice" }, { "id": 2, - "object": { - "name": "andre.weichert" - } + "name": "bob", + "email_address": "bob@example.org", + "password": "bob" }, { "id": 3, - "object": { - "name": "steffen.doegnitz" - } - }, - { - "id": 4, - "object": { - "name": "frank.dietrich" - } - }, - { - "id": 5, - "object": { - "name": "michael.berger" - } - }, - { - "id": 6, - "object": { - "name": "roland.schroeder" - } - }, - { - "id": 7, - "object": { - "name": "rene.hahn" - } - }, - { - "id": 8, - "object": { - "name": "max.meierhof" - } - }, - { - "id": 9, - "object": { - "name": "klaus.kleba" - } - }, - { - "id": 10, - "object": { - "name": "tim.detzner" - } + "name": "charlie", + "email_address": "charlie@example.org", + "password": "charlie" } ], "calendars": [ { "id": 1, - "object": { - "kind": "concrete", + "name": "house", + "public": false, + "members": [ + { + "user_id": 1, + "role": "editor" + } + ], + "resource": { + "kind": "local", "data": { - "name": "BV", - "private": false, - "hue": 0.0000000000000000, - "users": [ - ], "events": [ { - "name": "9. Bundesparteitag | 1. Sitzung | Tag 1", + "name": "clean floors", "begin": { "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 18}, + "date": {"year": 2024, "month": 9, "day": 21}, "time": {"hour": 10, "minute": 0, "second": 0} }, "end": { "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 18}, - "time": {"hour": 18, "minute": 0, "second": 0} + "date": {"year": 2024, "month": 9, "day": 21}, + "time": {"hour": 11, "minute": 0, "second": 0} }, - "location": "Halle", - "description": null - }, - { - "name": "9. Bundesparteitag | 1. Sitzung | Tag 2", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 19}, - "time": {"hour": 10, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 19}, - "time": {"hour": 18, "minute": 0, "second": 0} - }, - "location": "Halle", - "description": null - }, - { - "name": "9. Bundesparteitag | 1. Sitzung | Tag 3", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 20}, - "time": {"hour": 10, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 10, "day": 20}, - "time": {"hour": 18, "minute": 0, "second": 0} - }, - "location": "Halle", + "location": "1st floor", "description": null } ] @@ -124,73 +55,35 @@ }, { "id": 2, - "object": { - "kind": "concrete", + "name": "turf", + "public": false, + "members": [ + { + "user_id": 1, + "role": "viewer" + }, + { + "user_id": 2, + "role": "editor" + } + ], + "resource": { + "kind": "local", "data": { - "name": "LV Sachsen", - "private": false, - "hue": 0.6180339887498949, - "users": [ - { - "id": 9, - "role": "editor" - } - ], "events": [ { - "name": "Sören Pellmann zu den Landtagswahlen im Osten", + "name": "garden party", "begin": { "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 11}, + "date": {"year": 2024, "month": 9, "day": 21}, "time": {"hour": 18, "minute": 0, "second": 0} }, - "end": null, - "location": "online: https://v2202002113208108062.supersrv.de/b/har-jbu-lxy-rx1", - "description": null - }, - { - "name": "Erinnern versammeln. Praktiken für die Zukünfte einer Gesellschaft der Vielen.", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 13}, - "time": {"hour": 17, "minute": 0, "second": 0} - }, "end": { "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 15}, - "time": null + "date": {"year": 2024, "month": 9, "day": 21}, + "time": {"hour": 23, "minute": 0, "second": 0} }, - "location": "Weltecho, Annaberger Straße 24, 09111 Chemnitz", - "description": null - }, - { - "name": "Parteikonvent zur Auswertung des Wahljahres", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 14}, - "time": {"hour": 10, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 14}, - "time": {"hour": 16, "minute": 30, "second": 0} - }, - "location": "Veranstaltungs- und Kulturforum STADTPARK | Hammertal 3 | 09669 Frankenberg/Sachsen", - "description": null - }, - { - "name": "Ist die extreme Rechte noch zu stoppen?", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 19}, - "time": {"hour": 19, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 19}, - "time": {"hour": 21, "minute": 0, "second": 0} - }, - "location": "online: https://www.dielinke-sachsen.de/termine/?termin_ort=digital-internet-stream", + "location": "bob's garden", "description": null } ] @@ -199,149 +92,44 @@ }, { "id": 3, - "object": { - "kind": "concrete", - "data": { - "name": "KV Zwickau", - "private": false, - "hue": 0.4721359549995796, - "events": [ - { - "name": "Vorstands-Sitzung", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 5}, - "time": {"hour": 18, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 5}, - "time": {"hour": 21, "minute": 0, "second": 0} - }, - "location": "Zwickau, Innere Schneeberger Straße 17", - "description": null - } - ] + "name": "town", + "public": true, + "members": [ + { + "user_id": 1, + "role": "viewer" + }, + { + "user_id": 2, + "role": "viewer" + }, + { + "user_id": 3, + "role": "editor" } - } - }, - { - "id": 4, - "object": { - "kind": "concrete", + ], + "resource": { + "kind": "local", "data": { - "name": "OV Glauchau", - "private": false, - "users": [ - { - "id": 1, - "role": "editor" - }, - { - "id": 5, - "role": "editor" - }, - { - "id": 6, - "role": "editor" - } - ], - "hue": 0.09016994374947451, "events": [ { - "name": "Kinderspieletag", + "name": "ting", "begin": { "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 8}, - "time": {"hour": 12, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 8}, + "date": {"year": 2024, "month": 9, "day": 23}, "time": {"hour": 16, "minute": 0, "second": 0} }, - "location": null, - "description": null - }, - { - "name": "Mitglieder-Sitzung", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 19}, - "time": {"hour": 17, "minute": 30, "second": 0} - }, "end": { "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 19}, - "time": {"hour": 19, "minute": 0, "second": 0} + "date": {"year": 2024, "month": 9, "day": 23}, + "time": {"hour": 18, "minute": 0, "second": 0} }, - "location": null, + "location": "market square", "description": null } ] } } - }, - { - "id": 5, - "object": { - "kind": "concrete", - "data": { - "name": "OV Zwickau", - "private": false, - "hue": 0.09016994374947451, - "users": [ - { - "id": 7, - "role": "editor" - }, - { - "id": 8, - "role": "viewer" - } - ], - "events": [ - { - "name": "4ter Christopher Street Day", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 8, "day": 31}, - "time": {"hour": 10, "minute": 0, "second": 0} - }, - "end": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 8, "day": 31}, - "time": {"hour": 17, "minute": 0, "second": 0} - }, - "location": "Zwickau", - "description": null - }, - { - "name": "Regionaltreffen Westsachsen: Schule ohne Rassismus – Schule mit Courage", - "begin": { - "timezone_shift": 2, - "date": {"year": 2024, "month": 9, "day": 19}, - "time": {"hour": 9, "minute": 0, "second": 0} - }, - "end": null, - "location": null, - "description": null - } - ] - } - } - }, - { - "id": 6, - "object": { - "kind": "caldav", - "data": { - "name": "Lixer", - "private": true, - "url": "https://export.kalender.digital/ics/0/3e10dae66950379d4cc8/gesamterkalender.ics?past_months=3&future_months=36", - "read_only": true - } - } } ] } diff --git a/data/linke.json b/data/linke.json new file mode 100644 index 0000000..c6ab387 --- /dev/null +++ b/data/linke.json @@ -0,0 +1,347 @@ +{ + "users": [ + { + "id": 1, + "object": { + "name": "christian.frass" + } + }, + { + "id": 2, + "object": { + "name": "andre.weichert" + } + }, + { + "id": 3, + "object": { + "name": "steffen.doegnitz" + } + }, + { + "id": 4, + "object": { + "name": "frank.dietrich" + } + }, + { + "id": 5, + "object": { + "name": "michael.berger" + } + }, + { + "id": 6, + "object": { + "name": "roland.schroeder" + } + }, + { + "id": 7, + "object": { + "name": "rene.hahn" + } + }, + { + "id": 8, + "object": { + "name": "max.meierhof" + } + }, + { + "id": 9, + "object": { + "name": "klaus.kleba" + } + }, + { + "id": 10, + "object": { + "name": "tim.detzner" + } + } + ], + "calendars": [ + { + "id": 1, + "object": { + "kind": "concrete", + "data": { + "name": "BV", + "private": false, + "hue": 0.0000000000000000, + "users": [ + ], + "events": [ + { + "name": "9. Bundesparteitag | 1. Sitzung | Tag 1", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 18}, + "time": {"hour": 10, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 18}, + "time": {"hour": 18, "minute": 0, "second": 0} + }, + "location": "Halle", + "description": null + }, + { + "name": "9. Bundesparteitag | 1. Sitzung | Tag 2", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 19}, + "time": {"hour": 10, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 19}, + "time": {"hour": 18, "minute": 0, "second": 0} + }, + "location": "Halle", + "description": null + }, + { + "name": "9. Bundesparteitag | 1. Sitzung | Tag 3", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 20}, + "time": {"hour": 10, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 10, "day": 20}, + "time": {"hour": 18, "minute": 0, "second": 0} + }, + "location": "Halle", + "description": null + } + ] + } + } + }, + { + "id": 2, + "object": { + "kind": "concrete", + "data": { + "name": "LV Sachsen", + "private": false, + "hue": 0.6180339887498949, + "users": [ + { + "id": 9, + "role": "editor" + } + ], + "events": [ + { + "name": "Sören Pellmann zu den Landtagswahlen im Osten", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 11}, + "time": {"hour": 18, "minute": 0, "second": 0} + }, + "end": null, + "location": "online: https://v2202002113208108062.supersrv.de/b/har-jbu-lxy-rx1", + "description": null + }, + { + "name": "Erinnern versammeln. Praktiken für die Zukünfte einer Gesellschaft der Vielen.", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 13}, + "time": {"hour": 17, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 15}, + "time": null + }, + "location": "Weltecho, Annaberger Straße 24, 09111 Chemnitz", + "description": null + }, + { + "name": "Parteikonvent zur Auswertung des Wahljahres", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 14}, + "time": {"hour": 10, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 14}, + "time": {"hour": 16, "minute": 30, "second": 0} + }, + "location": "Veranstaltungs- und Kulturforum STADTPARK | Hammertal 3 | 09669 Frankenberg/Sachsen", + "description": null + }, + { + "name": "Ist die extreme Rechte noch zu stoppen?", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 19}, + "time": {"hour": 19, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 19}, + "time": {"hour": 21, "minute": 0, "second": 0} + }, + "location": "online: https://www.dielinke-sachsen.de/termine/?termin_ort=digital-internet-stream", + "description": null + } + ] + } + } + }, + { + "id": 3, + "object": { + "kind": "concrete", + "data": { + "name": "KV Zwickau", + "private": false, + "hue": 0.4721359549995796, + "events": [ + { + "name": "Vorstands-Sitzung", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 5}, + "time": {"hour": 18, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 5}, + "time": {"hour": 21, "minute": 0, "second": 0} + }, + "location": "Zwickau, Innere Schneeberger Straße 17", + "description": null + } + ] + } + } + }, + { + "id": 4, + "object": { + "kind": "concrete", + "data": { + "name": "OV Glauchau", + "private": false, + "users": [ + { + "id": 1, + "role": "editor" + }, + { + "id": 5, + "role": "editor" + }, + { + "id": 6, + "role": "editor" + } + ], + "hue": 0.09016994374947451, + "events": [ + { + "name": "Kinderspieletag", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 8}, + "time": {"hour": 12, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 8}, + "time": {"hour": 16, "minute": 0, "second": 0} + }, + "location": null, + "description": null + }, + { + "name": "Mitglieder-Sitzung", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 19}, + "time": {"hour": 17, "minute": 30, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 19}, + "time": {"hour": 19, "minute": 0, "second": 0} + }, + "location": null, + "description": null + } + ] + } + } + }, + { + "id": 5, + "object": { + "kind": "concrete", + "data": { + "name": "OV Zwickau", + "private": false, + "hue": 0.09016994374947451, + "users": [ + { + "id": 7, + "role": "editor" + }, + { + "id": 8, + "role": "viewer" + } + ], + "events": [ + { + "name": "4ter Christopher Street Day", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 8, "day": 31}, + "time": {"hour": 10, "minute": 0, "second": 0} + }, + "end": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 8, "day": 31}, + "time": {"hour": 17, "minute": 0, "second": 0} + }, + "location": "Zwickau", + "description": null + }, + { + "name": "Regionaltreffen Westsachsen: Schule ohne Rassismus – Schule mit Courage", + "begin": { + "timezone_shift": 2, + "date": {"year": 2024, "month": 9, "day": 19}, + "time": {"hour": 9, "minute": 0, "second": 0} + }, + "end": null, + "location": null, + "description": null + } + ] + } + } + }, + { + "id": 6, + "object": { + "kind": "caldav", + "data": { + "name": "Lixer", + "private": true, + "url": "https://export.kalender.digital/ics/0/3e10dae66950379d4cc8/gesamterkalender.ics?past_months=3&future_months=36", + "read_only": true + } + } + } + ] +} diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 66c3c17..0172138 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -893,6 +893,600 @@ declare namespace lib_plankton.log { } declare namespace lib_plankton.log { } +declare namespace lib_plankton.code { + /** + * @author fenris + */ + interface interface_code { + /** + * @author fenris + */ + encode(x: type_from): type_to; + /** + * @author fenris + */ + decode(x: type_to): type_from; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + type type_code = { + /** + * @author fenris + */ + encode: (x: type_from) => type_to; + /** + * @author fenris + */ + decode: (x: type_to) => type_from; + }; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function inverse_encode(decode: (to: type_to) => type_from, to: type_to): type_from; + /** + * @author fenris + */ + function inverse_decode(encode: (from: type_from) => type_to, from: type_from): type_to; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_inverse implements interface_code { + /** + * @author fenris + */ + protected subject: interface_code; + /** + * @author fenris + */ + constructor(subject: interface_code); + /** + * @implementation + * @author fenris + */ + encode(to: type_to): type_from; + /** + * @implementation + * @author fenris + */ + decode(from: type_from): type_to; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function pair_encode(encode_first: (from: type_from) => type_between, encode_second: (between: type_between) => type_to, from: type_from): type_to; + /** + * @author fenris + */ + function pair_decode(decode_first: (between: type_between) => type_from, decode_second: (to: type_to) => type_between, to: type_to): type_from; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_pair implements interface_code { + /** + * @author fenris + */ + protected first: interface_code; + /** + * @author fenris + */ + protected second: interface_code; + /** + * @author fenris + */ + constructor(first: interface_code, second: interface_code); + /** + * @implementation + * @author fenris + */ + encode(from: type_from): type_to; + /** + * @implementation + * @author fenris + */ + decode(to: type_to): type_from; + } +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + function chain_encode(encode_links: Array<(from: any) => any>, from: any): any; + /** + * @author fenris + */ + function chain_decode(decode_links: Array<(to: any) => any>, to: any): any; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_chain implements interface_code { + /** + * @author fenris + */ + protected links: Array>; + /** + * @author fenris + */ + constructor(links: Array>); + /** + * @implementation + * @author fenris + */ + encode(from: any): any; + /** + * @implementation + * @author fenris + */ + decode(to: any): any; + } +} +declare namespace lib_plankton.code { + /** + * @author Christian Fraß + */ + type type_flatten_from = Array<{ + [name: string]: any; + }>; + /** + * @author Christian Fraß + */ + type type_flatten_to = { + keys: Array; + data: Array>; + }; + /** + * @author Christian Fraß + */ + function flatten_encode(from: type_flatten_from, keys?: Array): type_flatten_to; + /** + * @author Christian Fraß + */ + function flatten_decode(to: type_flatten_to): type_flatten_from; +} +declare namespace lib_plankton.code { + /** + * @author fenris + */ + class class_code_flatten implements interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(x: type_flatten_from): type_flatten_to; + /** + * @implementation + * @author fenris + */ + decode(x: type_flatten_to): type_flatten_from; + } +} +declare namespace lib_plankton.json { + /** + */ + type type_source = any; + /** + */ + type type_target = string; + /** + * @author fenris + */ + export function encode(source: type_source, options?: { + formatted?: boolean; + }): type_target; + /** + * @author fenris + */ + export function decode(target: type_target): type_source; + /** + * @author fenris + */ + export function implementation_code(): lib_plankton.code.type_code; + export {}; +} +declare namespace lib_plankton.json { + /** + * @author fenris + */ + class class_json implements lib_plankton.code.interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(x: any): string; + /** + * @implementation + * @author fenris + */ + decode(x: string): any; + } +} +declare namespace lib_plankton.file { + /** + * @author fenris + */ + function exists(path: string): Promise; + /** + * @author fenris + */ + function read(path: string): Promise; + /** + * @author fenris + */ + function read_buffer(path: string): Promise; + /** + * @author fenris + */ + function read_stdin(): Promise; + /** + * @author fenris + */ + function write(path: string, content: string, options?: { + encoding?: string; + }): Promise; + /** + * @author fenris + */ + function write_buffer(path: string, content: Buffer, options?: {}): Promise; + /** + */ + function delete_(path: string): Promise; +} +declare namespace lib_plankton.object { + /** + * @author fenris + * @deprecated use the "??" operator instead + */ + function fetch(object: Object, fieldname: string, options?: { + fallback?: type_value; + escalate?: boolean; + }): type_value; + /** + */ + function map(object_from: Record, transformator: ((value_from: type_from, key?: string) => type_to)): Record; + /** + * gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück + */ + function filter(object_from: Record, predicate: ((value_from: type_value, key?: string) => boolean)): Record; + /** + * wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * + * @deprecated use Object.fromEntries instead! + */ + function from_array(array: Array<{ + key: string; + value: type_value; + }>): Record; + /** + * wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * + * @deprecated use Object.entries insetad! + */ + function to_array(object: Record): Array<{ + key: string; + value: type_value; + }>; + /** + * gibt eine Liste von Schlüsseln eines Objekts zurück + * + * @deprecated use Object.keys instead! + */ + function keys(object: Record): Array; + /** + * gibt eine Liste von Werten eines Objekts zurück + * + * @deprecated use Object.values instead! + */ + function values(object: Record): Array; + /** + * liest ein Baum-artiges Objekt an einer bestimmten Stelle aus + */ + function path_read(object: Object, path: string, options?: { + fallback?: type_value; + escalate?: boolean; + }): type_value; + /** + * schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt + */ + function path_write(object: Object, path: string, value: type_value, construct?: boolean): void; + /** + * prüft ob ein Objekt einem bestimmten Muster entspricht + * + * @deprecated not very useful + */ + function matches(object: Record, pattern: Record, options?: { + collate?: ((value_pattern: type_value_pattern, value_object: type_value_object) => boolean); + }): boolean; + /** + * erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt + */ + function flatten(value: any, options?: { + separator?: string; + key_for_array_element?: ((index: int) => string); + }): Record; + /** + * @deprecated use Object.assign instead! + */ + function clash(x: Record, y: Record, options?: { + overwrite?: boolean; + hooks?: { + existing?: ((key?: string, value_old?: any, value_new?: any) => void); + }; + }): Record; + /** + * @deprecated use Object.assign instead! + */ + function patch(core: (null | Record), mantle: (null | Record), options?: { + deep?: boolean; + path?: (null | string); + }): void; + /** + * @deprecated use Object.assign instead! + */ + function patched(core: Record, mantle: Record, options?: { + deep?: boolean; + }): Record; + /** + * @deprecated use Object.assign instead! + */ + function attached(object: Record, key: string, value: any): Record; + /** + * @author fenris + */ + function copy(object: Record): Record; +} +declare namespace lib_plankton.pair { + /** + */ + type type_pair = { + first: type_first; + second: type_second; + }; +} +declare namespace lib_plankton.pair { + /** + */ + function swap(pair: type_pair): type_pair; + /** + */ + function show(pair: type_pair, options?: { + show_first?: ((first: type_first) => string); + show_second?: ((second: type_second) => string); + }): string; +} +declare namespace lib_plankton.list { + /** + */ + type type_separation = { + yes: Array; + no: Array; + }; + /** + */ + type type_result_max = (null | { + index: int; + element: type_element; + value: type_value; + }); +} +declare namespace lib_plankton.list { + /** + * returns a certain list of integer numbers + */ + function range(from: int, to: int, options?: { + step?: int; + }): Array; + /** + * returns a certain list of consecutiv integer numbers, beginning with 0 + */ + function sequence(length: int): Array; + /** + */ + function from_iterator(iterator: Iterator): Array; + /** + */ + function is_empty(list: Array): boolean; + /** + * combines two lists into one + * + * @param {boolean} [options.cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true + */ + function zip(list_first: Array, list_second: Array, options?: { + cut?: boolean; + }): Array>; + /** + * checks whether two lists are equal + * + * @todo define common function "equals" and default predicate to + */ + function equals(list1: Array, list2: Array, options?: { + collate_element?: ((element1: type_element, element2: type_element) => boolean); + }): boolean; + /** + * creates a list with the elements from the input list, which fulfil a certain predicate (~ filter) + */ + function keep(list: Array, predicate: ((element: type_element) => boolean)): Array; + /** + * creates a list with the elements from the input list, which do not fulfil a certain predicate (~ dual filter) + */ + function drop(list: Array, predicate: ((element: type_element) => boolean)): Array; + /** + */ + function filter_inplace(list: Array, predicate: ((element: type_element) => boolean)): void; + /** + * returns a list with no duplicates (like unix' "unique") + */ + function cleaned(list: Array, options?: { + collate_element?: ((x: type_element, y: type_element) => boolean); + }): Array; + /** + * creates a binary partition of the list according to a given predicate + */ + function separate(list: Array, predicate: ((element: type_element) => boolean)): type_separation; + /** + */ + function clone(list: Array): Array; + /** + */ + function reversed(list: Array): Array; + /** + * @todo use Array.toSorted? + */ + function sorted(list: Array, options: { + compare_element?: ((element1: type_element, element2: type_element) => boolean); + }): Array; + /** + * die Liste in gleich große Blöcke zerlegen + */ + function chop(list: Array, chunk_size: int): Array>; + /** + */ + function group(list: Array, collate_element: ((x: type_element, y: type_element) => boolean)): Array>; + /** + */ + function has(list: Array, predicate: ((element: type_element) => boolean)): boolean; + /** + * @deprecate use Array.includes or Array.some + */ + function contains(list: Array, element: type_element, options: { + collate_element?: ((element1: type_element, element2: type_element) => boolean); + }): boolean; + /** + * retrieves the element and its index of the list, which has the maximum value + */ + function max(list: Array, target_function: ((element: type_element) => type_value), options: { + compare_value: ((value1: type_value, value2: type_value) => boolean); + }): type_result_max; + /** + * retrieves the element and its index of the list, which has the mininum value + */ + function min(list: Array, target_function: (element: type_element) => type_value, options: { + compare_value: ((value1: type_value, value2: type_value) => boolean); + }): type_result_max; + /** + * implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)" + * example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]] + */ + function distribute(lists: Array>): Array>; + /** + */ + function contrast(list_left: Array, extract_key_left: ((left: type_left) => string), list_right: Array, extract_key_right: ((right: type_right) => string)): { + both: Array<{ + key: string; + left: type_left; + right: type_right; + }>; + only_left: Array<{ + key: string; + left: type_left; + }>; + only_right: Array<{ + key: string; + right: type_right; + }>; + }; +} +declare namespace lib_plankton.conf { + /** + */ + type type_schema = ({ + enum?: Array; + default?: any; + description?: string; + } | { + type: "null"; + description?: string; + } | { + type: "boolean"; + nullable?: boolean; + enum?: Array; + default?: boolean; + description?: string; + } | { + type: "integer"; + nullable?: boolean; + enum?: Array; + default?: int; + description?: string; + } | { + type: "number"; + nullable?: boolean; + enum?: Array; + default?: number; + description?: string; + } | { + type: "string"; + nullable?: boolean; + enum?: Array; + default?: string; + description?: string; + } | { + type: "array"; + nullable?: boolean; + items: type_schema; + enum?: Array>; + default?: Array; + description?: string; + } | { + type: "object"; + nullable?: boolean; + properties?: Record; + required?: Array; + additionalProperties?: (false | type_schema); + enum?: Array>; + default?: Record; + description?: string; + } | { + anyOf: Array; + default?: any; + } | { + allOf: Array; + } | { + oneOf: Array; + } | { + not: type_schema; + }); + /** + */ + type type_report = { + incident: string; + details: Record; + }; + /** + */ + type type_adaption = { + reports: Array; + result: lib_plankton.pod.type_pod; + }; +} +declare namespace lib_plankton.conf { + /** + * @todo versioning + */ + function refine(schema: type_schema, value_raw: any): type_result; + /** + */ + function load(schema: type_schema, path: (null | string)): Promise; +} declare var plain_text_to_html: (text: string) => string; /** * @desc makes a valid @@ -2064,189 +2658,6 @@ declare namespace lib_plankton.shape.record { }): type_subject; export {}; } -declare namespace lib_plankton.code { - /** - * @author fenris - */ - interface interface_code { - /** - * @author fenris - */ - encode(x: type_from): type_to; - /** - * @author fenris - */ - decode(x: type_to): type_from; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - type type_code = { - /** - * @author fenris - */ - encode: (x: type_from) => type_to; - /** - * @author fenris - */ - decode: (x: type_to) => type_from; - }; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function inverse_encode(decode: (to: type_to) => type_from, to: type_to): type_from; - /** - * @author fenris - */ - function inverse_decode(encode: (from: type_from) => type_to, from: type_from): type_to; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_inverse implements interface_code { - /** - * @author fenris - */ - protected subject: interface_code; - /** - * @author fenris - */ - constructor(subject: interface_code); - /** - * @implementation - * @author fenris - */ - encode(to: type_to): type_from; - /** - * @implementation - * @author fenris - */ - decode(from: type_from): type_to; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function pair_encode(encode_first: (from: type_from) => type_between, encode_second: (between: type_between) => type_to, from: type_from): type_to; - /** - * @author fenris - */ - function pair_decode(decode_first: (between: type_between) => type_from, decode_second: (to: type_to) => type_between, to: type_to): type_from; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_pair implements interface_code { - /** - * @author fenris - */ - protected first: interface_code; - /** - * @author fenris - */ - protected second: interface_code; - /** - * @author fenris - */ - constructor(first: interface_code, second: interface_code); - /** - * @implementation - * @author fenris - */ - encode(from: type_from): type_to; - /** - * @implementation - * @author fenris - */ - decode(to: type_to): type_from; - } -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - function chain_encode(encode_links: Array<(from: any) => any>, from: any): any; - /** - * @author fenris - */ - function chain_decode(decode_links: Array<(to: any) => any>, to: any): any; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_chain implements interface_code { - /** - * @author fenris - */ - protected links: Array>; - /** - * @author fenris - */ - constructor(links: Array>); - /** - * @implementation - * @author fenris - */ - encode(from: any): any; - /** - * @implementation - * @author fenris - */ - decode(to: any): any; - } -} -declare namespace lib_plankton.code { - /** - * @author Christian Fraß - */ - type type_flatten_from = Array<{ - [name: string]: any; - }>; - /** - * @author Christian Fraß - */ - type type_flatten_to = { - keys: Array; - data: Array>; - }; - /** - * @author Christian Fraß - */ - function flatten_encode(from: type_flatten_from, keys?: Array): type_flatten_to; - /** - * @author Christian Fraß - */ - function flatten_decode(to: type_flatten_to): type_flatten_from; -} -declare namespace lib_plankton.code { - /** - * @author fenris - */ - class class_code_flatten implements interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: type_flatten_from): type_flatten_to; - /** - * @implementation - * @author fenris - */ - decode(x: type_flatten_to): type_flatten_from; - } -} declare namespace lib_plankton.www_form { /** */ @@ -2531,1120 +2942,6 @@ declare namespace lib_plankton.session { clear?: boolean; }): Promise; } -declare namespace lib_plankton.file { - /** - * @author fenris - */ - function exists(path: string): Promise; - /** - * @author fenris - */ - function read(path: string): Promise; - /** - * @author fenris - */ - function read_buffer(path: string): Promise; - /** - * @author fenris - */ - function read_stdin(): Promise; - /** - * @author fenris - */ - function write(path: string, content: string, options?: { - encoding?: string; - }): Promise; - /** - * @author fenris - */ - function write_buffer(path: string, content: Buffer, options?: {}): Promise; - /** - */ - function delete_(path: string): Promise; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - function map_clear(map_forEach: (procedure: (value?: type_value, key?: type_key) => void) => void, map_delete: (key: type_key) => void): void; - /** - * @author fenris - */ - function map_keys(map_forEach: (procedure: (value?: type_value, key?: type_key) => void) => void): Array; - /** - * @author fenris - */ - function map_values(map_forEach: (procedure: (value?: type_value, key?: type_key) => void) => void): Array; - /** - * @author fenris - */ - function map_pairs(map_forEach: (procedure: (value?: type_value, key?: type_key) => void) => void): Array<{ - key: type_key; - value: type_value; - }>; - /** - * @author fenris - */ - function map_toString(map_forEach: (procedure: (value?: type_value, key?: type_key) => void) => void, show_key?: (key: type_key) => string, show_value?: (value: type_value) => string): string; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - interface interface_map { - /** - * @desc [accessor] - */ - has(key: type_key): boolean; - /** - * @desc [accessor] - */ - get(key: type_key, fallback?: lib_plankton.pod.class_pod): type_value; - /** - * @desc [mutator] - */ - set(key: type_key, value: type_value): void; - /** - * @desc [mutator] - */ - delete(key: type_key): void; - /** - * @desc [accessor] - */ - forEach(procedure: ((value?: type_value, key?: type_key) => void)): void; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - abstract class class_mapbase implements interface_map { - /** - * @desc [constructor] - */ - constructor(); - /** - * @implementation - */ - abstract has(key: type_key): boolean; - /** - * @implementation - */ - abstract get(key: type_key, fallback?: lib_plankton.pod.class_pod): type_value; - /** - * @implementation - */ - abstract set(key: type_key, value: type_value): void; - /** - * @implementation - */ - abstract delete(key: type_key): void; - /** - * @implementation - */ - abstract forEach(procedure: ((value?: type_value, key?: type_key) => void)): void; - /** - * @desc [mutator] - */ - clear(): void; - /** - */ - get_safe(key: type_key): lib_plankton.pod.class_pod; - /** - * @desc [accessor] - */ - keys(): Array; - /** - * @desc [accessor] - */ - values(): Array; - /** - * @desc [accessor] - */ - pairs(): Array<{ - key: type_key; - value: type_value; - }>; - /** - * @desc [accessor] - */ - toString(show_key?: ((key: type_key) => string), show_value?: ((value: type_value) => string)): string; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - interface interface_memory { - /** - * @desc [accessor] the number of elements - */ - size(): int; - /** - * @desc [accessor] reads the takeable element - */ - scan(): type_element; - /** - * @desc [mutator] inserts an element - */ - give(element: type_element): void; - /** - * @desc [mutator] removes an element and returns it - */ - take(): type_element; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_pair implements interface_cloneable>, interface_collatable>, interface_hashable, interface_showable { - /** - * @author fenris - */ - protected first: type_first; - /** - * @author fenris - */ - protected second: type_second; - /** - * @author fenris - */ - constructor(first: type_first, second: type_second); - /** - * @desc [accessor] [getter] - * @author fenris - */ - first_get(): type_first; - /** - * @desc [accessor] [getter] - * @author fenris - */ - second_get(): type_second; - /** - * @desc [mutator] [setter] - * @author fenris - */ - first_set(first: type_first): void; - /** - * @desc [mutator] [setter] - * @author fenris - */ - second_set(second: type_second): void; - /** - * @desc [accessor] - * @author fenris - */ - swap(): class_pair; - /** - * @desc [accessor] - * @author fenris - */ - transform(transform_first: (first: type_first) => type_first_, transform_second: (second: type_second) => type_second_): class_pair; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _clone(): class_pair; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _hash(): string; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _collate(pair: class_pair): boolean; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _show(): string; - } -} -declare namespace lib_plankton.structures { - /** - */ - type type_collation = ((x: type_element, y: type_element) => boolean); - /** - * @author fenris - */ - export type type_set = { - elements: Array; - }; - /** - * @author fenris - */ - export function set_construct(collation: type_collation, elements?: Array): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_size(subject: type_set): int; - /** - * @desc [accessor] - * @author fenris - */ - export function set_has(collation: type_collation, subject: type_set, element: type_element): boolean; - /** - * @desc [mutator] - * @author fenris - */ - export function set_add(collation: type_collation, subject: type_set, element: type_element): void; - /** - * @desc [mutator] - * @author fenris - */ - export function set_pop(subject: type_set): lib_plankton.pod.type_pod; - /** - * @desc [accessor] - * @author fenris - */ - export function set_forEach(subject: type_set, function_: ((element: type_element) => void)): void; - /** - * @desc [accessor] - * @author fenris - */ - export function set_map(collation: type_collation, subject: type_set, transformator: ((element: type_element_from) => type_element_to)): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_filter(subject: type_set, predicate: ((element: type_element) => boolean)): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_dump(subject: type_set): Array; - /** - * @desc [accessor] - * @author fenris - */ - export function set_subset(collation: type_collation, subject: type_set, object: type_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - export function set_superset(collation: type_collation, subject: type_set, object: type_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - export function set_equals(collation: type_collation, subject: type_set, object: type_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - export function set_toString(show_element: ((element: type_element) => string), subject: type_set): string; - /** - * @desc [accessor] - * @author fenris - */ - export function set_empty(subject: type_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - export function set_union(collation: type_collation, subject: type_set, object: type_set): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_intersection(collation: type_collation, subject: type_set, object: type_set): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_difference(collation: type_collation, subject: type_set, object: type_set): type_set; - /** - * @desc [accessor] - * @author fenris - */ - export function set_symmetric_difference(collation: type_collation, subject: type_set, object: type_set): type_set; - /** - * @author fenris - */ - export function set_union_all(collation: type_collation, sets: Array>): type_set; - /** - * @author fenris - */ - export function set_intersection_all(collation: type_collation, sets: Array>): type_set; - export {}; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_set implements interface_collatable>, interface_showable { - /** - * @author fenris - */ - protected subject: type_set; - /** - * @author fenris - */ - protected equality: (element1: type_element, element2: type_element) => boolean; - /** - * @author fenris - */ - constructor(elements?: Array, equality?: (element1: type_element, element2: type_element) => boolean); - /** - * @author fenris - */ - protected static from_subject(equality: (element1: type_element, element2: type_element) => boolean, subject: type_set): class_set; - /** - * @desc [accessor] - * @author fenris - */ - size(): int; - /** - * @desc [accessor] - * @author fenris - */ - has(element: type_element): boolean; - /** - * @desc [mutator] - * @author fenris - */ - add(element: type_element): void; - /** - * @desc [mutator] - * @author fenris - */ - pop(): lib_plankton.pod.class_pod; - /** - * @desc [accessor] - * @author fenris - */ - forEach(function_: (element: type_element) => void): void; - /** - * @desc [accessor] - * @author fenris - */ - map(transformator: (element: type_element) => type_element_, equality?: (x: type_element_, y: type_element_) => boolean): class_set; - /** - * @desc [accessor] - * @author fenris - */ - filter(predicate: (element: type_element) => boolean): class_set; - /** - * @desc [accessor] - * @author fenris - */ - dump(): Array; - /** - * @desc [accessor] - * @author fenris - */ - subset(set: class_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - superset(set: class_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - equals(set: class_set): boolean; - /** - * @desc [accessor] - * @author fenris - */ - toString(): string; - /** - * @desc [accessor] - * @author fenris - */ - empty(): boolean; - /** - * @desc [accessor] - * @author fenris - */ - union(set: class_set): class_set; - /** - * @desc [accessor] - * @author fenris - */ - intersection(set: class_set): class_set; - /** - * @desc [accessor] - * @author fenris - */ - difference(set: class_set): class_set; - /** - * @desc [accessor] - * @author fenris - */ - symmetric_difference(set: class_set): class_set; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _collate(set: class_set): boolean; - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _show(): string; - /** - * @author fenris - */ - static union_all(sets: Array>): class_set; - /** - * @author fenris - */ - static intersection_all(sets: Array>): class_set; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - type type_stack = { - elements: Array; - }; - /** - * @author fenris - */ - function stack_construct(): type_stack; - /** - * @author fenris - */ - function stack_size(subject: type_stack): int; - /** - * @author fenris - */ - function stack_scan(subject: type_stack): type_element; - /** - * @author fenris - */ - function stack_take(subject: type_stack): type_element; - /** - * @author fenris - */ - function stack_give(subject: type_stack, element: type_element): void; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - abstract class class_stack implements interface_memory { - /** - * @author fenris - */ - protected subject: type_stack; - /** - * @author fenris - */ - constructor(); - /** - * @override - * @author fenris - */ - size(): int; - /** - * @override - * @author fenris - */ - scan(): type_element; - /** - * @override - * @author fenris - */ - take(): type_element; - /** - * @override - * @author fenris - */ - give(element: type_element): void; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - type type_queue = { - elements: Array; - }; - /** - * @author fenris - */ - function queue_construct(): type_queue; - /** - * @author fenris - */ - function queue_size(subject: type_queue): int; - /** - * @author fenris - */ - function queue_scan(subject: type_queue): type_element; - /** - * @author fenris - */ - function queue_take(subject: type_queue): type_element; - /** - * @author fenris - */ - function queue_give(subject: type_queue, element: type_element): void; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - abstract class class_queue implements interface_memory { - /** - * @author fenris - */ - protected subject: type_queue; - /** - * @author fenris - */ - constructor(); - /** - * @override - * @author fenris - */ - size(): int; - /** - * @override - * @author fenris - */ - scan(): type_element; - /** - * @override - * @author fenris - */ - take(): type_element; - /** - * @override - * @author fenris - */ - give(element: type_element): void; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - type type_simplemap = { - memory: { - [key: string]: type_value; - }; - }; - /** - * @author fenris - */ - function simplemap_construct(): type_simplemap; - /** - * @author fenris - */ - function simplemap_has(subject: type_simplemap, key: string): boolean; - /** - * @author fenris - */ - function simplemap_get_safe(subject: type_simplemap, key: string): lib_plankton.pod.type_pod; - /** - * @author fenris - */ - function simplemap_get(subject: type_simplemap, key: string, fallback?: lib_plankton.pod.type_pod): type_value; - /** - * @author fenris - */ - function simplemap_set(subject: type_simplemap, key: string, value: type_value): void; - /** - * @author fenris - */ - function simplemap_delete(subject: type_simplemap, key: string): void; - /** - * @author fenris - */ - function simplemap_clear(subject: type_simplemap): void; - /** - * @author fenris - */ - function simplemap_forEach(subject: type_simplemap, function_: (value?: type_value, key?: string) => void): void; - /** - * @author fenris - */ - function simplemap_from_object(object: { - [key: string]: type_value; - }): type_simplemap; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_simplemap extends class_mapbase implements interface_map { - /** - * @author fenris - * @desc [attribute] - */ - protected subject: type_simplemap; - /** - * @author fenris - */ - static make(): class_simplemap; - /** - * @author fenris - */ - static from_object(object: { - [key: string]: type_value; - }): class_simplemap; - /** - * @author fenris - * @desc [constructor] - */ - protected constructor(subject?: type_simplemap); - /** - * @author fenris - * @implementation - */ - has(key: string): boolean; - /** - * @author fenris - * @implementation - */ - get(key: string, fallback?: lib_plankton.pod.class_pod): type_value; - /** - * @author fenris - * @implementation - */ - set(key: string, value: type_value): void; - /** - * @author fenris - * @implementation - */ - delete(key: string): void; - /** - * @author fenris - * @implementation - */ - forEach(procedure: (value?: type_value, key?: string) => void): void; - } -} -declare namespace lib_plankton.structures { - /** - */ - type type_pair = { - key: type_key; - value: type_value; - }; - /** - * @author fenris - * @desc we base the hashmap on a simplemap, whos keys are the hashes and whos values are the key/value-pairs - */ - export type type_hashmap = { - core: type_simplemap>; - hashing: ((key: type_key) => string); - }; - /** - * @author fenris - */ - export function hashmap_construct(hashing: ((key: type_key) => string), pairs: Array<{ - key: type_key; - value: type_value; - }>): type_hashmap; - /** - * @author fenris - */ - export function hashmap_has(subject: type_hashmap, key: type_key): boolean; - /** - * @author fenris - */ - export function hashmap_get(subject: type_hashmap, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; - /** - * @author fenris - */ - export function hashmap_set(subject: type_hashmap, key: type_key, value: type_value): void; - /** - * @author fenris - */ - export function hashmap_delete(subject: type_hashmap, key: type_key): void; - /** - * @author fenris - */ - export function hashmap_clear(subject: type_hashmap): void; - /** - * @author fenris - */ - export function hashmap_forEach(subject: type_hashmap, procedure: ((value?: type_value, key?: type_key) => void)): void; - /** - * @author fenris - */ - export function hashmap_dump(subject: type_hashmap): Array>; - export {}; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_hashmap extends class_mapbase implements interface_map { - /** - * @author fenris - * @desc [attribute] - */ - protected subject: type_hashmap; - /** - * @author fenris - * @desc [constructor] - */ - constructor(hashing?: ((key: type_key) => string), pairs?: Array<{ - key: type_key; - value: type_value; - }>); - /** - * @author fenris - * @implementation - */ - has(key: type_key): boolean; - /** - * @author fenris - * @implementation - */ - get(key: type_key, fallback?: lib_plankton.pod.class_pod): type_value; - /** - * @author fenris - * @implementation - */ - set(key: type_key, value: type_value): void; - /** - * @author fenris - * @implementation - */ - delete(key: type_key): void; - /** - * @author fenris - * @implementation - */ - forEach(procedure: ((value?: type_value, key?: type_key) => void)): void; - } -} -declare namespace lib_plankton.structures { - /** - */ - type type_collation = ((key1: type_key, key2: type_key) => boolean); - /** - */ - export type type_collatemap = { - pairs: Array<{ - key: type_key; - value: type_value; - }>; - }; - /** - */ - export function collatemap_construct(): type_collatemap; - /** - */ - export function collatemap_has(collation: type_collation, subject: type_collatemap, key: type_key): boolean; - /** - * @todo use .find - */ - export function collatemap_get(collation: type_collation, subject: type_collatemap, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; - /** - */ - export function collatemap_set(collation: type_collation, subject: type_collatemap, key: type_key, value: type_value): void; - /** - */ - export function collatemap_delete(collation: type_collation, subject: type_collatemap, key: type_key): void; - /** - */ - export function collatemap_forEach(subject: type_collatemap, function_: ((value?: type_value, key?: type_key) => void)): void; - export {}; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_collatemap extends class_mapbase implements interface_map { - /** - * @author fenris - * @desc [attribute] - */ - protected collation: (key1: type_key, key2: type_key) => boolean; - /** - * @author fenris - * @desc [attribute] - */ - protected subject: type_collatemap; - /** - * @author fenris - * @desc [constructor] - */ - constructor(collation?: (key1: type_key, key2: type_key) => boolean); - /** - * @author fenris - * @implementation - */ - has(key: type_key): boolean; - /** - * @author fenris - * @implementation - */ - get(key: type_key, fallback?: lib_plankton.pod.class_pod): type_value; - /** - * @author fenris - * @implementation - */ - set(key: type_key, value: type_value): void; - /** - * @author fenris - * @implementation - */ - delete(key: type_key): void; - /** - * @author fenris - * @implementation - */ - forEach(procedure: (value?: type_value, key?: type_key) => void): void; - } - /** - * @author fenris - * @deprecated - */ - var class_map: typeof class_collatemap; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - type type_edge = { - from: type_node; - to: type_node; - }; - /** - * @author fenris - */ - class class_graph { - /** - * @author fenris - */ - protected equality: (node1: type_node, node2: type_node) => boolean; - /** - * @author fenris - */ - protected nodes: Array; - /** - * @author fenris - */ - protected edges: Array>; - /** - * @author fenris - */ - constructor(equality?: (node1: type_node, node2: type_node) => boolean, nodes?: Array, edges?: Array>); - /** - * @desc [accessor] [getter] - * @author fenris - */ - nodes_get(): Array; - /** - * @desc [mutator] - * @author fenris - */ - add_node(node: type_node): void; - /** - * @desc [accessor] [getter] - * @author fenris - */ - edges_get(): Array>; - /** - * @desc [mutator] - * @author fenris - */ - add_edge(edge: type_edge): void; - /** - * @desc [accessor] - * @author fenris - */ - has(node: type_node): boolean; - /** - * @desc [accessor] - * @author fenris - */ - outgoing(node: type_node): Array>; - /** - * @desc [accessor] - * @author fenris - */ - incoming(node: type_node): Array>; - /** - * @desc [accessor] - * @author fenris - */ - without(pivot: type_node): class_graph; - /** - * @desc [accessor] returns the topologic sorting of the nodes (if it exists) - * @author fenris - */ - topsort(): Array; - /** - * @desc [accessor] returns the reduced version of a graph representing an order relation (implicit transitivity) - * @author fenris - */ - hasse(): class_graph; - /** - * @author fenris - */ - output_dot({ "extract_id": extract_id, "extract_label": extract_label, "rotate": rotate, }?: { - extract_id?: (node: type_node) => string; - extract_label?: (node: type_node) => string; - rotate?: boolean; - }): Object; - } -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - const relation_le: string; - const relation_ge: string; - const relation_lt: string; - const relation_gt: string; - const relation_eq: string; - /** - * @author fenris - */ - type type_binnode = { - data: type_data; - left: type_binnode; - right: type_binnode; - depth: int; - }; - /** - * @author fenris - */ - type type_bintree = { - root: type_binnode; - }; - /** - * @author fenris - */ - function bintree_construct(): type_bintree; - /** - * @author fenris - */ - function bintree_depth(subject: type_bintree): int; - /** - * @author fenris - * @todo remove later on - */ - function bintree_check_depths(subject: type_bintree): boolean; - /** - * @author fenris - */ - function bintree_insert(compare: (x: type_data, y: type_data) => boolean, subject: type_bintree, data: type_data, rebalance?: boolean): void; - /** - * @author fenris - */ - function bintree_search(compare: (x: type_data, y: type_data) => boolean, subject: type_bintree, data: type_data, relation?: string): Array; - /** - * @author fenris - * @deprecated only used for AVL-Tree-Index atm. - */ - function bintree_find(compare: (x: type_data, y: type_data) => boolean, subject: type_bintree, data: type_data): type_data; - /** - * @author fenris - */ - function bintree_traverse(subject: type_bintree): Array; - /** - * @author fenris - */ - function bintree_show(show_data: (data: type_data) => string, subject: type_bintree): string; - /** - * @author fenris - * @todo tidy up or remove - */ - function bintree_to_graph(subject: type_bintree): class_graph; -} -declare namespace lib_plankton.structures { - /** - * @author fenris - */ - class class_bintree { - /** - * @author fenris - */ - protected subject: type_bintree; - /** - * @author fenris - */ - protected compare: (x: type_data, y: type_data) => boolean; - /** - * @author fenris - */ - constructor(compare?: (x: type_data, y: type_data) => boolean); - /** - * @author fenris - */ - depth(): int; - /** - * @author fenris - */ - insert(data: type_data, rebalance?: boolean): void; - /** - * @author fenris - */ - delete(data: type_data): void; - /** - * @author fenris - */ - search(relation: string, data: type_data): Array; - /** - * @author fenris - */ - traverse(): Array; - /** - * @author fenris - */ - show(): string; - } -} -declare namespace lib_plankton.json { - /** - */ - type type_source = any; - /** - */ - type type_target = string; - /** - * @author fenris - */ - export function encode(source: type_source, options?: { - formatted?: boolean; - }): type_target; - /** - * @author fenris - */ - export function decode(target: type_target): type_source; - /** - * @author fenris - */ - export function implementation_code(): lib_plankton.code.type_code; - export {}; -} -declare namespace lib_plankton.json { - /** - * @author fenris - */ - class class_json implements lib_plankton.code.interface_code { - /** - * @author fenris - */ - constructor(); - /** - * @implementation - * @author fenris - */ - encode(x: any): string; - /** - * @implementation - * @author fenris - */ - decode(x: string): any; - } -} declare module lib_et { /** * @desc type of extended timestamp @@ -4262,118 +3559,6 @@ declare namespace lib_plankton.http { decode(x: string): type_response; } } -declare namespace lib_plankton.object { - /** - * @author fenris - */ - function fetch(object: Object, fieldname: string, fallback?: type_value, escalation?: int): type_value; - /** - * @author fenris - */ - function map(object_from: { - [key: string]: type_from; - }, transformator: (value_from: type_from, key?: string) => type_to): { - [key: string]: type_to; - }; - /** - * @desc gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück - * @author fenris - */ - function filter(object_from: { - [key: string]: type_value; - }, predicate: (value_from: type_value, key?: string) => boolean): { - [key: string]: type_value; - }; - /** - * @desc wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um - * @author fenris - */ - function from_array(array: Array<{ - key: string; - value: type_value; - }>): { - [key: string]: type_value; - }; - /** - * @desc wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um - * @author fenris - */ - function to_array(object: { - [key: string]: type_value; - }): Array<{ - key: string; - value: type_value; - }>; - /** - * @desc gibt eine Liste von Schlüsseln eines Objekts zurück - * @author fenris - */ - function keys(object: { - [key: string]: any; - }): Array; - /** - * @desc gibt eine Liste von Werten eines Objekts zurück - * @author fenris - */ - function values(object: { - [key: string]: type_value; - }): Array; - /** - * @desc liest ein Baum-artiges Objekt an einer bestimmten Stelle aus - * @author fenris - */ - function path_read(object: Object, path: string, fallback?: type_value, escalation?: int): type_value; - /** - * @desc schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt - * @author fenris - */ - function path_write(object: Object, path: string, value: type_value, construct?: boolean): void; - /** - * @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: Object, pattern: Object, collate?: typeof instance_collate): boolean; - /** - * @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: any, separator?: string, key_for_element?: (index: int) => string): Object; - /** - * @author fenris - */ - function clash(x: { - [key: string]: any; - }, y: { - [key: string]: any; - }, { "overwrite": overwrite, "hooks": { "existing": hook_existing, }, }?: { - overwrite?: boolean; - hooks?: { - existing?: (key?: string, value_old?: any, value_new?: any) => void; - }; - }): { - [key: string]: any; - }; - /** - * @author fenris - */ - function patch(core: Object, mantle: Object, deep?: boolean, path?: string): void; - /** - * @author fenris - */ - function patched(core: Object, mantle: Object, deep?: boolean): Object; - /** - * @author fenris - */ - function attached(object: Object, key: string, value: any): Object; - /** - * @author fenris - */ - function copy(object: Object): Object; -} declare namespace lib_plankton.markdown { /** * @author fenris @@ -4991,3 +4176,14 @@ declare namespace lib_plankton.args { }): string; } } +declare namespace lib_plankton.bcrypt { + /** + */ + function compute(input: string, options?: { + rounds?: int; + salt?: (null | string); + }): Promise; + /** + */ + function compare(password_shall_image: string, password_is: string): Promise; +} diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index ba2cbb8..c3044b5 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -2355,6 +2355,2113 @@ var lib_plankton; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function inverse_encode(decode, to) { + return decode(to); + } + code.inverse_encode = inverse_encode; + /** + * @author fenris + */ + function inverse_decode(encode, from) { + return encode(from); + } + code.inverse_decode = inverse_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_inverse = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_inverse(subject) { + this.subject = subject; + } + /** + * @implementation + * @author fenris + */ + class_code_inverse.prototype.encode = function (to) { + var _this = this; + return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to); + }; + /** + * @implementation + * @author fenris + */ + class_code_inverse.prototype.decode = function (from) { + var _this = this; + return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from); + }; + return class_code_inverse; + }()); + code.class_code_inverse = class_code_inverse; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function pair_encode(encode_first, encode_second, from) { + var between = encode_first(from); + var to = encode_second(between); + return to; + } + code.pair_encode = pair_encode; + /** + * @author fenris + */ + function pair_decode(decode_first, decode_second, to) { + var between = decode_second(to); + var from = decode_first(between); + return from; + } + code.pair_decode = pair_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_pair = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_pair(first, second) { + this.first = first; + this.second = second; + } + /** + * @implementation + * @author fenris + */ + class_code_pair.prototype.encode = function (from) { + var _this = this; + return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from); + }; + /** + * @implementation + * @author fenris + */ + class_code_pair.prototype.decode = function (to) { + var _this = this; + return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to); + }; + return class_code_pair; + }()); + code.class_code_pair = class_code_pair; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + function chain_encode(encode_links, from) { + var value = from; + encode_links + .forEach(function (link) { + value = link(value); + }); + return value; + } + code.chain_encode = chain_encode; + /** + * @author fenris + */ + function chain_decode(decode_links, to) { + var value = to; + decode_links + .reverse() + .forEach(function (link) { + value = link(value); + }); + return value; + } + code.chain_decode = chain_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_chain = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_chain(links) { + this.links = links; + } + /** + * @implementation + * @author fenris + */ + class_code_chain.prototype.encode = function (from) { + return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from); + }; + /** + * @implementation + * @author fenris + */ + class_code_chain.prototype.decode = function (to) { + return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to); + }; + return class_code_chain; + }()); + code.class_code_chain = class_code_chain; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author Christian Fraß + */ + function flatten_encode(from, keys) { + if (keys === void 0) { keys = null; } + if (keys === null) { + if (from.length > 0) { + keys = Object.keys(from[0]); + } + else { + throw (new Error("encoding impossible")); + } + } + return { + "keys": keys, + "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) + }; + } + code.flatten_encode = flatten_encode; + /** + * @author Christian Fraß + */ + function flatten_decode(to) { + return (to.data + .map(function (dataset) { + var dataset_ = {}; + dataset + .forEach(function (value, index) { + var name = to.keys[index]; + dataset_[name] = value; + }); + return dataset_; + })); + } + code.flatten_decode = flatten_decode; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:code«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var code; + (function (code) { + /** + * @author fenris + */ + var class_code_flatten = /** @class */ (function () { + /** + * @author fenris + */ + function class_code_flatten() { + } + /** + * @implementation + * @author fenris + */ + class_code_flatten.prototype.encode = function (x) { + return code.flatten_encode(x); + }; + /** + * @implementation + * @author fenris + */ + class_code_flatten.prototype.decode = function (x) { + return code.flatten_decode(x); + }; + return class_code_flatten; + }()); + code.class_code_flatten = class_code_flatten; + })(code = lib_plankton.code || (lib_plankton.code = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:json«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:json« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:json« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:json«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var json; + (function (json) { + /** + * @author fenris + */ + function encode(source, options = {}) { + options = Object.assign({ + "formatted": false, + }, options); + return JSON.stringify(source, undefined, (options.formatted ? "\t" : undefined)); + } + json.encode = encode; + /** + * @author fenris + */ + function decode(target) { + return JSON.parse(target); + } + json.decode = decode; + /** + * @author fenris + */ + function implementation_code() { + return { + "encode": x => encode(x), + "decode": decode, + }; + } + json.implementation_code = implementation_code; + })(json = lib_plankton.json || (lib_plankton.json = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:json«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:json« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:json« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:json«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var json; + (function (json) { + /** + * @author fenris + */ + class class_json { + /** + * @author fenris + */ + constructor() { + } + /** + * @implementation + * @author fenris + */ + encode(x) { + return json.encode(x); + } + /** + * @implementation + * @author fenris + */ + decode(x) { + return json.decode(x); + } + } + json.class_json = class_json; + })(json = lib_plankton.json || (lib_plankton.json = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:file«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var file; + (function (file) { + /** + * @author fenris + */ + function exists(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.stat(path, function (error, stats) { + if (error) { + resolve(false); + } + else { + resolve(true); + } + }); + })); + } + file.exists = exists; + /** + * @author fenris + */ + function read(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.readFile(path, { + "encoding": "utf8", + "flag": "r" + }, function (error, content) { + if (error == null) { + resolve(content); + } + else { + reject(error); + } + }); + })); + } + file.read = read; + /** + * @author fenris + */ + function read_buffer(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.readFile(path, { + "flag": "r" + }, function (error, content) { + if (error == null) { + resolve(content); + } + else { + reject(error); + } + }); + })); + } + file.read_buffer = read_buffer; + /** + * @author fenris + */ + function read_stdin() { + return (new Promise(function (resolve, reject) { + var input_raw = ""; + process.stdin.setEncoding("utf8"); + process.stdin.on("readable", function () { + var chunk; + while ((chunk = process.stdin.read()) !== null) { + input_raw += chunk; + } + }); + process.stdin.on("end", function () { + resolve(input_raw); + }); + })); + } + file.read_stdin = read_stdin; + /** + * @author fenris + */ + function write(path, content, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "encoding": "utf-8" + }, options); + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.writeFile(path, content, { + "encoding": options.encoding, + "flag": "w" + }, function (error) { + if (error == null) { + resolve(undefined); + } + else { + reject(error); + } + }); + })); + } + file.write = write; + /** + * @author fenris + */ + function write_buffer(path, content, options) { + if (options === void 0) { options = {}; } + options = Object.assign({}, options); + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.writeFile(path, content, { + "flag": "w" + }, function (error) { + if (error == null) { + resolve(undefined); + } + else { + reject(error); + } + }); + })); + } + file.write_buffer = write_buffer; + /** + */ + function delete_(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.unlink(path, function () { + resolve(undefined); + }); + })); + } + file.delete_ = delete_; + })(file = lib_plankton.file || (lib_plankton.file = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:object«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»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 . + */ +var lib_plankton; +(function (lib_plankton) { + var object; + (function (object_1) { + /** + * @author fenris + * @deprecated use the "??" operator instead + */ + function fetch(object, fieldname, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "fallback": null, + "escalation": 1 + }, options); + if ((fieldname in object) + && + (object[fieldname] !== undefined)) { + return object[fieldname]; + } + else { + if (!options.escalate) { + return options.fallback; + } + else { + throw (new Error("field '" + fieldname + "' not in structure")); + } + } + } + object_1.fetch = fetch; + /** + */ + function map(object_from, transformator) { + return (Object.fromEntries(Object.entries(object_from) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return ([key, transformator(value, key)]); + }))); + } + object_1.map = map; + /** + * gibt ein Objekt mit bestimmten Einträgen des Eingabe-Objekts zurück + */ + function filter(object_from, predicate) { + return (Object.fromEntries(Object.entries(object_from) + .filter(function (_a) { + var key = _a[0], value = _a[1]; + return predicate(value, key); + }))); + } + object_1.filter = filter; + /** + * wandelt ein Array mit Einträgen der Form {key,value} in ein entsprechendes Objekt um + * + * @deprecated use Object.fromEntries instead! + */ + function from_array(array) { + return (Object.fromEntries(array + .map(function (_a) { + var key = _a["key"], value = _a["value"]; + return ([key, value]); + }))); + } + object_1.from_array = from_array; + /** + * wandelt ein Objekt in ein entsprechendes Array mit Einträgen der Form {key,value} um + * + * @deprecated use Object.entries insetad! + */ + function to_array(object) { + return (Object.entries(object) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return ({ "key": key, "value": value }); + })); + } + object_1.to_array = to_array; + /** + * gibt eine Liste von Schlüsseln eines Objekts zurück + * + * @deprecated use Object.keys instead! + */ + function keys(object) { + return Object.keys(object); + } + object_1.keys = keys; + /** + * gibt eine Liste von Werten eines Objekts zurück + * + * @deprecated use Object.values instead! + */ + function values(object) { + return Object.values(object); + } + object_1.values = values; + /** + * liest ein Baum-artiges Objekt an einer bestimmten Stelle aus + */ + function path_read(object, path, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "fallback": null, + "escalate": false + }, options); + var steps = ((path.length == 0) ? [] : path.split(".")); + if (steps.length == 0) { + throw (new Error("empty path")); + } + else { + var position_1 = object; + var reachable = ((position_1 != null) + && + (steps.slice(0, steps.length - 1) + .every(function (step) { + position_1 = lib_plankton.object.fetch(position_1, step, { + "fallback": null, + "escalate": false + }); + return (position_1 != null); + }))); + if (reachable) { + return lib_plankton.object.fetch(position_1, steps[steps.length - 1], { + "fallback": options.fallback, + "escalate": options.escalate + }); + } + else { + return lib_plankton.object.fetch({}, "_dummy_", { + "fallback": options.fallback, + "escalate": options.escalate + }); + } + } + } + object_1.path_read = path_read; + /** + * schreibt einen Wert an eine bestimmte Stelle in einem Baum-artigen Objekt + */ + function path_write(object, path, value, construct) { + if (construct === void 0) { construct = true; } + var steps = ((path.length == 0) ? [] : path.split(".")); + if (steps.length == 0) { + throw (new Error("empty path")); + } + else { + var position_2 = object; + var reachable = steps.slice(0, steps.length - 1).every(function (step) { + var position_ = lib_plankton.object.fetch(position_2, step, { + "fallback": null, + "escalate": false + }); + if (position_ == null) { + if (construct) { + position_2[step] = {}; + position_2 = position_2[step]; + return true; + } + else { + return false; + } + } + else { + position_2 = position_; + return true; + } + }); + if (reachable) { + position_2[steps[steps.length - 1]] = value; + } + else { + throw (new Error("path '" + path + "' does not exist and may not be constructed")); + } + } + } + object_1.path_write = path_write; + /** + * prüft ob ein Objekt einem bestimmten Muster entspricht + * + * @deprecated not very useful + */ + function matches(object, pattern, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "collate": instance_collate + }, options); + return (Object.entries(pattern) + .every(function (_a) { + var key = _a[0], value = _a[1]; + return options.collate(value, object[key]); + })); + } + object_1.matches = matches; + /** + * erzeugt eine Projektion eines Baum-artigen Objekts in ein Listen-artiges Objekt + */ + function flatten(value, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "separator": ".", + "key_for_array_element": (function (index) { return ("element_" + index.toFixed(0)); }) + }, options); + var integrate = function (result, key, value) { + if (value == null) { + result[key] = value; + } + else { + // primitive Werte direkt übernehmen + if (typeof (value) != "object") { + result[key] = value; + } + // sonst durch rekursiven Aufruf die flache Variante des Wertes ermitteln und einarbeiten + else { + var result_ = flatten(value, { + "separator": options.separator, + "key_for_array_element": options.key_for_array_element + }); + Object.entries(result_).forEach(function (_a) { + var key_ = _a[0], value_ = _a[1]; + result[(key + options.separator + key_)] = value_; + }); + } + } + }; + if ((value === null) + || + (value === undefined)) { + return null; + } + else { + var result_1 = {}; + if (typeof (value) != "object") { + result_1["value"] = value; + } + else { + if (value instanceof Array) { + value.forEach(function (element, index) { + integrate(result_1, options.key_for_array_element(index), element); + }); + } + else { + Object.entries(value).forEach(function (_a) { + var key = _a[0], value = _a[1]; + integrate(result_1, key, value); + }); + } + } + return result_1; + } + } + object_1.flatten = flatten; + /** + * @deprecated use Object.assign instead! + */ + function clash(x, y, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "overwrite": true, + "hooks": { + "existing": function (key, value_old, value_new) { + lib_plankton.log.warning("object_clash_field_already_defined", { + "key": key + }); + } + } + }, options); + var z = {}; + Object.keys(x).forEach(function (key) { + z[key] = x[key]; + }); + Object.keys(y).forEach(function (key) { + if (key in z) { + if (options.hooks.existing != null) { + options.hooks.existing(key, z[key], y[key]); + } + if (options.overwrite) { + z[key] = y[key]; + } + } + else { + z[key] = y[key]; + } + }); + return z; + } + object_1.clash = clash; + /** + * @deprecated use Object.assign instead! + */ + function patch(core, mantle, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "deep": true, + "path": null + }, options); + if (mantle == null) { + lib_plankton.log.warning("object_patch_mantle_is_null", { + "core": core + }); + } + else { + Object.keys(mantle).forEach(function (key) { + var path_ = ((options.path == null) + ? + key + : + (options.path + "." + key)); + var value_mantle = mantle[key]; + if (!(key in core)) { + if ((typeof (value_mantle) == "object") + && + (value_mantle != null) + && + options.deep) { + if (value_mantle instanceof Array) { + core[key] = []; + value_mantle.forEach(function (element) { + if ((typeof (element) == "object") + && + (element != null)) { + var element_ = {}; + patch(element_, element); + core[key].push(element_); + } + else { + core[key].push(element); + } + }); + } + else { + core[key] = {}; + patch(core[key], value_mantle, { + "deep": options.deep, + "path": path_ + }); + } + } + else { + core[key] = value_mantle; + } + } + else { + var value_core = core[key]; + if (typeof (value_core) == typeof (value_mantle)) { + if ((typeof (value_mantle) == "object") + && + (value_mantle != null) + && + options.deep) { + patch(core[key], value_mantle, { + "deep": options.deep, + "path": path_ + }); + } + else { + core[key] = value_mantle; + } + } + else { + if ((value_core != null) + && + (value_mantle != null)) { + lib_plankton.log.warning("object_path_different_shapes", { + "path": path_, + "core_type": typeof (value_core), + "mantle_type": typeof (value_mantle) + }); + } + core[key] = value_mantle; + // throw (new Error(message)); + } + } + }); + } + } + object_1.patch = patch; + /** + * @deprecated use Object.assign instead! + */ + function patched(core, mantle, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "deep": true + }, options); + var result = {}; + patch(result, core, { "deep": options.deep }); + patch(result, mantle, { "deep": options.deep }); + return result; + } + object_1.patched = patched; + /** + * @deprecated use Object.assign instead! + */ + function attached(object, key, value) { + var mantle = {}; + mantle[key] = value; + return patched(object, mantle, { "deep": false }); + } + object_1.attached = attached; + /** + * @author fenris + */ + function copy(object) { + return patched({}, object); + } + object_1.copy = copy; + })(object = lib_plankton.object || (lib_plankton.object = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:pair«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:pair« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:pair« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:pair«. If not, see . + */ +/* +This file is part of »bacterio-plankton:pair«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:pair« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:pair« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:pair«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var pair; + (function (pair_1) { + /** + */ + function swap(pair) { + return { + "first": pair.second, + "second": pair.first + }; + } + pair_1.swap = swap; + /** + */ + function show(pair, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "show_first": instance_show, + "show_second": instance_show + }, options); + return ("(" + + + options.show_first(pair.first) + + + "," + + + options.show_second(pair.second) + + + ")"); + } + pair_1.show = show; + })(pair = lib_plankton.pair || (lib_plankton.pair = {})); +})(lib_plankton || (lib_plankton = {})); +"use strict"; +/* +This file is part of »bacterio-plankton:list«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:list« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:list« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:list«. If not, see . + */ +/* +This file is part of »bacterio-plankton:list«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:list« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:list« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:list«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var list; + (function (list_1) { + /** + * returns a certain list of integer numbers + */ + function range(from, to, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "step": 1 + }, options); + var list = []; + for (var value = from; value <= to; value += options.step) { + list.push(value); + } + return list; + } + list_1.range = range; + /** + * returns a certain list of consecutiv integer numbers, beginning with 0 + */ + function sequence(length) { + return range(0, length - 1); + } + list_1.sequence = sequence; + /** + */ + function from_iterator(iterator) { + var list = []; + // @ts-ignore + for (var _i = 0, iterator_1 = iterator; _i < iterator_1.length; _i++) { + var element = iterator_1[_i]; + list.push(element); + } + return list; + } + list_1.from_iterator = from_iterator; + /** + */ + function is_empty(list) { + return (list.length <= 0); + } + list_1.is_empty = is_empty; + /** + * combines two lists into one + * + * @param {boolean} [options.cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true + */ + function zip(list_first, list_second, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "cut": true + }, options); + var empty_first = is_empty(list_first); + var empty_second = is_empty(list_second); + if (empty_first || empty_second) { + if (options.cut || (empty_first && empty_second)) { + return []; + } + else { + throw (new Error("lists have different lengths")); + } + } + else { + return ([{ "first": list_first[0], "second": list_second[0] }] + .concat(zip(list_first.slice(1), list_second.slice(1), { + "cut": options.cut + }))); + } + } + list_1.zip = zip; + /** + * checks whether two lists are equal + * + * @todo define common function "equals" and default predicate to + */ + function equals(list1, list2, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "collate_element": instance_collate + }, options); + if (list1.length == list2.length) { + return (zip(list1, list2, { "cut": true }) + .every(function (pair) { return options.collate_element(pair.first, pair.second); })); + } + else { + return false; + } + } + list_1.equals = equals; + /** + * creates a list with the elements from the input list, which fulfil a certain predicate (~ filter) + */ + function keep(list, predicate) { + return (list + .filter(function (element, index) { return predicate(element); })); + } + list_1.keep = keep; + /** + * creates a list with the elements from the input list, which do not fulfil a certain predicate (~ dual filter) + */ + function drop(list, predicate) { + return (list + .filter(function (element, index) { return (!predicate(element)); })); + } + list_1.drop = drop; + /** + */ + function filter_inplace(list, predicate) { + var index = 0; + while (index < list.length) { + var element = list[index]; + if (predicate(element)) { + index += 1; + } + else { + list.splice(index, 1); + } + } + } + list_1.filter_inplace = filter_inplace; + /** + * returns a list with no duplicates (like unix' "unique") + */ + function cleaned(list, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "collate_element": instance_collate + }, options); + var list_ = []; + list.forEach(function (element) { + if (!list_.some(function (element_) { return options.collate_element(element, element_); })) { + list_.push(element); + } + else { + // do nothing + } + }); + return list_; + } + list_1.cleaned = cleaned; + /** + * creates a binary partition of the list according to a given predicate + */ + function separate(list, predicate) { + return (list + .reduce(function (seperation, element) { + return (predicate(element) + ? { "yes": seperation.yes.concat([element]), "no": seperation["no"] } + : { "yes": seperation.yes, "no": seperation["no"].concat([element]) }); + }, { "yes": [], "no": [] })); + } + list_1.separate = separate; + ; + /** + */ + function clone(list) { + return keep(list, function (x) { return true; }); + } + list_1.clone = clone; + /** + */ + function reversed(list) { + var list_ = clone(list); + list_.reverse(); + return list_; + } + list_1.reversed = reversed; + /** + * @todo use Array.toSorted? + */ + function sorted(list, options) { + options = Object.assign({ + "compare_element": instance_compare + }, options); + var list_ = clone(list); + list_.sort(function (x, y) { return (options.compare_element(x, y) ? -1 : +1); }); + return list_; + } + list_1.sorted = sorted; + /** + * die Liste in gleich große Blöcke zerlegen + */ + function chop(list, chunk_size) { + var chunks = []; + var index = 0; + while (index < list.length) { + var chunk = list.slice(index, Math.min(list.length, index + chunk_size)); + index += chunk_size; + chunks.push(chunk); + } + return chunks; + } + list_1.chop = chop; + /** + */ + function group(list, collate_element) { + var result = []; + list.forEach(function (element) { + var target = result.find( + // @ts-ignore + function (group) { return collate_element(group[0], element); }); + if (target === undefined) { + target = []; + result.push(target); + } + target.push(element); + }); + return result; + } + list_1.group = group; + /** + */ + function has(list, predicate) { + return (list.find(predicate) !== undefined); + } + list_1.has = has; + /** + * @deprecate use Array.includes or Array.some + */ + function contains(list, element, options) { + options = Object.assign({ + "collate": instance_collate + }, options); + return has(list, function (element_) { return options.collate_element(element_, element); }); + } + list_1.contains = contains; + /** + * retrieves the element and its index of the list, which has the maximum value + */ + function max(list, target_function, options) { + options = Object.assign({ + "compare_value": instance_compare + }, options); + if (is_empty(list)) { + throw (new Error("the max-arg of an empty list is not defined")); + } + else { + return (list + .reduce(function (result, element, index) { + var value = target_function(element); + if ((result == null) + || + (!options.compare_value(value, result.value))) { + return { "index": index, "element": element, "value": value }; + } + else { + return result; + } + }, null)); + } + } + list_1.max = max; + /** + * retrieves the element and its index of the list, which has the mininum value + */ + function min(list, target_function, options) { + options = Object.assign({ + "compare_value": instance_compare + }, options); + return max(list, target_function, { + "compare_value": function (x, y) { return options.compare_value(y, x); } + }); + } + list_1.min = min; + /** + * implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)" + * example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]] + */ + function distribute(lists) { + if (is_empty(lists)) { + return [[]]; + } + else { + var subresult_1 = distribute(lists.slice(1)); + return (lists[0] + .map(function (element) { return subresult_1.map(function (list) { return [element].concat(list); }); }) + .reduce(function (x, y) { return x.concat(y); }, [])); + } + } + list_1.distribute = distribute; + /** + */ + function contrast(list_left, extract_key_left, list_right, extract_key_right) { + var gathering = {}; + list_left.forEach(function (source_left) { + var _a; + var key = extract_key_left(source_left); + gathering[key] = Object.assign(((_a = gathering[key]) !== null && _a !== void 0 ? _a : {}), { "left": source_left }); + }); + list_right.forEach(function (source_right) { + var _a; + var key = extract_key_right(source_right); + gathering[key] = Object.assign(((_a = gathering[key]) !== null && _a !== void 0 ? _a : {}), { "right": source_right }); + }); + var result = { + "both": [], + "only_left": [], + "only_right": [] + }; + Object.entries(gathering).forEach(function (_a) { + var key = _a[0], value = _a[1]; + if ("left" in value) { + if ("right" in value) { + result.both.push({ "key": key, "left": value.left, "right": value.right }); + } + else { + result.only_left.push({ "key": key, "left": value.left }); + } + } + else { + if ("right" in value) { + result.only_right.push({ "key": key, "right": value.right }); + } + else { + // impossible + // do nothing + } + } + }); + return result; + } + list_1.contrast = contrast; + })(list = lib_plankton.list || (lib_plankton.list = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:conf«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:conf« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:conf« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:conf«. If not, see . + */ +/* +This file is part of »bacterio-plankton:conf«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:conf« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:conf« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:conf«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var conf; + (function (conf) { + /** + */ + function adapt_primitive(schema, value) { + if (value === undefined) { + if (!("default" in schema)) { + return { + "reports": [ + { + "incident": "neither explicit value provided nor default value specified", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return { + "reports": [], + "result": lib_plankton.pod.make_filled(schema.default), + }; + } + } + else { + if (value === null) { + if (("nullable" in schema) + && + (!schema.nullable)) { + return { + "reports": [ + { + "incident": "null not allowed", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return { + "reports": [], + "result": lib_plankton.pod.make_filled(null), + }; + } + } + else { + if (("enum" in schema) + && + (!schema.enum.includes(value))) { + return { + "reports": [ + { + "incident": "provided value not in enumeration of valid values", + "details": { + "enumerated_values": schema.enum, + "provided_value": value, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + const type_map = { + "boolean": "boolean", + "integer": "number", + "number": "number", + "string": "string", + }; + // @ts-ignore + if (!(typeof (value) === type_map[schema.type])) { + return { + "reports": [ + { + // @ts-ignore + "incident": ("value should be " + type_map[schema.type]), + "details": { + "provided_value": value, + "type": typeof (value), + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return { + "reports": [], + "result": lib_plankton.pod.make_filled(value) + }; + } + } + } + } + } + /** + * @todo anyOf + * @todo allOf + * @todo oneOf + * @todo not + * @todo tests + */ + function adapt(schema, value_raw) { + let value = value_raw; + if (!("type" in schema)) { + if ("anyOf" in schema) { + if (value === undefined) { + if (!("default" in schema)) { + return { + "reports": [ + { + "incident": "neither explicit value provided nor default value specified", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + value = schema.default; + } + } + else { + // do nothing + } + const sub_adaptions = (schema.anyOf + .map((sub_schema) => adapt(sub_schema, value))); + const valid_sub_adaptions = (sub_adaptions + .filter((sub_adaption) => lib_plankton.pod.is_filled(sub_adaption.result))); + if (valid_sub_adaptions.length <= 0) { + return { + "reports": [ + { + "incident": "no valid apaptions", + "details": { + "sub_adaptions": sub_adaptions, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + if (valid_sub_adaptions.length > 1) { + return { + "reports": [ + { + "incident": "multiple valid apaptions", + "details": { + "valid_sub_adaptions": valid_sub_adaptions, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return valid_sub_adaptions[0]; + } + } + } + else { + throw (new Error("not implemented")); + } + } + else { + switch (schema.type) { + case "boolean": + return adapt_primitive(schema, value); + break; + case "integer": + return adapt_primitive(schema, value); + break; + case "number": + return adapt_primitive(schema, value); + break; + case "string": { + return adapt_primitive(schema, value); + break; + } + case "array": { + if (value === undefined) { + if (!("default" in schema)) { + return { + "reports": [ + { + "incident": "neither explicit value provided nor default value specified", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + value = schema.default; + } + } + /*else*/ { + if (value === null) { + if (("nullable" in schema) + && + (!schema.nullable)) { + return { + "reports": [ + { + "incident": "null not allowed", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return { + "reports": [], + "result": lib_plankton.pod.make_filled(null), + }; + } + } + else { + /*if ( + ("enum" in schema) + && + (! schema.enum.includes(value)) // TODO + ) { + return { + "reports": [ + { + "incident": "provided value not in enumeration of valid values", + "details": { + "enumerated_values": schema.enum, + "provided_value": value, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else*/ { + if ((!(typeof (value) === "object")) + && + (value.constructor.name !== "Array")) { + return { + "reports": [ + { + "incident": "value should be array", + "details": { + "provided_value": value, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + if (!("items" in schema)) { + // do nothing + return { + "reports": [], + "result": lib_plankton.pod.make_filled(value), + }; + } + else { + let reports = []; + for (let index = 0; index < value.length; index += 1) { + const adaption = adapt(schema.items, value[index]); + if (!lib_plankton.pod.is_filled(adaption.result)) { + reports = reports.concat(adaption.reports.map((report_entry) => ({ + "incident": report_entry.incident, + "details": Object.assign(report_entry.details, { + "path": (report_entry.details.path ?? []).concat([index]) + }), + }))); + } + else { + value[index] = lib_plankton.pod.cull(adaption.result); + } + } + return { + "reports": reports, + "result": ((reports.length > 0) + ? + lib_plankton.pod.make_empty() + : + lib_plankton.pod.make_filled(value)), + }; + } + } + } + } + } + break; + } + case "object": { + if (value === undefined) { + if (!("default" in schema)) { + return { + "reports": [ + { + "incident": "neither explicit value provided nor default value specified", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + value = schema.default; + } + } + /*else*/ { + if (value === null) { + if (("nullable" in schema) + && + (!schema.nullable)) { + return { + "reports": [ + { + "incident": "null not allowed", + "details": {} + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + return { + "reports": [], + "result": lib_plankton.pod.make_filled(null), + }; + } + } + else { + /*if ( + ("enum" in schema) + && + (! schema.enum.includes(value)) // TODO + ) { + return { + "reports": [ + { + "incident": "provided value not in enumeration of valid values", + "details": { + "enumerated_values": schema.enum, + "provided_value": value, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else*/ { + if (!(typeof (value) === "object")) { + return { + "reports": [ + { + "incident": "value should be object", + "details": { + "provided_value": value, + } + } + ], + "result": lib_plankton.pod.make_empty(), + }; + } + else { + value = lib_plankton.object.copy(value); + const contrast = lib_plankton.list.contrast(Object.keys(schema.properties), x => x, Object.keys(value), x => x); + let reports = []; + // gratuitous fields + { + if (contrast.only_right.length <= 0) { + // do nothing + } + else { + const additional_properties = (schema.additionalProperties ?? false); + if (additional_properties === false) { + reports = reports.concat(contrast.only_right + .map((entry) => ({ + "incident": "gratuitous field", + "details": { + "path": [entry.right], + } + }))); + } + else { + contrast.only_right.forEach((entry) => { + const sub_adaption = adapt(additional_properties, value[entry.right]); + if (!lib_plankton.pod.is_filled(sub_adaption.result)) { + reports = reports.concat(sub_adaption.reports + .map((report_entry) => ({ + "incident": report_entry.incident, + "details": Object.assign(report_entry.details, { + "path": (report_entry.details.path ?? []).concat([entry.right]) + }), + }))); + } + else { + value[entry.right] = lib_plankton.pod.cull(sub_adaption.result); + } + }); + } + } + } + // missing fields + { + contrast.only_left.forEach((entry) => { + if (("required" in schema) + && + schema.required.includes(entry.left)) { + reports.push({ + "incident": "missing field", + "details": { + "path": [entry.left], + } + }); + } + else { + const sub_adaption = adapt(schema.properties[entry.left], undefined); + if (!lib_plankton.pod.is_filled(sub_adaption.result)) { + reports = reports.concat(sub_adaption.reports + .map((report_entry) => ({ + "incident": report_entry.incident, + "details": Object.assign(report_entry.details, { + "path": (report_entry.details.path ?? []).concat([entry.left]) + }), + }))); + } + else { + value[entry.left] = lib_plankton.pod.cull(sub_adaption.result); + } + } + }); + // regular fields + { + contrast.both.forEach((entry) => { + const sub_adaption = adapt(schema.properties[entry.left], value[entry.right]); + if (!lib_plankton.pod.is_filled(sub_adaption.result)) { + reports = reports.concat(sub_adaption.reports + .map((report_entry) => ({ + "incident": report_entry.incident, + "details": Object.assign(report_entry.details, { + "path": (report_entry.details.path ?? []).concat([entry.right]) + }), + }))); + } + else { + value[entry.right] = lib_plankton.pod.cull(sub_adaption.result); + } + }); + } + return { + "reports": reports, + "result": ((reports.length > 0) + ? + lib_plankton.pod.make_empty() + : + lib_plankton.pod.make_filled(value)), + }; + } + } + } + } + } + break; + } + default: { + throw (new Error("unhandled schema type: " + schema.type)); + break; + } + } + } + } + /** + * @todo versioning + */ + function refine(schema, value_raw) { + const adaption = adapt(schema, value_raw); + if (!lib_plankton.pod.is_filled(adaption.result)) { + throw (new Error("conf could not be loaded:\n" + + + (adaption.reports + .map((report) => ("- " + report.incident + " | " + JSON.stringify(report.details, undefined, "\t"))) + .join("\n")))); + } + else { + return lib_plankton.pod.cull(adaption.result); + } + } + conf.refine = refine; + /** + */ + function load(schema, path) { + return (((path === null) + ? + Promise.resolve(undefined) + : + (lib_plankton.file.read(path) + .then((content) => Promise.resolve(lib_plankton.json.decode(content))))) + .then((data_raw) => Promise.resolve(refine(schema, data_raw)))); + } + conf.load = load; + })(conf = lib_plankton.conf || (lib_plankton.conf = {})); +})(lib_plankton || (lib_plankton = {})); +/* This file is part of »bacterio-plankton:string«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -6774,448 +8881,6 @@ var lib_plankton; })(shape = lib_plankton.shape || (lib_plankton.shape = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function inverse_encode(decode, to) { - return decode(to); - } - code.inverse_encode = inverse_encode; - /** - * @author fenris - */ - function inverse_decode(encode, from) { - return encode(from); - } - code.inverse_decode = inverse_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_inverse = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_inverse(subject) { - this.subject = subject; - } - /** - * @implementation - * @author fenris - */ - class_code_inverse.prototype.encode = function (to) { - var _this = this; - return code.inverse_encode(function (x) { return _this.subject.decode(x); }, to); - }; - /** - * @implementation - * @author fenris - */ - class_code_inverse.prototype.decode = function (from) { - var _this = this; - return code.inverse_decode(function (x) { return _this.subject.encode(x); }, from); - }; - return class_code_inverse; - }()); - code.class_code_inverse = class_code_inverse; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function pair_encode(encode_first, encode_second, from) { - var between = encode_first(from); - var to = encode_second(between); - return to; - } - code.pair_encode = pair_encode; - /** - * @author fenris - */ - function pair_decode(decode_first, decode_second, to) { - var between = decode_second(to); - var from = decode_first(between); - return from; - } - code.pair_decode = pair_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_pair = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_pair(first, second) { - this.first = first; - this.second = second; - } - /** - * @implementation - * @author fenris - */ - class_code_pair.prototype.encode = function (from) { - var _this = this; - return code.pair_encode(function (x) { return _this.first.encode(x); }, function (x) { return _this.second.encode(x); }, from); - }; - /** - * @implementation - * @author fenris - */ - class_code_pair.prototype.decode = function (to) { - var _this = this; - return code.pair_decode(function (x) { return _this.first.decode(x); }, function (x) { return _this.second.decode(x); }, to); - }; - return class_code_pair; - }()); - code.class_code_pair = class_code_pair; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - function chain_encode(encode_links, from) { - var value = from; - encode_links - .forEach(function (link) { - value = link(value); - }); - return value; - } - code.chain_encode = chain_encode; - /** - * @author fenris - */ - function chain_decode(decode_links, to) { - var value = to; - decode_links - .reverse() - .forEach(function (link) { - value = link(value); - }); - return value; - } - code.chain_decode = chain_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_chain = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_chain(links) { - this.links = links; - } - /** - * @implementation - * @author fenris - */ - class_code_chain.prototype.encode = function (from) { - return code.chain_encode(this.links.map(function (link) { return (function (x) { return link.encode(x); }); }), from); - }; - /** - * @implementation - * @author fenris - */ - class_code_chain.prototype.decode = function (to) { - return code.chain_decode(this.links.map(function (link) { return (function (x) { return link.decode(x); }); }), to); - }; - return class_code_chain; - }()); - code.class_code_chain = class_code_chain; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author Christian Fraß - */ - function flatten_encode(from, keys) { - if (keys === void 0) { keys = null; } - if (keys === null) { - if (from.length > 0) { - keys = Object.keys(from[0]); - } - else { - throw (new Error("encoding impossible")); - } - } - return { - "keys": keys, - "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) - }; - } - code.flatten_encode = flatten_encode; - /** - * @author Christian Fraß - */ - function flatten_decode(to) { - return (to.data - .map(function (dataset) { - var dataset_ = {}; - dataset - .forEach(function (value, index) { - var name = to.keys[index]; - dataset_[name] = value; - }); - return dataset_; - })); - } - code.flatten_decode = flatten_decode; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:code«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var code; - (function (code) { - /** - * @author fenris - */ - var class_code_flatten = /** @class */ (function () { - /** - * @author fenris - */ - function class_code_flatten() { - } - /** - * @implementation - * @author fenris - */ - class_code_flatten.prototype.encode = function (x) { - return code.flatten_encode(x); - }; - /** - * @implementation - * @author fenris - */ - class_code_flatten.prototype.decode = function (x) { - return code.flatten_decode(x); - }; - return class_code_flatten; - }()); - code.class_code_flatten = class_code_flatten; - })(code = lib_plankton.code || (lib_plankton.code = {})); -})(lib_plankton || (lib_plankton = {})); -/* This file is part of »bacterio-plankton:www_form«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -8433,2599 +10098,6 @@ var lib_plankton; })(session = lib_plankton.session || (lib_plankton.session = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:file«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var file; - (function (file) { - /** - * @author fenris - */ - function exists(path) { - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.stat(path, function (error, stats) { - if (error) { - resolve(false); - } - else { - resolve(true); - } - }); - })); - } - file.exists = exists; - /** - * @author fenris - */ - function read(path) { - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.readFile(path, { - "encoding": "utf8", - "flag": "r" - }, function (error, content) { - if (error == null) { - resolve(content); - } - else { - reject(error); - } - }); - })); - } - file.read = read; - /** - * @author fenris - */ - function read_buffer(path) { - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.readFile(path, { - "flag": "r" - }, function (error, content) { - if (error == null) { - resolve(content); - } - else { - reject(error); - } - }); - })); - } - file.read_buffer = read_buffer; - /** - * @author fenris - */ - function read_stdin() { - return (new Promise(function (resolve, reject) { - var input_raw = ""; - process.stdin.setEncoding("utf8"); - process.stdin.on("readable", function () { - var chunk; - while ((chunk = process.stdin.read()) !== null) { - input_raw += chunk; - } - }); - process.stdin.on("end", function () { - resolve(input_raw); - }); - })); - } - file.read_stdin = read_stdin; - /** - * @author fenris - */ - function write(path, content, options) { - if (options === void 0) { options = {}; } - options = Object.assign({ - "encoding": "utf-8" - }, options); - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.writeFile(path, content, { - "encoding": options.encoding, - "flag": "w" - }, function (error) { - if (error == null) { - resolve(undefined); - } - else { - reject(error); - } - }); - })); - } - file.write = write; - /** - * @author fenris - */ - function write_buffer(path, content, options) { - if (options === void 0) { options = {}; } - options = Object.assign({}, options); - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.writeFile(path, content, { - "flag": "w" - }, function (error) { - if (error == null) { - resolve(undefined); - } - else { - reject(error); - } - }); - })); - } - file.write_buffer = write_buffer; - /** - */ - function delete_(path) { - var nm_fs = require("fs"); - return (new Promise(function (resolve, reject) { - nm_fs.unlink(path, function () { - resolve(undefined); - }); - })); - } - file.delete_ = delete_; - })(file = lib_plankton.file || (lib_plankton.file = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function map_clear(map_forEach, map_delete) { - map_forEach((value, key) => { - map_delete(key); - }); - } - structures.map_clear = map_clear; - /** - * @author fenris - */ - function map_keys(map_forEach) { - let keys = []; - map_forEach((value, key) => { - keys.push(key); - }); - return keys; - } - structures.map_keys = map_keys; - /** - * @author fenris - */ - function map_values(map_forEach) { - let values = []; - map_forEach((value, key) => { - values.push(value); - }); - return values; - } - 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; - } - 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(", ")) - + - "]"); - } - structures.map_toString = map_toString; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_mapbase { - /** - * @desc [constructor] - */ - constructor() { - } - /** - * @desc [mutator] - */ - clear() { - return (structures.map_clear((procedure) => this.forEach(procedure), (key) => this.delete(key))); - } - /** - */ - get_safe(key) { - try { - const value = this.get(key); - return lib_plankton.pod.class_pod.filled(value); - } - catch (error) { - return lib_plankton.pod.class_pod.empty(); - } - } - /** - * @desc [accessor] - */ - keys() { - return (structures.map_keys((procedure) => this.forEach(procedure))); - } - /** - * @desc [accessor] - */ - values() { - return (structures.map_values((procedure) => this.forEach(procedure))); - } - /** - * @desc [accessor] - */ - pairs() { - return (structures.map_pairs((procedure) => this.forEach(procedure))); - } - /** - * @desc [accessor] - */ - toString(show_key = instance_show, show_value = instance_show) { - return (structures.map_toString((procedure) => this.forEach(procedure), show_key, show_value)); - } - } - structures.class_mapbase = class_mapbase; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (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) + ")"); - } - } - structures.class_pair = class_pair; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function set_construct(collation, elements = []) { - let subject = { - "elements": [] - }; - elements.forEach(element => set_add(collation, subject, element)); - return subject; - } - structures.set_construct = set_construct; - /** - * @desc [accessor] - * @author fenris - */ - function set_size(subject) { - return subject.elements.length; - } - structures.set_size = set_size; - /** - * @desc [accessor] - * @author fenris - */ - function set_has(collation, subject, element) { - return (subject.elements - .some(element_ => collation(element, element_))); - } - 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); - } - } - structures.set_add = set_add; - /** - * @desc [mutator] - * @author fenris - */ - function set_pop(subject) { - if (subject.elements.length == 0) { - return lib_plankton.pod.make_empty(); - } - else { - return lib_plankton.pod.make_filled(subject.elements.pop()); - } - } - structures.set_pop = set_pop; - /** - * @desc [accessor] - * @author fenris - */ - function set_forEach(subject, function_) { - subject.elements.forEach(element => function_(element)); - } - 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)))); - } - 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)))); - } - structures.set_filter = set_filter; - /** - * @desc [accessor] - * @author fenris - */ - function set_dump(subject) { - return subject.elements; - } - 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))); - } - 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))); - } - 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)); - } - structures.set_equals = set_equals; - /** - * @desc [accessor] - * @author fenris - */ - function set_toString(show_element, subject) { - return ("{" - + - subject.elements.map(element => show_element(element)).join(",") - + - "}"); - } - structures.set_toString = set_toString; - /** - * @desc [accessor] - * @author fenris - */ - function set_empty(subject) { - return (subject.elements.length == 0); - } - 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; - } - 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; - } - 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; - } - 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))); - } - 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)); - } - 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)); - } - structures.set_intersection_all = set_intersection_all; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_set { - /** - * @author fenris - */ - constructor(elements = [], equality = instance_collate /**/) { - this.equality = equality; - this.subject = structures.set_construct(equality, elements); - } - /** - * @author fenris - */ - static from_subject(equality = instance_collate /**/, subject) { - let set = new class_set([], equality); - set.subject = subject; - return set; - } - /** - * @desc [accessor] - * @author fenris - */ - size() { - return structures.set_size(this.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - has(element) { - return structures.set_has(this.equality, this.subject, element); - } - /** - * @desc [mutator] - * @author fenris - */ - add(element) { - return structures.set_add(this.equality, this.subject, element); - } - /** - * @desc [mutator] - * @author fenris - */ - pop() { - return (new lib_plankton.pod.class_pod(structures.set_pop(this.subject))); - } - /** - * @desc [accessor] - * @author fenris - */ - forEach(function_) { - return structures.set_forEach(this.subject, function_); - } - /** - * @desc [accessor] - * @author fenris - */ - map(transformator, equality = instance_collate /**/) { - return (class_set.from_subject(equality, structures.set_map(equality, this.subject, transformator))); - } - /** - * @desc [accessor] - * @author fenris - */ - filter(predicate) { - return (class_set.from_subject(this.equality, structures.set_filter(this.subject, predicate))); - } - /** - * @desc [accessor] - * @author fenris - */ - dump() { - return structures.set_dump(this.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - subset(set) { - return structures.set_subset(this.equality, this.subject, set.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - superset(set) { - return structures.set_superset(this.equality, this.subject, set.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - equals(set) { - return structures.set_equals(this.equality, this.subject, set.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - toString() { - return structures.set_toString(instance_show, this.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - empty() { - return structures.set_empty(this.subject); - } - /** - * @desc [accessor] - * @author fenris - */ - union(set) { - return (class_set.from_subject(this.equality, structures.set_union(this.equality, this.subject, set.subject))); - } - /** - * @desc [accessor] - * @author fenris - */ - intersection(set) { - return (class_set.from_subject(this.equality, structures.set_intersection(this.equality, this.subject, set.subject))); - } - /** - * @desc [accessor] - * @author fenris - */ - difference(set) { - return (class_set.from_subject(this.equality, structures.set_difference(this.equality, this.subject, set.subject))); - } - /** - * @desc [accessor] - * @author fenris - */ - symmetric_difference(set) { - return (class_set.from_subject(this.equality, structures.set_symmetric_difference(this.equality, this.subject, set.subject))); - } - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _collate(set) { - return structures.set_equals(this.equality, this.subject, set.subject); - } - /** - * @desc [accessor] [implementation] - * @author fenris - */ - _show() { - return 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, 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, structures.set_intersection_all(sets[0].equality, sets.map(set => set.subject)))); - } - } - } - structures.class_set = class_set; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function stack_construct() { - return { - "elements": [] - }; - } - structures.stack_construct = stack_construct; - /** - * @author fenris - */ - function stack_size(subject) { - return subject.elements.length; - } - 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]; - } - } - structures.stack_scan = stack_scan; - /** - * @author fenris - */ - function stack_take(subject) { - let element = stack_scan(subject); - subject.elements.pop(); - return element; - } - structures.stack_take = stack_take; - /** - * @author fenris - */ - function stack_give(subject, element) { - subject.elements.push(element); - } - structures.stack_give = stack_give; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_stack { - /** - * @author fenris - */ - constructor() { - this.subject = structures.stack_construct(); - } - /** - * @override - * @author fenris - */ - size() { - return structures.stack_size(this.subject); - } - /** - * @override - * @author fenris - */ - scan() { - return structures.stack_scan(this.subject); - } - /** - * @override - * @author fenris - */ - take() { - return structures.stack_take(this.subject); - } - /** - * @override - * @author fenris - */ - give(element) { - return structures.stack_give(this.subject, element); - } - } - structures.class_stack = class_stack; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function queue_construct() { - return { - "elements": [] - }; - } - structures.queue_construct = queue_construct; - /** - * @author fenris - */ - function queue_size(subject) { - return subject.elements.length; - } - 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]; - } - } - structures.queue_scan = queue_scan; - /** - * @author fenris - */ - function queue_take(subject) { - let element = queue_scan(subject); - subject.elements.shift(); - return element; - } - structures.queue_take = queue_take; - /** - * @author fenris - */ - function queue_give(subject, element) { - subject.elements.push(element); - } - structures.queue_give = queue_give; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_queue { - /** - * @author fenris - */ - constructor() { - this.subject = structures.queue_construct(); - } - /** - * @override - * @author fenris - */ - size() { - return structures.queue_size(this.subject); - } - /** - * @override - * @author fenris - */ - scan() { - return structures.queue_scan(this.subject); - } - /** - * @override - * @author fenris - */ - take() { - return structures.queue_take(this.subject); - } - /** - * @override - * @author fenris - */ - give(element) { - return structures.queue_give(this.subject, element); - } - } - structures.class_queue = class_queue; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function simplemap_construct() { - return { - "memory": {} - }; - } - structures.simplemap_construct = simplemap_construct; - /** - * @author fenris - */ - function simplemap_has(subject, key) { - return (key in subject.memory); - } - structures.simplemap_has = simplemap_has; - /** - * @author fenris - */ - function simplemap_get_safe(subject, key) { - if (key in subject.memory) { - return lib_plankton.pod.make_filled(subject.memory[key]); - } - else { - return lib_plankton.pod.make_empty(); - } - } - structures.simplemap_get_safe = simplemap_get_safe; - /** - * @author fenris - */ - function simplemap_get(subject, key, fallback = lib_plankton.pod.make_empty()) { - if (key in subject.memory) { - return subject.memory[key]; - } - else { - if (!lib_plankton.pod.is_filled(fallback)) { - throw (new Error("key not found")); - } - else { - return lib_plankton.pod.cull(fallback); - } - } - } - structures.simplemap_get = simplemap_get; - /** - * @author fenris - */ - function simplemap_set(subject, key, value) { - subject.memory[key] = value; - } - structures.simplemap_set = simplemap_set; - /** - * @author fenris - */ - function simplemap_delete(subject, key) { - delete subject.memory[key]; - } - structures.simplemap_delete = simplemap_delete; - /** - * @author fenris - */ - function simplemap_clear(subject) { - // subject.memory = {}; - Object.keys(subject.memory).forEach(key => { delete subject.memory[key]; }); - } - 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); - }); - } - 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; - } - structures.simplemap_from_object = simplemap_from_object; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_simplemap extends structures.class_mapbase { - /** - * @author fenris - */ - static make() { - const subject = structures.simplemap_construct(); - return (new class_simplemap(subject)); - } - /** - * @author fenris - */ - static from_object(object) { - return (new class_simplemap(structures.simplemap_from_object(object))); - } - /** - * @author fenris - * @desc [constructor] - */ - constructor(subject = structures.simplemap_construct()) { - super(); - this.subject = subject; - } - /** - * @author fenris - * @implementation - */ - has(key) { - return structures.simplemap_has(this.subject, key); - } - /** - * @author fenris - * @implementation - */ - get(key, fallback = lib_plankton.pod.class_pod.empty()) { - return structures.simplemap_get(this.subject, key, fallback.tear()); - } - /** - * @author fenris - * @implementation - */ - set(key, value) { - return structures.simplemap_set(this.subject, key, value); - } - /** - * @author fenris - * @implementation - */ - delete(key) { - return structures.simplemap_delete(this.subject, key); - } - /** - * @author fenris - * @implementation - */ - forEach(procedure) { - return structures.simplemap_forEach(this.subject, procedure); - } - } - structures.class_simplemap = class_simplemap; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - function hashmap_construct(hashing, pairs) { - const subject = { - "core": structures.simplemap_construct(), - "hashing": hashing, - }; - pairs.forEach((pair) => { - hashmap_set(subject, pair.key, pair.value); - }); - return subject; - } - structures.hashmap_construct = hashmap_construct; - /** - * @author fenris - */ - function hashmap_has(subject, key) { - const key_ = subject.hashing(key); - return structures.simplemap_has(subject.core, key_); - } - structures.hashmap_has = hashmap_has; - /** - * @author fenris - */ - function hashmap_get(subject, key, fallback = lib_plankton.pod.make_empty()) { - /* - we have to adjust the fallback argument, so that it can be used in our underlying simplemap core - therefore we pack the value together with any key as dummy - */ - const fallback_ = lib_plankton.pod.propagate(fallback, (value) => ({ - "key": key, - "value": value - })); - const key_ = subject.hashing(key); - return (structures.simplemap_get(subject.core, key_, fallback_) - .value); - } - structures.hashmap_get = hashmap_get; - /** - * @author fenris - */ - function hashmap_set(subject, key, value) { - const key_ = subject.hashing(key); - return (structures.simplemap_set(subject.core, key_, { "key": key, "value": value })); - } - structures.hashmap_set = hashmap_set; - /** - * @author fenris - */ - function hashmap_delete(subject, key) { - const key_ = subject.hashing(key); - return (structures.simplemap_delete(subject.core, key_)); - } - structures.hashmap_delete = hashmap_delete; - /** - * @author fenris - */ - function hashmap_clear(subject) { - return structures.simplemap_clear(subject.core); - } - structures.hashmap_clear = hashmap_clear; - /** - * @author fenris - */ - function hashmap_forEach(subject, procedure) { - return (structures.simplemap_forEach(subject.core, ({ "key": key, "value": value }, key_) => { - procedure(value, key); - })); - } - structures.hashmap_forEach = hashmap_forEach; - /** - * @author fenris - */ - function hashmap_dump(subject) { - let result = []; - hashmap_forEach(subject, (value, key) => { - result.push({ - "key": key, - "value": value, - }); - }); - return result; - } - structures.hashmap_dump = hashmap_dump; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_hashmap extends structures.class_mapbase { - /** - * @author fenris - * @desc [constructor] - */ - constructor(hashing = instance_hash, pairs = []) { - super(); - this.subject = structures.hashmap_construct(hashing, pairs); - } - /** - * @author fenris - * @implementation - */ - has(key) { - return structures.hashmap_has(this.subject, key); - } - /** - * @author fenris - * @implementation - */ - get(key, fallback = lib_plankton.pod.class_pod.empty()) { - return structures.hashmap_get(this.subject, key, fallback.tear()); - } - /** - * @author fenris - * @implementation - */ - set(key, value) { - return structures.hashmap_set(this.subject, key, value); - } - /** - * @author fenris - * @implementation - */ - delete(key) { - return structures.hashmap_delete(this.subject, key); - } - /** - * @author fenris - * @implementation - */ - forEach(procedure) { - return structures.hashmap_forEach(this.subject, procedure); - } - } - structures.class_hashmap = class_hashmap; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - */ - function collatemap_construct() { - return { - "pairs": [], - }; - } - structures.collatemap_construct = collatemap_construct; - /** - */ - function collatemap_has(collation, subject, key) { - return subject.pairs.some((pair) => collation(key, pair.key)); - } - structures.collatemap_has = collatemap_has; - /** - * @todo use .find - */ - function collatemap_get(collation, subject, key, fallback) { - let value; - const found = (subject.pairs - .some((pair) => { - if (collation(key, pair.key)) { - value = pair.value; - return true; - } - else { - return false; - } - })); - if (found) { - return value; - } - else { - if (!lib_plankton.pod.is_filled(fallback)) { - throw (new Error("key not found")); - } - else { - return lib_plankton.pod.cull(fallback); - } - } - } - structures.collatemap_get = collatemap_get; - /** - */ - function collatemap_set(collation, subject, key, value) { - const found = (subject.pairs - .some((pair) => { - if (collation(key, pair.key)) { - pair.value = value; - return true; - } - else { - return false; - } - })); - if (found) { - // nothing - } - else { - subject.pairs.push({ - "key": key, - "value": value - }); - } - } - structures.collatemap_set = collatemap_set; - /** - */ - function collatemap_delete(collation, subject, key) { - let index; - const 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 - } - } - structures.collatemap_delete = collatemap_delete; - /** - */ - function collatemap_forEach( - // collation : type_collation, - subject, function_) { - subject.pairs - .forEach((pair) => { - function_(pair.value, pair.key); - }); - } - structures.collatemap_forEach = collatemap_forEach; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_collatemap extends structures.class_mapbase { - /** - * @author fenris - * @desc [constructor] - */ - constructor(collation = instance_collate) { - super(); - this.subject = structures.collatemap_construct(); - this.collation = collation; - } - /** - * @author fenris - * @implementation - */ - has(key) { - return structures.collatemap_has(this.collation, this.subject, key); - } - /** - * @author fenris - * @implementation - */ - get(key, fallback = lib_plankton.pod.class_pod.empty()) { - return structures.collatemap_get(this.collation, this.subject, key, fallback.tear()); - } - /** - * @author fenris - * @implementation - */ - set(key, value) { - return structures.collatemap_set(this.collation, this.subject, key, value); - } - /** - * @author fenris - * @implementation - */ - delete(key) { - return structures.collatemap_delete(this.collation, this.subject, key); - } - /** - * @author fenris - * @implementation - */ - forEach(procedure) { - return structures.collatemap_forEach(this.subject, procedure); - } - } - structures.class_collatemap = class_collatemap; - /** - * @author fenris - * @deprecated - */ - structures.class_map = class_collatemap; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_graph { - /** - * @author fenris - */ - constructor(equality = null, nodes = [], edges = []) { - if (equality == null) { - // equality = ((node1, node2) => lib_plankton.trait.call("collatable", "collate", {"kind": "auto"}, {"first": node1, "second": node2})); - equality = instance_collate /**/; - } - 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": {} - }; - }), - } - }); - } - } - structures.class_graph = class_graph; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - structures.relation_le = "le"; - structures.relation_ge = "ge"; - structures.relation_lt = "lt"; - structures.relation_gt = "gt"; - 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, - }; - } - structures.bintree_construct = bintree_construct; - /** - * @author fenris - */ - function bintree_depth(subject) { - return ((binnode_isdef(subject.root)) - ? binnode_depth(subject.root) - : 0); - } - 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); - } - 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); - } - } - } - 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); - } - 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; - } - } - structures.bintree_find = bintree_find; - /** - * @author fenris - */ - function bintree_traverse(subject) { - return ((binnode_isdef(subject.root)) - ? binnode_traverse(subject.root) - : []); - } - structures.bintree_traverse = bintree_traverse; - /** - * @author fenris - */ - function bintree_show(show_data, subject) { - return ((binnode_isdef(subject.root)) - ? binnode_show(show_data, subject.root) - : "--"); - } - 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 structures.class_graph((x, y) => (x.data == y.data), gathering.nodes, gathering.edges); - return graph; - } - structures.bintree_to_graph = bintree_to_graph; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:structures«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var structures; - (function (structures) { - /** - * @author fenris - */ - class class_bintree { - /** - * @author fenris - */ - constructor(compare = instance_compare) { - this.subject = structures.bintree_construct(); - this.compare = compare; - } - /** - * @author fenris - */ - depth() { - return structures.bintree_depth(this.subject); - } - /** - * @author fenris - */ - insert(data, rebalance = true) { - return 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 structures.bintree_search(this.compare, this.subject, data, relation); - } - /** - * @author fenris - */ - traverse() { - return structures.bintree_traverse(this.subject); - } - /** - * @author fenris - */ - show() { - return structures.bintree_show(instance_show /**/, this.subject); - } - } - structures.class_bintree = class_bintree; - })(structures = lib_plankton.structures || (lib_plankton.structures = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:json«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:json« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:json« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:json«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var json; - (function (json) { - /** - * @author fenris - */ - function encode(source, options = {}) { - options = Object.assign({ - "formatted": false, - }, options); - return JSON.stringify(source, undefined, (options.formatted ? "\t" : undefined)); - } - json.encode = encode; - /** - * @author fenris - */ - function decode(target) { - return JSON.parse(target); - } - json.decode = decode; - /** - * @author fenris - */ - function implementation_code() { - return { - "encode": x => encode(x), - "decode": decode, - }; - } - json.implementation_code = implementation_code; - })(json = lib_plankton.json || (lib_plankton.json = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:json«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:json« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:json« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:json«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var json; - (function (json) { - /** - * @author fenris - */ - class class_json { - /** - * @author fenris - */ - constructor() { - } - /** - * @implementation - * @author fenris - */ - encode(x) { - return json.encode(x); - } - /** - * @implementation - * @author fenris - */ - decode(x) { - return json.decode(x); - } - } - json.class_json = class_json; - })(json = lib_plankton.json || (lib_plankton.json = {})); -})(lib_plankton || (lib_plankton = {})); -/* This file is part of »bacterio-plankton:date«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -13199,375 +12271,6 @@ var lib_plankton; })(http = lib_plankton.http || (lib_plankton.http = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:object«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»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 . - */ -var lib_plankton; -(function (lib_plankton) { - var object; - (function (object_1) { - /** - * @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 '".concat(fieldname, "' not in structure")); - message += ("; using fallback value '".concat(String(fallback), "'")); - // console.warn(message); - return fallback; - break; - } - case 2: { - var message = ("field '".concat(fieldname, "' not in structure")); - throw (new Error(message)); - break; - } - default: { - throw (new Error("invalid escalation level ".concat(escalation))); - break; - } - } - } - } - object_1.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; - } - object_1.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; - } - object_1.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; - } - object_1.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; - } - object_1.to_array = to_array; - /** - * @desc gibt eine Liste von Schlüsseln eines Objekts zurück - * @author fenris - */ - function keys(object) { - return Object.keys(object); - } - object_1.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; }); - } - object_1.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 = lib_plankton.object.fetch(position_1, step, null, 0); - return (position_1 != null); - }); - if (reachable) { - return lib_plankton.object.fetch(position_1, steps[steps.length - 1], fallback, escalation); - } - else { - return lib_plankton.object.fetch({}, "_dummy_", fallback, escalation); - } - } - } - object_1.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_ = lib_plankton.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 '".concat(path, "' does not exist and may not be constructed")); - throw (new Error(message)); - } - } - } - object_1.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]); }); - } - object_1.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_2 = (value); - Object.keys(object_2) - .forEach(function (key) { - integrate(result_2, key, object_2[key]); - }); - } - } - return result_2; - } - } - object_1.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, _f = _e["existing"], hook_existing = _f === void 0 ? null : _f; - if (hook_existing == null) { - (function (key, value_old, value_new) { return console.warn("field ".concat(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; - } - object_1.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 : "".concat(path, ".").concat(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 '".concat(path_, "'; core has type '").concat(typeof (value_core), "' and mantle has type '").concat(typeof (value_mantle), "'"); - console.warn(message); - } - core[key] = value_mantle; - // throw (new Error(message)); - } - } - }); - } - } - object_1.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; - } - object_1.patched = patched; - /** - * @author fenris - */ - function attached(object, key, value) { - var mantle = {}; - mantle[key] = value; - return patched(object, mantle, false); - } - object_1.attached = attached; - /** - * @author fenris - */ - function copy(object) { - return patched({}, object); - } - object_1.copy = copy; - })(object = lib_plankton.object || (lib_plankton.object = {})); -})(lib_plankton || (lib_plankton = {})); -/* This file is part of »bacterio-plankton:markdown«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -15744,3 +14447,115 @@ var lib_plankton; args.class_handler = class_handler; })(args = lib_plankton.args || (lib_plankton.args = {})); })(lib_plankton || (lib_plankton = {})); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +/* +This file is part of »bacterio-plankton:bcrypt«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:bcrypt« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:bcrypt« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:bcrypt«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var bcrypt; + (function (bcrypt) { + /** + */ + function compute(input, options) { + var _a; + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var nm_bcrypt, salt, _b, result; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + options = Object.assign({ + "rounds": 12, + "salt": null + }, options); + nm_bcrypt = require("bcrypt"); + if (!((_a = options.salt) !== null && _a !== void 0)) return [3 /*break*/, 1]; + _b = _a; + return [3 /*break*/, 3]; + case 1: return [4 /*yield*/, nm_bcrypt.genSalt(options.rounds)]; + case 2: + _b = (_c.sent()); + _c.label = 3; + case 3: + salt = (_b); + return [4 /*yield*/, nm_bcrypt.hash(input, salt)]; + case 4: + result = _c.sent(); + return [2 /*return*/, result]; + } + }); + }); + } + bcrypt.compute = compute; + /** + */ + function compare(password_shall_image, password_is) { + return __awaiter(this, void 0, void 0, function () { + var nm_bcrypt, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + nm_bcrypt = require("bcrypt"); + return [4 /*yield*/, nm_bcrypt.compare(password_is, password_shall_image)]; + case 1: + result = _a.sent(); + return [2 /*return*/, result]; + } + }); + }); + } + bcrypt.compare = compare; + })(bcrypt = lib_plankton.bcrypt || (lib_plankton.bcrypt = {})); +})(lib_plankton || (lib_plankton = {})); diff --git a/source/api/actions/calendar_list.ts b/source/api/actions/calendar_list.ts index 5e12c9d..dd92729 100644 --- a/source/api/actions/calendar_list.ts +++ b/source/api/actions/calendar_list.ts @@ -58,16 +58,21 @@ namespace _zeitbild.api ], } }), - "restriction": restriction_none, // TODO - "execution": () => ( - _zeitbild.service.calendar.overview(2) // TODO: user_id - .then( - data => Promise.resolve({ - "status_code": 200, - "data": data, - }) - ) - ) + "restriction": restriction_logged_in, + "execution": async (stuff) => { + const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff); + const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.identify(session.value.name); + + return ( + _zeitbild.service.calendar.overview(user_id) + .then( + data => Promise.resolve({ + "status_code": 200, + "data": data, + }) + ) + ); + } } ); } diff --git a/source/api/actions/events.ts b/source/api/actions/events.ts index f84dd08..713d01f 100644 --- a/source/api/actions/events.ts +++ b/source/api/actions/events.ts @@ -102,6 +102,9 @@ namespace _zeitbild.api }), "restriction": restriction_none, // TODO "execution": async (stuff) => { + const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff); + const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.identify(session.value.name); + const from : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["from"]); const to : _zeitbild.helpers.type_pit = parseInt(stuff.query_parameters["to"]); const calendar_ids_wanted : Array<_zeitbild.type.calendar_id> = ( @@ -123,7 +126,7 @@ namespace _zeitbild.api null ); const calendar_ids_allowed : Array<_zeitbild.type.calendar_id> = ( - (await _zeitbild.service.calendar.overview(0)) // TODO: user_id + (await _zeitbild.service.calendar.overview(user_id)) .map((x : any) => x.id) ); const calendar_ids : Array<_zeitbild.type.calendar_id> = ( diff --git a/source/api/actions/session_begin.ts b/source/api/actions/session_begin.ts index 32bfbab..8125575 100644 --- a/source/api/actions/session_begin.ts +++ b/source/api/actions/session_begin.ts @@ -50,15 +50,15 @@ namespace _zeitbild.api return Promise.reject(new Error("impossible")); } else { - const admin : (null | _zeitbild.service.admin.type_value) = await _zeitbild.service.admin.login(input.name, input.password); - if (admin === null) { + const passed : boolean = await _zeitbild.service.auth_internal.check(input.name, input.password); + if (! passed) { return Promise.resolve({ "status_code": 403, "data": null, }); } else { - const session_key : string = await lib_plankton.session.begin(admin.name); + const session_key : string = await lib_plankton.session.begin(input.name); return Promise.resolve({ "status_code": 201, "data": session_key, diff --git a/source/api/actions/session_oidc.ts b/source/api/actions/session_oidc.ts index 757f741..308749f 100644 --- a/source/api/actions/session_oidc.ts +++ b/source/api/actions/session_oidc.ts @@ -13,7 +13,7 @@ namespace _zeitbild.api lib_plankton.http.enum_method.delete, "/session/oidc", { - "description": "beendet eine Sitzung", + "description": "verarbeitet einen OIDC login callback", "input_schema": () => ({ "type": "null", }), @@ -22,8 +22,15 @@ namespace _zeitbild.api }), "restriction": restriction_logged_in, "execution": async (stuff) => { - const session : {key : string; value : lib_plankton.session.type_session} = await session_from_stuff(stuff); - await lib_plankton.session.end(session.key); + // do NOT wait + _zeitbild.auth.control( + { + "kind": "authorization_callback", + "data": { + "http_request": http_request + } + } + ); return Promise.resolve({ "status_code": 200, "data": null, diff --git a/source/api/actions/session_prepare.ts b/source/api/actions/session_prepare.ts index 987dcb5..d284a4d 100644 --- a/source/api/actions/session_prepare.ts +++ b/source/api/actions/session_prepare.ts @@ -13,11 +13,10 @@ namespace _zeitbild.api name : string; password : string; }, - ( - null - | - string - ) + { + kind : string; + data : any; + } >( rest_subject, lib_plankton.http.enum_method.get, @@ -28,25 +27,15 @@ namespace _zeitbild.api "nullable": true, }), "output_schema": () => ({ - "type": "string", - "description": "der Sitzungs-Schlüssel, der als Header 'X-Session-Key' gesetzt werden muss um Erlaubnis zur Ausführung geschützter Aktionen zu erhalten", + "nullable": false }), "restriction": restriction_none, "execution": async () => { - const admin : (null | _zeitbild.service.admin.type_value) = await _zeitbild.service.admin.login(input.name, input.password); - if (admin === null) { - return Promise.resolve({ - "status_code": 403, - "data": null, - }); - } - else { - const session_key : string = await lib_plankton.session.begin(admin.name); - return Promise.resolve({ - "status_code": 201, - "data": session_key, - }); - } + const preparation = await _zeitbild.auth.prepare(); + return Promise.resolve({ + "status_code": 200, + "data": preparation, + }); }, } ); diff --git a/source/api/functions.ts b/source/api/functions.ts index 2987e3b..935cb43 100644 --- a/source/api/functions.ts +++ b/source/api/functions.ts @@ -26,8 +26,10 @@ namespace _zeitbild.api } // session { + // _zeitbild.api.register_session_prepare(rest_subject); _zeitbild.api.register_session_begin(rest_subject); _zeitbild.api.register_session_end(rest_subject); + // _zeitbild.api.register_session_oidc(rest_subject); } // calendar { diff --git a/source/auth.ts b/source/auth.ts new file mode 100644 index 0000000..1be7e2f --- /dev/null +++ b/source/auth.ts @@ -0,0 +1,93 @@ + +namespace _zeitbild.auth +{ + + /** + let _subject : ( + null + | + lib_plankton.auth.type_auth + ) = null; + */ + + + /** + */ + export function init( + ) : Promise + { + /* + switch (_zeitbild.conf.get().auth.kind) { + case "internal": { + _subject = lib_plankton.auth.internal.implementation_auth( + { + // "password_image_chest": password_image_chest, + // "check_password": (image, input) => Promise.resolve(image === get_password_image(input)), + } + ); + } + case "oidc": { + _subject = lib_plankton.auth.oidc.implementation_auth( + { + "url_authorization": _zeitbild.conf.get().auth.data.url_authorization, + "url_token": _zeitbild.conf.get().auth.data.url_token, + "url_userinfo": _zeitbild.conf.get().auth.data.url_userinfo, + "client_id": _zeitbild.conf.get().auth.data.client_id, + "client_secret": _zeitbild.conf.get().auth.data.client_secret, + "url_redirect": "/session/begin", + "scopes": [ + "openid", + "profile", + "email", + ], + "login_url_mode": "open", + } + ); + } + default: { + // do nothing + break; + } + } + */ + return Promise.resolve(undefined); + } + + + /** + export function prepare( + ) : Promise<{kind : string; data : any;}> + { + return ( + _subject.prepare() + .then( + (data) => ({ + "kind": _zeitbild.conf.get().auth.kind, + "data": data, + }) + ) + ); + } + */ + + + /** + export function execute( + input : any + ) : Promise + { + return _subject.execute(input); + } + */ + + + /** + export function control( + input : any + ) : Promise + { + return _subject.control(input); + } + */ + +} diff --git a/source/conf.ts b/source/conf.ts index d6a0eae..084f127 100644 --- a/source/conf.ts +++ b/source/conf.ts @@ -4,245 +4,214 @@ namespace _zeitbild.conf /** */ - type type_log_threshold = ( - "debug" - | - "info" - | - "notice" - | - "warning" - | - "error" - ); - - - /** - */ - type type_log_format = ( - "jsonl" - | - "human_readable" - ); - - - /** - */ - export type type_conf = { - general : { - language : (null | string); - }; - log : Array< - { - kind : "stdout"; - data : { - threshold : type_log_threshold; - }; + const _schema : lib_plankton.conf.type_schema = { + "nullable": false, + "type": "object", + "properties": { + "version": { + "nullable": false, + "type": "integer", + "enum": [1] + }, + "log": { + "nullable": false, + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "kind": { + "nullable": false, + "type": "string", + "enum": ["stdout"] + }, + "data": { + "nullable": false, + "type": "object", + "properties": { + "threshold": { + "nullable": false, + "type": "string", + "enum": [ + "debug", + "info", + "notice", + "warning", + "error" + ], + "default": "info" + } + }, + "required": [ + ] + } + } + } + ] + }, + "default": [ + { + "kind": "stdout", + "data": { + "threshold": "info" + } + } + ] + }, + "server": { + "nullable": false, + "type": "object", + "properties": { + "address": { + "nullable": false, + "type": "string", + "default": "::" + }, + "port": { + "nullable": false, + "type": "integer", + "default": 7845 + } + }, + "required": [ + ], + "additionalProperties": false, + "default": { + } + }, + "database": { + "anyOf": [ + { + "type": "object", + "properties": { + "kind": { + "nullable": false, + "type": "string", + "enum": ["sqlite"] + }, + "data": { + "nullable": false, + "type": "object", + "properties": { + "path": { + "nullable": false, + "type": "string", + "default": "data.sqlite" + } + }, + "required": [ + ], + "default": {} + } + }, + "required": [ + "kind" + ] + }, + { + "type": "object", + "properties": { + "kind": { + "nullable": false, + "type": "string", + "enum": ["postgresql"] + }, + "data": { + "nullable": false, + "type": "object", + "properties": { + "host": { + "nullable": false, + "type": "string" + }, + "port": { + "nullable": false, + "type": "integer", + "default": 5432 + }, + "username": { + "nullable": false, + "type": "string" + }, + "password": { + "nullable": false, + "type": "string" + }, + "scheme": { + "nullable": false, + "type": "string" + } + }, + "required": [ + "host", + "username", + "password", + "scheme" + ] + } + }, + "required": [ + "kind", + "data" + ] + } + ], + "default": { + "kind": "sqlite" + } + }, + "session_management": { + "nullable": false, + "type": "object", + "properties": { + "in_memory": { + "nullable": false, + "type": "boolean", + "default": true + }, + "drop_all_at_start": { + "nullable": false, + "type": "boolean", + "default": true + }, + "lifetime": { + "nullable": false, + "type": "integer", + "default": 900 + } + }, + "required": [ + ], + "additionalProperties": false, + "default": {} } - | - { - kind : "file"; - data : { - threshold : type_log_threshold; - path : string; - }; - } - | - { - kind : "email"; - data : { - threshold : type_log_threshold; - smtp_credentials : { - host : string; - port : int; - username : string; - password : string; - }; - sender : string; - receivers : Array; - }; - } - >; - server : { - host : string; - port : int; - path_base : string; - }; - database : ( - { - kind : "sqlite"; - data : { - path : string; - }; - } - | - { - kind : "postgresql"; - data : { - host : string; - port ?: int; - username : string; - password : string; - schema : string; - }; - } - ); - authentication : ( - { - kind : "internal"; - data : { - }; - } - | - { - kind : "oidc"; - data : { - client_id : string; - client_secret : string; - url_authorization : string; - url_token : string; - url_userinfo : string; - }; - } - ); - session_management : { - in_memory : boolean; - drop_all_at_start : boolean; - lifetime : int; - }; + }, + "required": [ + "version" + ], + "additionalProperties": false }; /** */ - var _data : (null | type_conf) = null; + var _data : (null | any) = null; /** */ - export function inject( - conf_raw : any - ) : void + export function schema( + ) : lib_plankton.conf.type_schema { - const version : int = (conf_raw["version"] ?? 1); - _data = { - "general": ( - ((node_general) => ({ - "language": (node_general["language"] ?? null), - })) (conf_raw["general"] ?? {}) - ), - "log": ( - (() => { - const node_log = ( - conf_raw["log"] - ?? - [ - { - "kind": "stdout", - "data": { - } - }, - ] - ); - return ( - node_log.map( - (node_log_entry : any) => ({ - "kind": node_log_entry["kind"], - "data": Object.assign( - { - "format": "human_readable", - "threshold": "notice", - }, - (node_log_entry["data"] ?? {}) - ) - }) - ) - ); - }) () - ), - "server": ( - ((node_server) => ({ - "host": (() => { - return (node_server["host"] ?? "::"); - }) (), - "port": (node_server["port"] ?? 7845), - "path_base": (node_server["path_base"] ?? ""), - })) (conf_raw["server"] ?? {}) - ), - "database": ( - ((node_database) => { - const kind : string = (node_database["kind"] ?? "sqlite"); - const node_database_data_raw = (node_database["data"] ?? {}); - switch (kind) { - case "sqlite": { - return { - "kind": kind, - "data": { - "path": (node_database_data_raw["path"] ?? "data.sqlite"), - } - }; - break; - } - case "postgresql": { - return { - "kind": kind, - "data": node_database_data_raw, - }; - break; - } - default: { - throw (new Error("unhandled")); - break; - } - } - }) (conf_raw["database"] ?? {}) - ), - "session_management": ( - ((node_session_management) => ({ - "in_memory": (node_session_management["in_memory"] ?? true), - "drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true), - "lifetime": (node_session_management["lifetime"] ?? 900), - })) (conf_raw["session_management"] ?? {}) - ), - }; - } - - - /** - * @todo mandatory fields - */ - export async function load( - path : string - ) : Promise - { - let conf_raw : any; - if (! (await lib_plankton.file.exists(path))) { - // return Promise.reject(new Error("configuration file not found: " + path + "; using fallback")); - conf_raw = {}; - } - else { - try { - conf_raw = lib_plankton.json.decode(await lib_plankton.file.read(path)); - } - catch (error) { - conf_raw = null; - } - } - if (conf_raw === null) { - return Promise.reject("configuration file could not be read"); - } - else { - inject(conf_raw); - // process.stderr.write(JSON.stringify(_data, undefined, "\t")); - return Promise.resolve(undefined); - } + return _schema; } /** */ export function get( - ) : type_conf + ) : any { if (_data === null) { throw (new Error("conf not loaded yet")); @@ -252,4 +221,18 @@ namespace _zeitbild.conf } } + + /** + */ + export async function init( + path : string + ) : Promise + { + _data = await lib_plankton.conf.load( + _schema, + path + ); + return Promise.resolve(undefined); + } + } diff --git a/source/main.ts b/source/main.ts index ad2ff7e..cc5846c 100644 --- a/source/main.ts +++ b/source/main.ts @@ -1,4 +1,90 @@ +/** + */ +type type_data = { + users : Array< + { + id : int; + name : string; + email_address : string; + password : string; + } + >; + calendars : Array< + { + id : int; + name : string; + public : boolean; + members : Array< + { + user_id : int; + role : _zeitbild.type.role; + } + >; + resource : _zeitbild.type.resource_object; + } + >; +}; + + +/** + */ +async function data_init( + data : type_data +) : Promise +{ + let track : { + user : Record< + int, + _zeitbild.type.user_id + >; + calendar : Record< + int, + _zeitbild.type.user_id + >; + } = { + "user": {}, + "calendar": {}, + }; + for await (const user_raw of data.users) { + const user_id : _zeitbild.type.user_id = await _zeitbild.service.user.add( + { + "name": user_raw.name, + "email_address": user_raw.email_address, + } + ); + await _zeitbild.service.auth_internal.set( + user_raw.name, + user_raw.password + ); + track.user[user_raw.id] = user_id; + } + for await (const calendar_raw of data.calendars) { + const resource_id : _zeitbild.type.resource_id = await _zeitbild.service.resource.add( + calendar_raw.resource + ); + const calendar_id : _zeitbild.type.calendar_id = await _zeitbild.service.calendar.add( + { + "name": calendar_raw.name, + "public": calendar_raw.public, + "members": ( + calendar_raw.members + .map( + (member_raw) => ({ + "user_id": track.user[member_raw.user_id], + "role": member_raw.role, + }) + ) + ), + "resource_id": resource_id, + } + ); + track.calendar[calendar_raw.id] = calendar_id; + } + return Promise.resolve(undefined); +} + + /** */ async function main( @@ -35,8 +121,16 @@ async function main( "description": "api-doc" }, { - "name": "expose-conf", - "description": "expose-conf" + "name": "conf-schema", + "description": "conf-schema" + }, + { + "name": "conf-expose", + "description": "conf-expose" + }, + { + "name": "fill", + "description": "fill" }, { "name": "help", @@ -88,10 +182,12 @@ async function main( const args : Record = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" ")); // init2 - await _zeitbild.conf.load(args["conf_path"]); + await _zeitbild.conf.init( + args["conf_path"] + ); lib_plankton.log.conf_push( _zeitbild.conf.get().log.map( - log_output => lib_plankton.log.channel_make( + (log_output : any) => lib_plankton.log.channel_make( { "kind": log_output.kind, "data": log_output.data @@ -125,7 +221,19 @@ async function main( ); break; } - case "expose-conf": { + case "conf-schema": { + process.stdout.write( + JSON.stringify( + _zeitbild.conf.schema(), + undefined, + "\t" + ) + + + "\n" + ); + break; + } + case "conf-expose": { process.stdout.write( JSON.stringify( _zeitbild.conf.get(), @@ -150,6 +258,15 @@ async function main( ); break; } + case "fill": { + await data_init( + lib_plankton.json.decode( + await lib_plankton.file.read(args.data_path) + ) + ); + process.stdout.write("-- done\n"); + break; + } case "serve": { // prepare database await _zeitbild.database.check(); @@ -184,6 +301,8 @@ async function main( } ); + await _zeitbild.auth.init(); + const rest_subject : lib_plankton.rest.type_rest = _zeitbild.api.make(); const server : lib_plankton.server.type_subject = lib_plankton.server.make( async (input, metadata) => { @@ -219,9 +338,12 @@ async function main( ( main(process.argv.slice(2)) .then( - () => {} + () => { + } ) .catch( - (error) => {process.stderr.write(String(error) + "\n");} + (error) => { + process.stderr.write(String(error) + "\n"); + } ) ); diff --git a/source/repositories/auth_internal.ts b/source/repositories/auth_internal.ts new file mode 100644 index 0000000..31ba27b --- /dev/null +++ b/source/repositories/auth_internal.ts @@ -0,0 +1,77 @@ + +namespace _zeitbild.repository.auth_internal +{ + + /** + */ + var _chest : ( + null + | + lib_plankton.storage.type_chest< + Array, + Record, + lib_plankton.database.type_description_create_table, + lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, + Record + > + ) = null; + + + /** + */ + function get_chest( + ) : lib_plankton.storage.type_chest< + Array, + Record, + lib_plankton.database.type_description_create_table, + lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, + Record + > + { + if (_chest === null) { + _chest = lib_plankton.storage.sql_table_common.chest( + { + "database_implementation": _zeitbild.database.get_implementation(), + "table_name": "auth_internal", + "key_names": ["name"], + } + ); + } + else { + // do nothing + } + return _chest; + } + + + /** + */ + export function read( + name : string + ) : Promise + { + return ( + get_chest().read([name]) + .then( + (row) => Promise.resolve(row["password_image"]) + ) + ); + } + + + /** + */ + export function write( + name : string, + password_image : string + ) : Promise + { + return ( + get_chest().write([name], {"password_image": password_image}) + .then( + () => Promise.resolve(undefined) + ) + ); + } + +} diff --git a/source/repositories/resource.ts b/source/repositories/resource.ts index 5a3fd58..c57efe7 100644 --- a/source/repositories/resource.ts +++ b/source/repositories/resource.ts @@ -210,6 +210,92 @@ namespace _zeitbild.repository.resource */ + /** + */ + function encode_event( + event : _zeitbild.type.event_object, + local_resource_id : int + ) : Record + { + /* + const decode_datetime : ((datetime_raw : string) => _zeitbild.helpers.type_datetime) = ((datetime_raw) => { + const parts : Array = datetime_raw.split("|"); + const timezone_shift : int = parseInt(parts[0]); + if (parts[1].length <= 10) { + return { + "timezone_shift": timezone_shift, + "date": { + "year": parseInt(parts[1].slice(0, 4)), + "month": parseInt(parts[1].slice(5, 7)), + "day": parseInt(parts[1].slice(8, 10)), + }, + "time": null + }; + } + else { + return { + "timezone_shift": timezone_shift, + "date": { + "year": parseInt(parts[1].slice(0, 4)), + "month": parseInt(parts[1].slice(5, 7)), + "day": parseInt(parts[1].slice(8, 10)), + }, + "time": { + "hour": parseInt(parts[1].slice(11, 13)), + "minute": parseInt(parts[1].slice(14, 16)), + "second": parseInt(parts[1].slice(17, 19)), + } + }; + } + }); + */ + const encode_datetime : ((datetime : _zeitbild.helpers.type_datetime) => string) = ((datetime) => { + return lib_plankton.string.coin( + "{{timezone_shift}}|{{date}}{{macro_time}}", + { + "timezone_shift": datetime.timezone_shift.toFixed(0).padStart(2, "0"), + "date": lib_plankton.string.coin( + "{{year}}-{{month}}-{{day}}", + { + "year": datetime.date.year.toFixed(0).padStart(4, "0"), + "month": datetime.date.month.toFixed(0).padStart(2, "0"), + "day": datetime.date.day.toFixed(0).padStart(2, "0"), + } + ), + "macro_time": ( + (datetime.time === null) + ? + "" + : + lib_plankton.string.coin( + "T{{hour}}:{{minute}}:{{second}}", + { + "hour": datetime.time.hour.toFixed(0).padStart(2, "0"), + "minute": datetime.time.minute.toFixed(0).padStart(2, "0"), + "second": datetime.time.second.toFixed(0).padStart(2, "0"), + } + ) + ), + } + ); + }); + return { + "local_resource_id": local_resource_id, + "name": event.name, + "begin": encode_datetime(event.begin), + "end": ( + (event.end === null) + ? + null + : + encode_datetime(event.end) + ), + "location": event.location, + "description": event.description, + } + } + + /** */ function decode_event( @@ -311,4 +397,58 @@ namespace _zeitbild.repository.resource } } + + /** + */ + export async function create( + resource_object : _zeitbild.type.resource_object + ) : Promise<_zeitbild.type.resource_id> + { + switch (resource_object.kind) { + case "local": { + const local_resource_id : int = await get_local_resource_core_store().create( + { + "_dummy": null, + } + ); + for await (const event of resource_object.data.events) { + get_local_resource_event_store().create( + encode_event( + event, + local_resource_id + ) + ) + } + const resource_id : _zeitbild.type.resource_id = await get_resource_core_store().create( + { + "kind": "local", + "sub_id": local_resource_id, + } + ); + return Promise.resolve<_zeitbild.type.resource_id>(resource_id); + break; + } + case "caldav": { + const caldav_resource_id : int = await get_caldav_resource_store().create( + { + "url": resource_object.data.url, + "read_only": resource_object.data.read_only, + } + ); + const resource_id : _zeitbild.type.resource_id = await get_local_resource_core_store().create( + { + "kind": "caldav", + "sub_id": caldav_resource_id, + } + ); + return Promise.resolve<_zeitbild.type.resource_id>(resource_id); + break; + } + default: { + throw (new Error("not implemended")); + break; + } + } + } + } diff --git a/source/repositories/user.ts b/source/repositories/user.ts new file mode 100644 index 0000000..06d4752 --- /dev/null +++ b/source/repositories/user.ts @@ -0,0 +1,119 @@ + +namespace _zeitbild.repository.user +{ + + /** + */ + var _store : ( + null + | + lib_plankton.storage.type_store< + _zeitbild.type.user_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + ) = null; + + + /** + */ + function get_store( + ) : lib_plankton.storage.type_store< + _zeitbild.type.user_id, + Record, + {}, + lib_plankton.storage.type_sql_table_autokey_search_term, + Record + > + { + if (_store === null) { + _store = lib_plankton.storage.sql_table_autokey_store( + { + "database_implementation": _zeitbild.database.get_implementation(), + "table_name": "users", + "key_name": "id", + } + ); + } + else { + // do nothing + } + return _store; + } + + + /** + */ + function encode( + user_object : _zeitbild.type.user_object + ) : Record + { + return { + "name": user_object.name, + "email_address": user_object.email_address, + }; + } + + + /** + */ + function decode( + row : Record + ) : _zeitbild.type.user_object + { + return { + "name": row["name"], + "email_address": row["email_address"], + }; + } + + + /** + */ + export async function read( + user_id : _zeitbild.type.user_id + ) : Promise<_zeitbild.type.user_object> + { + const row : Record = await get_store().read(user_id); + const user_object : _zeitbild.type.user_object = decode(row); + return Promise.resolve<_zeitbild.type.user_object>(user_object); + } + + + /** + */ + export async function create( + user_object : _zeitbild.type.user_object + ) : Promise<_zeitbild.type.user_id> + { + const row : Record = encode(user_object); + const user_id : _zeitbild.type.user_id = await get_store().create(row); + return Promise.resolve<_zeitbild.type.user_id>(user_id); + } + + + /** + */ + export async function identify( + name : string + ) : Promise<_zeitbild.type.user_id> + { + const hits : Array<{key : _zeitbild.type.user_id; preview : any;}> = await get_store().search( + { + "expression": "(name = $name)", + "arguments": { + "name": name, + } + } + ); + if (hits.length <= 0) { + return Promise.reject<_zeitbild.type.user_id>(new Error("not found")); + } + else { + return Promise.resolve<_zeitbild.type.user_id>(hits[0].key); + } + } + +} diff --git a/source/services/auth_internal.ts b/source/services/auth_internal.ts new file mode 100644 index 0000000..e5535ad --- /dev/null +++ b/source/services/auth_internal.ts @@ -0,0 +1,40 @@ + +namespace _zeitbild.service.auth_internal +{ + + /** + */ + export function set( + name : string, + password : string + ) : Promise + { + return ( + lib_plankton.bcrypt.compute(password) + .then( + (password_image) => _zeitbild.repository.auth_internal.write(name, password_image) + ) + ); + } + + + /** + */ + export async function check( + name : string, + password : string + ) : Promise + { + try { + const password_image : string = await _zeitbild.repository.auth_internal.read(name); + return lib_plankton.bcrypt.compare( + password_image, + password + ); + } + catch (error) { + return Promise.resolve(false); + } + } + +} diff --git a/source/services/calendar.ts b/source/services/calendar.ts index 8dc9256..48d3da2 100644 --- a/source/services/calendar.ts +++ b/source/services/calendar.ts @@ -2,6 +2,16 @@ namespace _zeitbild.service.calendar { + /** + */ + export function add( + calendar_object : _zeitbild.type.calendar_object + ) : Promise<_zeitbild.type.calendar_id> + { + return _zeitbild.repository.calendar.create(calendar_object); + } + + /** */ export async function list( diff --git a/source/services/resource.ts b/source/services/resource.ts new file mode 100644 index 0000000..11e13a5 --- /dev/null +++ b/source/services/resource.ts @@ -0,0 +1,14 @@ + +namespace _zeitbild.service.resource +{ + + /** + */ + export function add( + resource_object : _zeitbild.type.resource_object + ) : Promise<_zeitbild.type.resource_id> + { + return _zeitbild.repository.resource.create(resource_object); + } + +} diff --git a/source/services/user.ts b/source/services/user.ts new file mode 100644 index 0000000..7ea5a5a --- /dev/null +++ b/source/services/user.ts @@ -0,0 +1,24 @@ + +namespace _zeitbild.service.user +{ + + /** + */ + export function add( + user_object : _zeitbild.type.user_object + ) : Promise<_zeitbild.type.user_id> + { + return _zeitbild.repository.user.create(user_object); + } + + + /** + */ + export function identify( + name : string + ) : Promise<_zeitbild.type.user_id> + { + return _zeitbild.repository.user.identify(name); + } + +} diff --git a/tools/makefile b/tools/makefile index 48cb83a..1df0b18 100644 --- a/tools/makefile +++ b/tools/makefile @@ -18,16 +18,32 @@ cmd_tsc := ${dir_tools}/typescript/node_modules/.bin/tsc ## rules .PHONY: default -default: ${dir_build}/zeitbild +default: ${dir_build}/zeitbild node_modules +.PHONY: node_modules +node_modules: + @ cd ${dir_build} && npm install sqlite3 bcrypt + +${dir_temp}/conf.ts: \ + ${dir_source}/conf.ts.tpl \ + ${dir_source}/conf.schema.json + @ ${cmd_mkdir} $(dir $@) + ${dir_tools}/coin $@ + ${dir_temp}/zeitbild-unlinked.js: \ ${dir_lib}/plankton/plankton.d.ts \ ${dir_source}/helpers.ts \ ${dir_source}/conf.ts \ ${dir_source}/database.ts \ + ${dir_source}/auth.ts \ ${dir_source}/types.ts \ + ${dir_source}/repositories/auth_internal.ts \ + ${dir_source}/repositories/user.ts \ ${dir_source}/repositories/resource.ts \ ${dir_source}/repositories/calendar.ts \ + ${dir_source}/services/auth_internal.ts \ + ${dir_source}/services/user.ts \ + ${dir_source}/services/resource.ts \ ${dir_source}/services/calendar.ts \ ${dir_source}/api/base.ts \ ${dir_source}/api/actions/meta_ping.ts \ diff --git a/tools/update-plankton b/tools/update-plankton index 5f658b0..ea7ca0e 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -8,21 +8,23 @@ modules="" modules="${modules} base" modules="${modules} call" modules="${modules} log" +modules="${modules} conf" modules="${modules} storage" modules="${modules} database" modules="${modules} session" modules="${modules} file" modules="${modules} string" -modules="${modules} structures" modules="${modules} json" modules="${modules} ical" modules="${modules} url" modules="${modules} http" modules="${modules} api" modules="${modules} rest" +modules="${modules} rest" modules="${modules} server" modules="${modules} args" -modules="${modules} auth" +# modules="${modules} auth" +modules="${modules} bcrypt" ## exec