From 03f29fae111e8acf92e43690ab12ac3445d551a5 Mon Sep 17 00:00:00 2001 From: Fenris Wolf Date: Thu, 19 Sep 2024 01:40:27 +0200 Subject: [PATCH] [mod] --- conf/example.json | 3 +- lib/plankton/plankton.d.ts | 2067 +++---------- lib/plankton/plankton.js | 5988 ++++++++++++------------------------ source/index.html | 2 +- source/logic/backend.ts | 416 +-- source/logic/conf.ts | 95 + source/logic/helpers.ts | 56 +- source/logic/main.ts | 41 +- source/logic/types.ts | 6 +- source/logic/view.ts | 284 +- tools/build | 19 - tools/makefile | 3 +- tools/update-plankton | 6 +- 13 files changed, 2805 insertions(+), 6181 deletions(-) create mode 100644 source/logic/conf.ts diff --git a/conf/example.json b/conf/example.json index 63ec3b1..a65c065 100644 --- a/conf/example.json +++ b/conf/example.json @@ -1,4 +1,3 @@ { - "view_mode": "table", - "timezone_shift": 0 + "version": 1 } diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 28f1eb6..8b4eea3 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -718,1045 +718,6 @@ declare namespace lib_plankton.file { */ function blob_write_text(text: string): lib_plankton.call.type_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.code { /** * @author fenris @@ -3190,117 +2151,6 @@ declare namespace lib_plankton.color { value?: float; }): type_color; } -declare namespace lib_plankton.color { - /** - * @author fenris - */ - class class_color { - /** - * @author fenris - */ - private subject; - /** - * @author fenris - */ - protected constructor(subject: type_color); - /** - * @author fenris - */ - private static _cram; - /** - * @author fenris - */ - private static _tear; - /** - * @author fenris - */ - static make_hsv({ "hue": hue, "saturation": saturation, "value": value }: { - hue?: float; - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - blend(color: class_color, strength?: float): class_color; - /** - * @author fenris - */ - output_rgb(): string; - /** - * @author fenris - */ - output_hex(): string; - /** - * @author fenris - */ - output_dot(): string; - /** - * @author fenris - */ - static give_generic({ "n": n, "offset": offset, "saturation": saturation, "value": value, }: { - n: int; - offset?: float; - saturation?: float; - value?: float; - }): class_color; - static generic(x: any): class_color; - /** - * @author fenris - */ - static give_gray(value?: float): class_color; - /** - * @author fenris - */ - static give_black(): class_color; - /** - * @author fenris - */ - static give_white(): class_color; - /** - * @author fenris - */ - static give_red({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_green({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_blue({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_yellow({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_cyan({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - /** - * @author fenris - */ - static give_magenta({ "saturation": saturation, "value": value, }?: { - saturation?: float; - value?: float; - }): class_color; - } -} /** * @author fenris */ @@ -3378,515 +2228,155 @@ declare namespace lib_plankton.xml { compile(depth?: int): string; } } -declare module lib_et { +declare namespace lib_plankton.map { /** - * @desc type of extended timestamp - * @author fenris */ - type type_et = { - era: int; - stamp: int; - }; - /** - * @desc type of UNIX timestamp - * @author fenris - */ - type type_timestamp = int; - /** - * @desc type of Javascript Date object - * @author fenris - */ - type type_jsdate = Date; - /** - * @author fenris - */ - type type_components = { - year: int; - month: int; - day: int; - hour: int; - minute: int; - second: int; + type type_pair = { + key: type_key; + value: type_value; }; /** * @author fenris */ - type type_ywd = { - year: int; - week: int; - day: int; + type type_map = { + size: (() => int); + has: ((key: type_key) => boolean); + get: ((key: type_key, fallback?: lib_plankton.pod.type_pod) => type_value); + set: ((key: type_key, value: type_value) => void); + delete: ((key: type_key) => void); + iterate: ((procedure: ((value: type_value, key?: type_key) => void)) => void); }; - /** - * @author fenris - */ - function part(et1: type_et, et2: type_et): type_et; - /** - * @desc less - * @author fenris - */ - function before(reference: type_et, et: type_et): boolean; - /** - * @desc greater - * @author fenris - */ - function after(reference: type_et, et: type_et): boolean; - /** - * @author fenris - */ - function between(begin: type_et, end: type_et, et: type_et): boolean; - /** - * @author fenris - */ - function intersect(begin1: type_et, end1: type_et, begin2: type_et, end2: type_et): boolean; - /** - * @author fenris - */ - function move(base: type_et, span: type_et): type_et; - /** - * @desc currified version of "move" - * @author fenris - */ - function move_(span: type_et): (base: type_et) => type_et; - /** - * @author fenris - */ - function from_timestamp(timestamp: type_timestamp): type_et; - /** - * @author fenris - */ - function to_timestamp(et: type_et): type_timestamp; - /** - * @author fenris - */ - function from_jsdate(jsdate: type_jsdate): type_et; - /** - * @author fenris - */ - function to_jsdate(et: type_et): type_jsdate; - /** - * @author fenris - */ - function from_components(components: type_components): type_et; - /** - * @author fenris - */ - function to_components(et: type_et): type_components; - /** - * @author fenris - */ - function now(): type_et; - /** - * @author fenris - */ - function to_string(et: type_et): string; - /** - * @author fenris - */ - function to_string_ywd(et: type_et): string; - /** - * @desc retrieve week of year - * @author fenris - */ - function get_woy(et: type_et): int; - /** - * @desc retrieve day of week - * @author fenris - */ - function get_dow(et: type_et): int; - /** - * @author fenris - */ - function trunc_minute(et?: type_et): type_et; - /** - * @author fenris - */ - function trunc_hour(et?: type_et): type_et; - /** - * @author fenris - */ - function trunc_day(et?: type_et): type_et; - /** - * @author fenris - */ - function trunc_month(et?: type_et): type_et; - /** - * @author fenris - */ - function trunc_year(et?: type_et): type_et; - /** - * @author fenris - */ - function trunc_week(et?: type_et): type_et; - /** - * @author fenris - */ - function span_second(seconds?: int): type_et; - /** - * @author fenris - */ - function span_minute(minutes?: int): type_et; - /** - * @author fenris - */ - function span_hour(hours?: int): type_et; - /** - * @author fenris - */ - function span_day(days?: int): type_et; - /** - * @author fenris - */ - function span_week(weeks?: int): type_et; - /** - * @author fenris - */ - function span_year(years?: int): type_et; } -declare module lib_et { +declare namespace lib_plankton.map { /** - * @author fenris */ - class class_et { - /** - * @author fenris - */ - protected subject: type_et; - /** - * @author fenris - */ - constructor(subject: type_et); - /** - * @author fenris - */ - move(et: class_et): class_et; - /** - * @author fenris - */ - before(et: class_et): boolean; - /** - * @author fenris - */ - after(et: class_et): boolean; - /** - * @author fenris - */ - between(et1: class_et, et2: class_et): boolean; - /** - * @author fenris - */ - trunc_minute(): class_et; - /** - * @author fenris - */ - trunc_hour(): class_et; - /** - * @author fenris - */ - trunc_day(): class_et; - /** - * @author fenris - */ - trunc_month(): class_et; - /** - * @author fenris - */ - trunc_year(): class_et; - /** - * @author fenris - */ - trunc_week(): class_et; - /** - * @author fenris - */ - static now(): class_et; - /** - * @author fenris - */ - static span_second(count?: int): class_et; - /** - * @author fenris - */ - static span_minute(count?: int): class_et; - /** - * @author fenris - */ - static span_hour(count?: int): class_et; - /** - * @author fenris - */ - static span_day(count?: int): class_et; - /** - * @author fenris - */ - static span_week(count?: int): class_et; - /** - * @author fenris - */ - static span_year(count?: int): class_et; - /** - * @author fenris - */ - static from_timestamp(timestamp: type_timestamp): class_et; - /** - * @author fenris - */ - to_timestamp(): type_timestamp; - /** - * @author fenris - */ - static from_jsdate(jsdate: type_jsdate): class_et; - /** - * @author fenris - */ - to_jsdate(): type_jsdate; - /** - * @author fenris - */ - static from_components(components: type_components): class_et; - /** - * @author fenris - */ - to_components(): type_components; - /** - * @author fenris - */ - get_woy(): int; - /** - * @author fenris - */ - get_dow(): int; - /** - * @author fenris - */ - to_string(): string; - } + function clear(map: type_map): void; + /** + */ + function keys(map: type_map): Array; + /** + */ + function values(map: type_map): Array; + /** + */ + function dump(map: type_map): Array>; + /** + */ + function show(map: type_map, options?: { + show_key?: ((key: type_key) => string); + show_value?: ((value: type_value) => string); + }): string; } -declare var global_config: any; -/** - * @author neuc - */ -declare namespace lib_plankton.date { - /** - * @author neu3no, fenris - */ - function set_days(day_names: Array): void; - /** - * @author neu3no, fenris - */ - function set_months(month_names: Array): void; - /** - * @desc week of year - * @param {Date} date - * @return {int} - * @author fenris - */ - function get_week(date: Date): int; - /** - * @author neu3no, fenris - */ - function set_currentDate(date: Date): void; - /** - * @author neu3no, fenris - */ - function parse(format: string, date?: Date): string; - /** - * @author neu3no, fenris - */ - function locale_date(date?: Date, ignore_error?: boolean): string; +declare namespace lib_plankton.map.simplemap { /** */ - type type_unixtimestamp = int; - /** - */ - type type_components = { - timezone_offset: int; - year: int; - month: int; - day: int; - hour: int; - minute: int; - second: int; + type type_subject = { + data: Record; }; /** */ - function now(): type_unixtimestamp; + function make(options?: { + data?: Record; + }): type_subject; /** */ - function from_components(components: type_components): type_unixtimestamp; + function size(subject: type_subject): int; /** */ - function to_components(unixtimestamp: type_unixtimestamp): type_components; + function has(subject: type_subject, key: string): boolean; /** */ - function get_timestamp_from_year_and_week_and_day(year: int, week: int, day: int): type_unixtimestamp; + function get_safe(subject: type_subject, key: string): lib_plankton.pod.type_pod; + /** + */ + function get(subject: type_subject, key: string, fallback?: lib_plankton.pod.type_pod): type_value; + /** + */ + function set(subject: type_subject, key: string, value: type_value): void; + /** + */ + function delete_(subject: type_subject, key: string): void; + /** + */ + function iterate(subject: type_subject, procedure: ((value?: type_value, key?: string) => void)): void; + /** + */ + function implementation_map(subject: type_subject): type_map; } -declare var strftime: typeof lib_plankton.date; -declare namespace lib_plankton.ical { +declare namespace lib_plankton.map.hashmap { /** + * we base the hashmap on a simplemap, whos keys are the hashes and whos values are the key/value-pairs */ - type type_rrule = { - freq?: string; - byday?: string; - bymonth?: string; + type type_subject = { + hashing: ((key: type_key) => string); + core: lib_plankton.map.simplemap.type_subject>; }; /** */ - type type_offset = string; + function make(hashing: ((key: type_key) => string), options?: { + pairs?: Array>; + }): type_subject; /** */ + function size(subject: type_subject): int; /** */ - export enum enum_class { - public = "public", - private = "private", - confidential = "confidential" - } + function has(subject: type_subject, key: type_key): boolean; /** */ - export enum enum_event_status { - tentative = "tentative", - confirmed = "confirmed", - cancelled = "cancelled" - } + function get(subject: type_subject, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; /** */ - export enum enum_transp { - opaque = "opaque", - transparent = "transparent" - } + function set(subject: type_subject, key: type_key, value: type_value): void; /** */ - type type_tzid = string; + function delete_(subject: type_subject, key: type_key): void; /** */ - export type type_date = { - year: int; - month: int; - day: int; + function iterate(subject: type_subject, procedure: ((value?: type_value, key?: type_key) => void)): void; + /** + */ + function implementation_map(subject: type_subject): type_map; +} +declare namespace lib_plankton.map.collatemap { + /** + */ + type type_collation = ((key1: type_key, key2: type_key) => boolean); + /** + */ + export type type_subject = { + collation: type_collation; + pairs: Array>; }; /** */ - export type type_time = { - hour: int; - minute: int; - second: int; - utc: boolean; - }; + export function make(collation: type_collation, options?: { + pairs?: Array>; + }): type_subject; /** */ - export type type_datetime = { - date: type_date; - time: (null | type_time); - }; + export function size(subject: type_subject): int; /** */ - export type type_dt = { - tzid: type_tzid; - value: type_datetime; - }; + export function has(subject: type_subject, key: type_key): boolean; + /** + * @todo use .find + */ + export function get(subject: type_subject, key: type_key, fallback?: lib_plankton.pod.type_pod): type_value; /** */ - type type_duration = { - negative: boolean; - weeks?: int; - days?: int; - hours?: int; - minutes?: int; - seconds?: int; - }; + export function set(subject: type_subject, key: type_key, value: type_value): void; /** */ - type type_vtimezone = { - tzid?: type_tzid; - standard?: { - dtstart: type_datetime; - rrule: type_rrule; - tzoffsetfrom?: type_offset; - tzoffsetto?: type_offset; - }; - daylight?: { - dtstart: type_datetime; - rrule: type_rrule; - tzoffsetfrom?: type_offset; - tzoffsetto?: type_offset; - }; - }; + export function delete_(subject: type_subject, key: type_key): void; /** - * @see https://www.rfc-editor.org/rfc/rfc5545#section-3.6.1 */ - export type type_vevent = { - uid: string; - dtstamp: type_datetime; - dtstart?: type_dt; - class?: enum_class; - created?: type_datetime; - description?: string; - geo?: { - latitude: float; - longitude: float; - }; - last_modified?: type_datetime; - location?: string; - organizer?: { - cn?: string; - value?: string; - }; - priority?: int; - sequence?: int; - status?: enum_event_status; - summary?: string; - transp?: enum_transp; - url?: string; - recurid?: any; - rrule?: type_rrule; - dtend?: type_dt; - duration?: type_duration; - attach?: any; - attendee?: string; - categories?: Array; - comment?: any; - contact?: any; - exdate?: any; - rstatus?: any; - related?: any; - resources?: any; - rdate?: any; - x_props?: Record; - iana_props?: Record; - }; + export function iterate(subject: type_subject, function_: ((value?: type_value, key?: type_key) => void)): void; /** - * @see https://www.rfc-editor.org/rfc/rfc5545#section-3.4 */ - export type type_vcalendar = { - version: string; - prodid: string; - vevents: Array; - calscale?: string; - method?: string; - vtimezone?: type_vtimezone; - x_props?: Record; - iana_props?: Record; - }; + export function implementation_map(subject: type_subject): type_map; export {}; } -declare namespace lib_plankton.ical { - /** - */ - function datetime_to_unixtimestamp(datetime: type_datetime): lib_plankton.date.type_unixtimestamp; - /** - * @see https://www.rfc-editor.org/rfc/rfc5545 - * @see https://icalendar.org/iCalendar-RFC-5545/ - * @todo implement edge cases - */ - function ics_decode(ics: string, options?: { - debug?: boolean; - }): type_vcalendar; - /** - * @todo method - * @todo add missing fields - */ - function ics_encode(vcalendar: type_vcalendar): string; -} declare namespace lib_plankton.http { /** * @author fenris @@ -4046,3 +2536,376 @@ declare namespace lib_plankton.url { decode(x: string): any; } } +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 namespace lib_plankton.www_form { + /** + */ + type type_source = Record; + /** + */ + type type_target = string; + /** + * @author fenris + */ + function encode(source: type_source): type_target; + /** + * @author fenris + */ + function decode(target: type_target): type_source; +} +declare namespace lib_plankton.www_form { + /** + * @author fenris + */ + class class_www_form implements lib_plankton.code.interface_code { + /** + * @author fenris + */ + constructor(); + /** + * @implementation + * @author fenris + */ + encode(source: type_source): type_target; + /** + * @implementation + * @author fenris + */ + decode(target: type_target): type_source; + } +} diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index bc36cbe..4362588 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -1667,2341 +1667,6 @@ var lib_plankton; })(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:code«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -8260,173 +5925,6 @@ var lib_plankton; color_1.give_magenta = give_magenta; })(color = lib_plankton.color || (lib_plankton.color = {})); })(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:color«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:color« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:color« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:color«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var color; - (function (color_2) { - /** - * @author fenris - */ - class class_color { - /** - * @author fenris - */ - constructor(subject) { - this.subject = subject; - } - /** - * @author fenris - */ - static _cram(subject) { - return (new class_color(subject)); - } - /** - * @author fenris - */ - static _tear(instance) { - return (instance.subject); - } - /** - * @author fenris - */ - static make_hsv({ "hue": hue = undefined, "saturation": saturation = undefined, "value": value = undefined }) { - return (class_color._cram(color_2.make_hsv({ - "hue": hue, - "saturation": saturation, - "value": value - }))); - } - /** - * @author fenris - */ - blend(color, strength = 0.5) { - return (class_color._cram(color_2.blend(class_color._tear(this), class_color._tear(color), strength))); - } - /** - * @author fenris - */ - output_rgb() { - return (color_2.output_rgb(class_color._tear(this))); - } - /** - * @author fenris - */ - output_hex() { - return (color_2.output_hex(class_color._tear(this))); - } - /** - * @author fenris - */ - output_dot() { - return (color_2.output_dot(class_color._tear(this))); - } - /** - * @author fenris - */ - static give_generic({ "n": n, "offset": offset = undefined, "saturation": saturation = undefined, "value": value = undefined, }) { - return (class_color._cram(color_2.give_generic(n, { - "offset": offset, - "saturation": saturation, - "value": value, - }))); - } - static generic(x) { return class_color.give_generic(x); } - ; - /** - * @author fenris - */ - static give_gray(value = 0.5) { - return (class_color._cram(color_2.give_gray({ "value": value }))); - } - /** - * @author fenris - */ - static give_black() { - return (class_color._cram(color_2.give_black())); - } - /** - * @author fenris - */ - static give_white() { - return (class_color._cram(color_2.give_white())); - } - /** - * @author fenris - */ - static give_red({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_red({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_green({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_green({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_blue({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_blue({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_yellow({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_yellow({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_cyan({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_cyan({ - "saturation": saturation, - "value": value, - }))); - } - /** - * @author fenris - */ - static give_magenta({ "saturation": saturation = undefined, "value": value = undefined, } = {}) { - return (class_color._cram(color_2.give_magenta({ - "saturation": saturation, - "value": value, - }))); - } - } - color_2.class_color = class_color; - })(color = lib_plankton.color || (lib_plankton.color = {})); -})(lib_plankton || (lib_plankton = {})); var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || @@ -8568,1632 +6066,484 @@ var lib_plankton; })(xml = lib_plankton.xml || (lib_plankton.xml = {})); })(lib_plankton || (lib_plankton = {})); /* -This file is part of »bacterio-plankton:date«. +This file is part of »bacterio-plankton:map«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' -»bacterio-plankton:date« is free software: you can redistribute it and/or modify +»bacterio-plankton:map« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -»bacterio-plankton:date« is distributed in the hope that it will be useful, +»bacterio-plankton:map« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:date«. If not, see . +along with »bacterio-plankton:map«. If not, see . */ -var lib_et; -(function (lib_et) { - /** - * @author fenris - */ - function div(x, y) { - return Math.floor(x / y); - } - /** - * @author fenris - */ - function mod(x, y) { - return (x - (y * div(x, y))); - } - /** - * @author fenris - */ - function json_encode(obj) { - return JSON.stringify(obj); - } - /** - * @desc the maximum of a regular UNIX-timestamp: 2^31-1; one second is cut - * @author fenris - */ - const _modulus = 0x7FFFFFFF; - /** - * @desc add (e1,s1) (e2,s2) = (e1+e2+((s1+s2) div m),(s1+s2) mod m) - * @author fenris - */ - function add(et1, et2) { - let era = (et1.era + et2.era + div(et1.stamp + et2.stamp, _modulus)); - let stamp = mod(et1.stamp + et2.stamp, _modulus); - return { "era": era, "stamp": stamp }; - } - /** - * @desc neutral = (0,0) - */ - function neutral() { - return { "era": 0, "stamp": 0 }; - } - /** - * @desc invert (e,s) = (-1-e,m-s) - */ - function invert(et) { - let era = (-1 - et.era); - let stamp = (_modulus - et.stamp); - return { "era": era, "stamp": stamp }; - } - /** - * @author fenris - */ - function part(et1, et2) { - return add(et1, invert(et2)); - } - lib_et.part = part; - /** - * @desc less - * @author fenris - */ - function before(reference, et) { - let et_ = part(et, reference); - return ((et_.era >= 0) && (et_.stamp > 0)); - } - lib_et.before = before; - /** - * @desc greater - * @author fenris - */ - function after(reference, et) { - let et_ = part(reference, et); - return ((et_.era >= 0) && (et_.stamp > 0)); - } - lib_et.after = after; - /** - * @author fenris - */ - function between(begin, end, et) { - return (before(begin, et) - && - after(end, et)); - } - lib_et.between = between; - /** - * @author fenris - */ - function intersect(begin1, end1, begin2, end2) { - return ((between(begin1, end1, begin2) - || - between(begin1, end1, end2)) - || - (between(begin2, end2, begin1) - || - between(begin2, end2, end1))); - } - lib_et.intersect = intersect; - /** - * @author fenris - */ - function move(base, span) { - return add(base, span); - } - lib_et.move = move; - /** - * @desc currified version of "move" - * @author fenris - */ - function move_(span) { - return (base => move(base, span)); - } - lib_et.move_ = move_; - /** - * @author fenris - */ - function from_timestamp(timestamp) { - let era = div(timestamp, _modulus); - let stamp = mod(timestamp, _modulus); - let et = { "era": era, "stamp": stamp }; - return et; - } - lib_et.from_timestamp = from_timestamp; - /** - * @author fenris - */ - function to_timestamp(et) { - if (et.era != 0) { - const message = "case (era <> 0) not properly implemented"; - console.warn(message + "; well ... i'll do my very best ..."); - // throw (new Error(message)); - } - let timestamp = ((et.era * _modulus) + et.stamp); - return timestamp; - } - lib_et.to_timestamp = to_timestamp; - /** - * @author fenris - */ - function from_jsdate(jsdate) { - const timestamp = Math.floor(jsdate.getTime() / 1000); - const et = from_timestamp(timestamp); - return et; - } - lib_et.from_jsdate = from_jsdate; - /** - * @author fenris - */ - function to_jsdate(et) { - const timestamp = to_timestamp(et); - const jsdate = (new Date(timestamp * 1000)); - return jsdate; - } - lib_et.to_jsdate = to_jsdate; - /** - * @author fenris - */ - function from_components(components) { - const timestamp = Math.floor(Date.UTC((components.year), (components.month - 1), (components.day), (components.hour || 0), (components.minute || 0), (components.second || 0)) - / - 1000); - const et = from_timestamp(timestamp); - return et; - } - lib_et.from_components = from_components; - /** - * @author fenris - */ - function to_components(et) { - const jsdate = to_jsdate(et); - const components = { - "year": jsdate.getUTCFullYear(), - "month": jsdate.getUTCMonth() + 1, - "day": jsdate.getUTCDate(), - "hour": jsdate.getUTCHours(), - "minute": jsdate.getUTCMinutes(), - "second": jsdate.getUTCSeconds(), - }; - return components; - } - lib_et.to_components = to_components; - /** - * @author fenris - */ - function now() { - let timestamp = Math.floor(Date.now() / 1000); - let et = from_timestamp(timestamp); - return et; - } - lib_et.now = now; - /** - * @author fenris - */ - function to_string(et) { - // return (json_encode(et) + " ~ " + json_encode(to_components(et))); - return to_jsdate(et).toUTCString(); - } - lib_et.to_string = to_string; - /** - * @author fenris - */ - function to_string_ywd(et) { - // return (json_encode(et) + " ~ " + json_encode(to_components(et))); - return to_jsdate(et).toUTCString(); - } - lib_et.to_string_ywd = to_string_ywd; - /** - * @desc retrieve week of year - * @author fenris - */ - function get_woy(et) { - let jsdate = to_jsdate(et); - let begin_of_year = new Date(jsdate.getFullYear(), 0, 1, 12, 0, 0); - let day_of_week = begin_of_year.getDay(); - let overhang = (day_of_week >= 4); - let factor = (1000 * 60 * 60 * 24); - let days = ((jsdate.getTime() - begin_of_year.getTime()) / factor); - let week = (Math.ceil((days + day_of_week) / 7) - (overhang ? 1 : 0)); - return week; - } - lib_et.get_woy = get_woy; - /** - * @desc retrieve day of week - * @author fenris - */ - function get_dow(et) { - let jsdate = to_jsdate(et); - let dow = (mod(jsdate.getDay() - 1, 7) + 1); - return dow; - } - lib_et.get_dow = get_dow; - /** - * @author fenris - */ - function trunc_minute(et = now()) { - let components = to_components(et); - let components_ = { - "year": components.year, - "month": components.month, - "day": components.day, - "hour": components.hour, - "minute": components.minute, - "second": 0 - }; - let et_ = from_components(components_); - return et_; - } - lib_et.trunc_minute = trunc_minute; - /** - * @author fenris - */ - function trunc_hour(et = now()) { - let components = to_components(et); - let components_ = { - "year": components.year, - "month": components.month, - "day": components.day, - "hour": components.hour, - "minute": 0, - "second": 0 - }; - let et_ = from_components(components_); - return et_; - } - lib_et.trunc_hour = trunc_hour; - /** - * @author fenris - */ - function trunc_day(et = now()) { - let components = to_components(et); - let components_ = { - "year": components.year, - "month": components.month, - "day": components.day, - "hour": 0, - "minute": 0, - "second": 0 - }; - let et_ = from_components(components_); - return et_; - } - lib_et.trunc_day = trunc_day; - /** - * @author fenris - */ - function trunc_month(et = now()) { - let components = to_components(et); - let components_ = { - "year": components.year, - "month": components.month, - "day": 0, - "hour": 0, - "minute": 0, - "second": 0 - }; - let et_ = from_components(components_); - return et_; - } - lib_et.trunc_month = trunc_month; - /** - * @author fenris - */ - function trunc_year(et = now()) { - let components = to_components(et); - let components_ = { - "year": components.year, - "month": 0, - "day": 0, - "hour": 0, - "minute": 0, - "second": 0 - }; - let et_ = from_components(components_); - return et_; - } - lib_et.trunc_year = trunc_year; - /** - * @author fenris - */ - function trunc_week(et = now()) { - let et_ = trunc_day(et); - while (to_jsdate(et_).getDay() > 1) { - et_ = add(et_, span_day(-1)); - } - return et_; - } - lib_et.trunc_week = trunc_week; - /** - * @author fenris - */ - function span_second(seconds = 1) { - return from_timestamp(seconds); - } - lib_et.span_second = span_second; - /** - * @author fenris - */ - function span_minute(minutes = 1) { - return span_second(minutes * 60); - } - lib_et.span_minute = span_minute; - /** - * @author fenris - */ - function span_hour(hours = 1) { - return span_minute(hours * 60); - } - lib_et.span_hour = span_hour; - /** - * @author fenris - */ - function span_day(days = 1) { - return span_hour(days * 24); - } - lib_et.span_day = span_day; - /** - * @author fenris - */ - function span_week(weeks = 1) { - return span_day(weeks * 7); - } - lib_et.span_week = span_week; - /** - * @author fenris - */ - function span_year(years = 1) { - return span_second(Math.floor(years * 365.25 * 24 * 60 * 60)); - } - lib_et.span_year = span_year; -})(lib_et || (lib_et = {})); /* -This file is part of »bacterio-plankton:date«. +This file is part of »bacterio-plankton:map«. Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' -»bacterio-plankton:date« is free software: you can redistribute it and/or modify +»bacterio-plankton:map« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -»bacterio-plankton:date« is distributed in the hope that it will be useful, +»bacterio-plankton:map« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:date«. If not, see . - */ -var lib_et; -(function (lib_et) { - /** - * @author fenris - */ - class class_et { - /** - * @author fenris - */ - constructor(subject) { - this.subject = subject; - } - /** - * @author fenris - */ - move(et) { - return (new class_et(lib_et.move(this.subject, et.subject))); - } - /** - * @author fenris - */ - before(et) { - return lib_et.before(et.subject, this.subject); - } - /** - * @author fenris - */ - after(et) { - return lib_et.after(et.subject, this.subject); - } - /** - * @author fenris - */ - between(et1, et2) { - return lib_et.between(et1.subject, et2.subject, this.subject); - } - /** - * @author fenris - */ - trunc_minute() { - return (new class_et(lib_et.trunc_minute(this.subject))); - } - /** - * @author fenris - */ - trunc_hour() { - return (new class_et(lib_et.trunc_hour(this.subject))); - } - /** - * @author fenris - */ - trunc_day() { - return (new class_et(lib_et.trunc_day(this.subject))); - } - /** - * @author fenris - */ - trunc_month() { - return (new class_et(lib_et.trunc_month(this.subject))); - } - /** - * @author fenris - */ - trunc_year() { - return (new class_et(lib_et.trunc_year(this.subject))); - } - /** - * @author fenris - */ - trunc_week() { - return (new class_et(lib_et.trunc_week(this.subject))); - } - /** - * @author fenris - */ - static now() { - return (new class_et(lib_et.now())); - } - /** - * @author fenris - */ - static span_second(count = 1) { - return (new class_et(lib_et.span_second(count))); - } - /** - * @author fenris - */ - static span_minute(count = 1) { - return (new class_et(lib_et.span_minute(count))); - } - /** - * @author fenris - */ - static span_hour(count = 1) { - return (new class_et(lib_et.span_hour(count))); - } - /** - * @author fenris - */ - static span_day(count = 1) { - return (new class_et(lib_et.span_day(count))); - } - /** - * @author fenris - */ - static span_week(count = 1) { - return (new class_et(lib_et.span_week(count))); - } - /** - * @author fenris - */ - static span_year(count = 1) { - return (new class_et(lib_et.span_year(count))); - } - /** - * @author fenris - */ - static from_timestamp(timestamp) { - return (new class_et(lib_et.from_timestamp(timestamp))); - } - /** - * @author fenris - */ - to_timestamp() { - return lib_et.to_timestamp(this.subject); - } - /** - * @author fenris - */ - static from_jsdate(jsdate) { - return (new class_et(lib_et.from_jsdate(jsdate))); - } - /** - * @author fenris - */ - to_jsdate() { - return lib_et.to_jsdate(this.subject); - } - /** - * @author fenris - */ - static from_components(components) { - return (new class_et(lib_et.from_components(components))); - } - /** - * @author fenris - */ - to_components() { - return lib_et.to_components(this.subject); - } - /** - * @author fenris - */ - get_woy() { - return lib_et.get_woy(this.subject); - } - /** - * @author fenris - */ - get_dow() { - return lib_et.get_dow(this.subject); - } - /** - * @author fenris - */ - to_string() { - return lib_et.to_string(this.subject); - } - } - lib_et.class_et = class_et; -})(lib_et || (lib_et = {})); -/* -This file is part of »bacterio-plankton:date«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:date« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:date« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:date«. If not, see . - */ -/** - * @author neuc +along with »bacterio-plankton:map«. If not, see . */ var lib_plankton; (function (lib_plankton) { - var date; - (function (date_1) { + var map; + (function (map_1) { /** - * @author neu3no, fenris */ - var _days = [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday" - ]; - /** - * @author neu3no, fenris - */ - var _months = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" - ]; - /** - * @author neu3no, fenris - */ - var _segments = { - "%a": (date => _days[date.getDay()].slice(0, 3)), - "%A": (date => _days[date.getDay()]), - "%b": (date => _days[date.getMonth()].slice(0, 3)), - "%B": (date => _days[date.getMonth()]), - "%c": (date => date.toLocaleString()), - "%C": (date => Math.floor((date.getFullYear()) / 100).toString()), - "%d": (date => lib_plankton.string.sprintf("%02d", [date.getDate()])), - "%D": (date => parse("%m/%d/%y", date)), - "%e": (date => lib_plankton.string.sprintf("%2d", [date.getDate()])), - "%F": (date => parse("%Y-%m-%d", date)), - "%g": (date => lib_plankton.string.sprintf("%02d", [date.getFullYear() % 1000])), - "%G": (date => date.getFullYear().toString()), - "%h": (date => parse("%b", date)), - "%H": (date => lib_plankton.string.sprintf("%02d", [date.getHours()])), - "%I": (date => lib_plankton.string.sprintf("%02d", [((date.getHours() > 12) ? (date.getHours() - 12) : date.getHours())])), - "%j": (date => lib_plankton.string.sprintf("%03d", [helper_dayOfYear(date)])), - "%m": (date => lib_plankton.string.sprintf("%02d", [date.getMonth() + 1])), - "%M": (date => lib_plankton.string.sprintf("%02d", [date.getMinutes()])), - "%n": (date => "\n"), - "%p": (date => ((date.getHours() > 12) ? "PM" : "AM")), - "%r": (date => parse("%I:%M:%S %p", date)), - "%R": (date => parse("%H:%M", date)), - "%S": (date => date.getSeconds().toString()), - "%t": (date => "\t"), - "%T": (date => parse("%H:%M:%S", date)), - "%u": (date => lib_plankton.string.sprintf("%02d", [((date.getDay() === 0) ? 7 : date.getDay())])), - "%U": (date => lib_plankton.string.sprintf("%02d", [helper_englishWeekOfYear(date)])), - "%V": (date => lib_plankton.string.sprintf("%02d", [helper_weekOfYear(date)])), - "%w": (date => lib_plankton.string.sprintf("%02d", [date.getDay().toString()])), - "%W": (date => parse("%w", date)), - "%x": (date => parse("%m/%d/%G", date)), - "%X": (date => parse("%T", date)), - "%y": (date => parse("%g", date)), - "%Y": (date => parse("%G", date)), - "%z": (date => date.getTimezoneOffset().toString()), - "%Z": (date => date.toUTCString().split(' ').pop()), - "%%": (date => "%"), - }; - /** - * @author neu3no, fenris - */ - var _currentDate = (new Date(Date.now())); - /** - * @author neu3no, fenris - */ - function set_days(day_names) { - _days = day_names; - } - date_1.set_days = set_days; - /** - * @author neu3no, fenris - */ - function set_months(month_names) { - _months = month_names; - } - date_1.set_months = set_months; - /** - * @desc source: https://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366 - * @author neu3no, fenris - */ - function helper_dayOfYear(date) { - let start = new Date(date.getFullYear(), 0, 0); - let diff = (date.getTime() - start.getTime()); - let oneDay = (1000 * 60 * 60 * 24); - return Math.floor(diff / oneDay); - } - /** - * @desc source: http://weeknumber.net/how-to/javascript - * @author neu3no, fenris - */ - function helper_weekOfYear(date_) { - let date = new Date(date_.getTime()); - date.setHours(0, 0, 0, 0); - // Thursday in current week decides the year. - date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); - // January 4 is always in week 1. - let week1 = new Date(date.getFullYear(), 0, 4); - // Adjust to Thursday in week 1 and count number of weeks from date to week1. - return (1 - + - Math.round((((date.getTime() - week1.getTime()) / 86400000) - - - 3 - + - (week1.getDay() + 6) % 7) - / - 7)); - } - /** - * @author neu3no, fenris - */ - function helper_englishWeekOfYear(date) { - let nr = helper_weekOfYear(date); - if (date.getDay() === 0) { - nr = nr - 1; - } - return nr; - } - /** - * @desc week of year - * @param {Date} date - * @return {int} - * @author fenris - */ - function get_week(date) { - let begin_of_year = new Date(date.getFullYear(), 0, 1, 12, 0, 0); - let day_of_week = begin_of_year.getDay(); - let overhang = (day_of_week >= 4); - let factor = (1000 * 60 * 60 * 24); - let days = ((date.getTime() - begin_of_year.getTime()) / factor); - let week = (Math.ceil((days + day_of_week) / 7) - (overhang ? 1 : 0)); - return week; - } - date_1.get_week = get_week; - /** - * @author neu3no, fenris - */ - function set_currentDate(date) { - _currentDate = date; - } - date_1.set_currentDate = set_currentDate; - /** - * @author neu3no, fenris - */ - function parse(format, date = _currentDate) { - let ret = format; - let re = new RegExp("%[a-z]", "gi"); - let match; - while (match = re.exec(format)) { - ret = ret.replace(match[0], parse_segment(match[0], date)); - } - return ret; - } - date_1.parse = parse; - /** - * @author neu3no, fenris - */ - function parse_segment(segment, date = _currentDate) { - if (!(segment in _segments)) { - let message = ("unknown format argument '" + segment + "'"); - throw (new Error(message)); - } - else { - return _segments[segment](date); - } - } - /** - * @author neu3no, fenris - */ - function locale_date(date = new Date(), ignore_error = false) { - if (!(date instanceof Date)) { - if (!ignore_error) { - throw new SyntaxError("date must be instance of Date"); - } - else { - console.warn("'" + date + "' seems not to be instance of Date; try to force convert."); - let tmp = date; - date = new Date(tmp); - if ((date.toString() === "Invalid Date") - || - (!(date < new Date(0)) && !(date > new Date(0)))) { - console.warn("conversion didn't work, returning default value"); - return "Ø"; - } - } - } - let conf = ( - /* - global_config.get_value("date") - || - */ - { - "use_locale_date": true, - "format_string": "%d.%m.%Y" + function clear(map) { + map.iterate(function (value, key) { + map["delete"](key); }); - if (conf.use_locale_date) { - return date.toLocaleDateString(); - } - else { - return strftime.parse(conf.format_string, date); - } } - date_1.locale_date = locale_date; + map_1.clear = clear; /** */ - function now() { - return Math.floor(Date.now() / 1000); + function keys(map) { + var keys = []; + map.iterate(function (value, key) { + keys.push(key); + }); + return keys; } - date_1.now = now; + map_1.keys = keys; /** */ - function from_components(components) { - return Math.floor(new Date(Date.parse(lib_string.coin("{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.{{milliseconds}}{{timezone_offset}}", { - "year": components.year.toFixed(0).padStart(4, "0"), - "month": components.month.toFixed(0).padStart(2, "0"), - "day": components.day.toFixed(0).padStart(2, "0"), - "hour": components.hour.toFixed(0).padStart(2, "0"), - "minute": components.minute.toFixed(0).padStart(2, "0"), - "second": components.second.toFixed(0).padStart(2, "0"), - "milliseconds": (0).toFixed(0).padStart(3, "0"), - "timezone_offset": lib_string.coin("{{sign}}{{amount}}:00", { - "sign": ((components.timezone_offset < 0) ? "-" : "+"), - "amount": Math.abs(components.timezone_offset).toFixed(0).padStart(2, "0"), - }), - }))).getTime() - / - 1000); + function values(map) { + var values = []; + map.iterate(function (value, key) { + values.push(value); + }); + return values; } - date_1.from_components = from_components; + map_1.values = values; /** */ - function to_components(unixtimestamp) { - const date_object = new Date(unixtimestamp * 1000); - const date_string = date_object.toISOString(); - return { - "timezone_offset": 0, - "year": parseInt(date_string.slice(0, 4)), - "month": parseInt(date_string.slice(5, 7)), - "day": parseInt(date_string.slice(8, 10)), - "hour": parseInt(date_string.slice(11, 13)), - "minute": parseInt(date_string.slice(14, 16)), - "second": parseInt(date_string.slice(17, 19)), - }; + function dump(map) { + var pairs = []; + map.iterate(function (value, key) { + pairs.push({ "key": key, "value": value }); + }); + return pairs; } - date_1.to_components = to_components; + map_1.dump = dump; /** */ - function get_timestamp_from_year_and_week_and_day(year, week, day) { - const d = (1 + ((week - 1) * 7)); - const date_raw = new Date(year, 0, d); - return (Math.round(date_raw.getTime() / 1000) - + - (60 * 60 * 24 * (day - date_raw.getDay() + 1))); - } - date_1.get_timestamp_from_year_and_week_and_day = get_timestamp_from_year_and_week_and_day; - })(date = lib_plankton.date || (lib_plankton.date = {})); -})(lib_plankton || (lib_plankton = {})); -var strftime = lib_plankton.date; -/* -This file is part of »bacterio-plankton:ical«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:ical« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:ical« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:ical«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var ical; - (function (ical) { - /** - */ - // type type_timestamp = string; - /** - */ - let enum_class; - (function (enum_class) { - enum_class["public"] = "public"; - enum_class["private"] = "private"; - enum_class["confidential"] = "confidential"; - })(enum_class = ical.enum_class || (ical.enum_class = {})); - ; - /** - */ - let enum_event_status; - (function (enum_event_status) { - enum_event_status["tentative"] = "tentative"; - enum_event_status["confirmed"] = "confirmed"; - enum_event_status["cancelled"] = "cancelled"; - })(enum_event_status = ical.enum_event_status || (ical.enum_event_status = {})); - ; - /** - */ - let enum_transp; - (function (enum_transp) { - enum_transp["opaque"] = "opaque"; - enum_transp["transparent"] = "transparent"; - })(enum_transp = ical.enum_transp || (ical.enum_transp = {})); - ; - })(ical = lib_plankton.ical || (lib_plankton.ical = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:ical«. - -Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' - - -»bacterio-plankton:ical« is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -»bacterio-plankton:ical« is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with »bacterio-plankton:ical«. If not, see . - */ -var lib_plankton; -(function (lib_plankton) { - var ical; - (function (ical) { - /** - */ - function date_decode(date_encoded) { - return { - "year": parseInt(date_encoded.slice(0, 4)), - "month": parseInt(date_encoded.slice(4, 6)), - "day": parseInt(date_encoded.slice(6, 8)), - }; - } - /** - */ - function time_decode(time_encoded) { - return { - "hour": parseInt(time_encoded.slice(0, 2)), - "minute": parseInt(time_encoded.slice(2, 4)), - "second": parseInt(time_encoded.slice(4, 6)), - "utc": ((time_encoded.length >= 7) && (time_encoded[6] === "Z")) - }; - } - /** - */ - function datetime_decode(datetime_encoded) { - const parts = datetime_encoded.split("T", 2); - return { - "date": date_decode(parts[0]), - "time": ((parts.length >= 2) ? time_decode(parts[1]) : null), - }; - } - /** - */ - let enum_decode_state_label; - (function (enum_decode_state_label) { - enum_decode_state_label["expect_vcalendar_begin"] = "expect_vcalendar_begin"; - enum_decode_state_label["expect_vcalendar_property"] = "expect_vcalendar_property"; - enum_decode_state_label["expect_vevent_property"] = "expect_vevent_property"; - enum_decode_state_label["done"] = "done"; - })(enum_decode_state_label || (enum_decode_state_label = {})); - ; - /** - */ - function class_encode(class_) { - switch (class_) { - case ical.enum_class.private: { - return "PRIVATE"; - break; - } - case ical.enum_class.public: { - return "PUBLIC"; - break; - } - case ical.enum_class.confidential: { - return "CONFIDENTIAL"; - break; - } - } - } - /** - */ - function class_decode(class_encoded) { - return { - "PRIVATE": ical.enum_class.private, - "PUBLIC": ical.enum_class.public, - "CONFIDENTIAL": ical.enum_class.confidential, - }[class_encoded]; - } - /** - */ - function event_status_encode(event_status) { - switch (event_status) { - case ical.enum_event_status.tentative: { - return "TENTATIVE"; - break; - } - case ical.enum_event_status.confirmed: { - return "CONFIRMED"; - break; - } - case ical.enum_event_status.cancelled: { - return "CANCELLED"; - break; - } - } - } - /** - */ - function event_status_decode(event_status_encoded) { - return { - "TENTATIVE": ical.enum_event_status.tentative, - "CONFIRMED": ical.enum_event_status.confirmed, - "CANCELLED": ical.enum_event_status.cancelled, - }[event_status_encoded]; - } - /** - */ - function transp_encode(transp) { - switch (transp) { - case ical.enum_transp.opaque: { - return "OPAQUE"; - break; - } - case ical.enum_transp.transparent: { - return "TRANSPARENT"; - break; - } - } - } - /** - */ - function transp_decode(transp_encoded) { - return { - "OPAQUE": ical.enum_transp.opaque, - "TRANSPARENT": ical.enum_transp.transparent, - }[transp_encoded]; - } - /** - */ - function datetime_to_unixtimestamp(datetime) { - if ((datetime.time !== null) && (!datetime.time.utc)) { - throw (new Error("can not convert not utc time values")); - } - else { - return lib_plankton.date.from_components({ - "timezone_offset": 0, - "year": datetime.date.year, - "month": datetime.date.month, - "day": datetime.date.day, - "hour": ((datetime.time === null) ? 0 : datetime.time.hour), - "minute": ((datetime.time === null) ? 0 : datetime.time.minute), - "second": ((datetime.time === null) ? 0 : datetime.time.second), - }); - } - } - ical.datetime_to_unixtimestamp = datetime_to_unixtimestamp; - /** - * @see https://www.rfc-editor.org/rfc/rfc5545 - * @see https://icalendar.org/iCalendar-RFC-5545/ - * @todo implement edge cases - */ - function ics_decode(ics, options = {}) { + function show(map, options) { + if (options === void 0) { options = {}; } options = Object.assign({ - "debug": false, + "show_key": instance_show, + "show_value": instance_show }, options); - // preprocessing - const lines = ics.split("\r\n"); - let content_lines = []; - let content_line_buffer = null; - lines.forEach(line => { - if (line.trim() === "") { - // do nothing + return ("[" + + + (dump(map) + .map(function (_a) { + var key = _a["key"], value = _a["value"]; + return (options.show_key(key) + + + " -> " + + + options.show_value(value)); + }) + .join(", ")) + + + "]"); + } + map_1.show = show; + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:map« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var simplemap; + (function (simplemap) { + /** + */ + function make(options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "data": {} + }, options); + return { + "data": options.data + }; + } + simplemap.make = make; + /** + */ + function size(subject) { + return Object.keys(subject.data).length; + } + simplemap.size = size; + /** + */ + function has(subject, key) { + return (key in subject.data); + } + simplemap.has = has; + /** + */ + function get_safe(subject, key) { + if (key in subject.data) { + return lib_plankton.pod.make_filled(subject.data[key]); } else { - const is_folding = ((line.length >= 2) - && - ((line[0] === " ") - || - (line[0] === "\t")) - /* - && - ! ( - (line[1] === " ") - || - (line[1] === "\t") - ) - */ - ); - if (is_folding) { - content_line_buffer += line.slice(1); + return lib_plankton.pod.make_empty(); + } + } + simplemap.get_safe = get_safe; + /** + */ + function get(subject, key, fallback) { + if (fallback === void 0) { fallback = lib_plankton.pod.make_empty(); } + if (key in subject.data) { + return subject.data[key]; + } + else { + if (!lib_plankton.pod.is_filled(fallback)) { + throw (new Error("key not found")); } else { - if (content_line_buffer === null) { - // do nothing - } - else { - content_lines.push(content_line_buffer); - } - content_line_buffer = line; + return lib_plankton.pod.cull(fallback); } } - }); - const instructions = content_lines.map((content_line) => { - const parts = content_line.split(":"); - const parts_left = parts[0].split(";"); + } + simplemap.get = get; + /** + */ + function set(subject, key, value) { + subject.data[key] = value; + } + simplemap.set = set; + /** + */ + function delete_(subject, key) { + delete subject.data[key]; + } + simplemap.delete_ = delete_; + /** + */ + function iterate(subject, procedure) { + Object.entries(subject.data).forEach(function (_a) { + var key = _a[0], value = _a[1]; + procedure(value, key); + }); + } + simplemap.iterate = iterate; + /** + */ + function implementation_map(subject) { return { - "command": parts_left[0], - "parameters": Object.fromEntries(parts_left.slice(1).map(x => x.split("=", 2))), - "value": (parts.slice(1).join(":") - .split(";") - .map(x => x.replace(new RegExp("\\\\,", "g"), ","))), + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (function_) { return iterate(subject, function_); } }; - }); - // core - let state = { - "label": enum_decode_state_label.expect_vcalendar_begin, - "vcalendar": null, - "vevent": null, - }; - instructions.forEach((instruction) => { - if (options.debug) { - console.info(JSON.stringify({ "instruction": instruction, "state": state }, undefined, "\t")); + } + simplemap.implementation_map = implementation_map; + })(simplemap = map.simplemap || (map.simplemap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:map« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var hashmap; + (function (hashmap) { + /** + */ + function make(hashing, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "pairs": [] + }, options); + var subject = { + "hashing": hashing, + "core": lib_plankton.map.simplemap.make({}) + }; + options.pairs.forEach(function (pair) { + set(subject, pair.key, pair.value); + }); + return subject; + } + hashmap.make = make; + /** + */ + function size(subject) { + return lib_plankton.map.simplemap.size(subject.core); + } + hashmap.size = size; + /** + */ + function has(subject, key) { + return lib_plankton.map.simplemap.has(subject.core, subject.hashing(key)); + } + hashmap.has = has; + /** + */ + function get(subject, key, fallback) { + if (fallback === void 0) { fallback = lib_plankton.pod.make_empty(); } + /* + we have to adjust the fallback argument, so that it can be used in our underlying simplemap core + therefore we pack the value together with any key as dummy + */ + return (lib_plankton.map.simplemap.get(subject.core, subject.hashing(key), lib_plankton.pod.propagate(fallback, function (value) { return ({ + "key": key, + "value": value + }); })) + .value); + } + hashmap.get = get; + /** + */ + function set(subject, key, value) { + var key_ = subject.hashing(key); + return (lib_plankton.map.simplemap.set(subject.core, key_, { "key": key, "value": value })); + } + hashmap.set = set; + /** + */ + function delete_(subject, key) { + return (lib_plankton.map.simplemap.delete_(subject.core, subject.hashing(key))); + } + hashmap.delete_ = delete_; + /** + */ + function iterate(subject, procedure) { + return (lib_plankton.map.simplemap.iterate(subject.core, function (_a, key_) { + var key = _a["key"], value = _a["value"]; + procedure(value, key); + })); + } + hashmap.iterate = iterate; + /** + */ + function implementation_map(subject) { + return { + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (procedure) { return iterate(subject, procedure); } + }; + } + hashmap.implementation_map = implementation_map; + })(hashmap = map.hashmap || (map.hashmap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:map«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:map« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:map« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +3GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:map«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var map; + (function (map) { + var collatemap; + (function (collatemap) { + /** + */ + function make(collation, options) { + if (options === void 0) { options = {}; } + options = Object.assign({ + "pairs": [] + }, options); + var subject = { + "collation": collation, + "pairs": [] + }; + options.pairs.forEach(function (pair) { + set(subject, pair.key, pair.value); + }); + return subject; + } + collatemap.make = make; + /** + */ + function size(subject) { + return subject.pairs.length; + } + collatemap.size = size; + /** + */ + function has(subject, key) { + return (subject.pairs.some(function (pair) { return subject.collation(key, pair.key); })); + } + collatemap.has = has; + /** + * @todo use .find + */ + function get(subject, key, fallback) { + var value; + var found = (subject.pairs + .some(function (pair) { + if (subject.collation(key, pair.key)) { + value = pair.value; + return true; + } + else { + return false; + } + })); + if (found) { + return value; } - switch (state.label) { - default: { - throw (new Error("unhandled state label: " + state.label)); - break; + else { + if (!lib_plankton.pod.is_filled(fallback)) { + throw (new Error("key not found")); } - case enum_decode_state_label.expect_vcalendar_begin: { - switch (instruction.command) { - default: { - throw (new Error("unexpected instruction key: " + instruction.command)); - break; - } - case "BEGIN": { - switch (instruction.value[0]) { - default: { - throw (new Error("unexpected instruction value: " + instruction.value[0])); - break; - } - case "VCALENDAR": { - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": { - "version": "", - "prodid": "", - "vevents": [], - }, - "vevent": null, - }; - break; - } - } - break; - } - } - break; - } - case enum_decode_state_label.expect_vcalendar_property: { - switch (instruction.command) { - case "VERSION": { - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["version", instruction.value[0]]])), - "vevent": state.vevent, - }; - break; - } - case "PRODID": { - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["prodid", instruction.value[0]]])), - "vevent": state.vevent, - }; - break; - } - case "METHOD": { - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": Object.assign(state.vcalendar, Object.fromEntries([["method", instruction.value[0]]])), - "vevent": state.vevent, - }; - break; - } - case "BEGIN": { - const object = instruction.value[0]; - switch (object) { - default: { - throw (new Error("unhandled object: " + object)); - break; - } - case "VCALENDAR": { - throw (new Error("unexpected object: " + object)); - break; - } - case "VEVENT": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": { - "uid": "", - "dtstamp": { - "date": { "year": 2000, "month": 0, "day": 0 }, - "time": { "hour": 0, "minute": 0, "second": 0, "utc": true }, - }, - }, - }; - break; - } - } - break; - } - case "END": { - const object = instruction.value[0]; - switch (object) { - default: { - throw (new Error("unhandled object: " + object)); - break; - } - case "VCALENDAR": { - state = { - "label": enum_decode_state_label.done, - "vcalendar": state.vcalendar, - "vevent": state.vevent, - }; - break; - } - } - break; - } - default: { - if (instruction.command.startsWith("X-")) { - const key = instruction.command.slice(2).toLowerCase(); - const value = instruction.value.join(";"); - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": Object.assign(state.vcalendar, { - "x_props": Object.assign((state.vcalendar.x_props ?? {}), Object.fromEntries([[key, value]])) - }), - "vevent": state.vevent, - }; - } - else { - console.info({ "instruction": instruction, "state": state }); - throw (new Error("unhandled instruction key: " + instruction.command)); - } - break; - } - } - break; - } - case enum_decode_state_label.expect_vevent_property: { - switch (instruction.command) { - case "UID": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["uid", instruction.value[0]]])), - }; - break; - } - case "DTSTART": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([ - [ - "dtstart", - { - "tzid": instruction.parameters["tzid"], - "value": datetime_decode(instruction.value[0]), - } - ] - ])), - }; - break; - } - case "DTEND": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([ - [ - "dtend", - { - "tzid": instruction.parameters["tzid"], - "value": datetime_decode(instruction.value[0]), - } - ] - ])), - }; - break; - } - case "DTSTAMP": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([ - [ - "dtstamp", - datetime_decode(instruction.value[0]) - ] - ])), - }; - break; - } - case "SEQUENCE": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["sequence", parseInt(instruction.value[0])]])), - }; - break; - } - case "TRANSP": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["transp", transp_decode(instruction.value[0])]])), - }; - break; - } - case "SUMMARY": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["summary", instruction.value[0]]])), - }; - break; - } - case "CLASS": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["class", class_decode(instruction.value[0])]])), - }; - break; - } - case "STATUS": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["status", event_status_decode(instruction.value[0])]])), - }; - break; - } - case "DESCRIPTION": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["description", instruction.value[0]]])), - }; - break; - } - case "CATEGORIES": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["categories", instruction.value[0].split(",")]])), - }; - break; - } - case "CREATED": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([ - [ - "created", - { - "value": datetime_decode(instruction.value[0]), - } - ] - ])), - }; - break; - } - case "LOCATION": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["location", instruction.value[0]]])), - }; - break; - } - case "URL": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["url", instruction.value[0]]])), - }; - break; - } - case "LAST-MODIFIED": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([ - [ - "last_modified", - { - "value": datetime_decode(instruction.value[0]), - } - ] - ])), - }; - break; - } - case "ATTENDEE": { - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, Object.fromEntries([["attendee", instruction.value[0]]])), - }; - break; - } - case "BEGIN": { - const object = instruction.value[0]; - switch (object) { - default: { - throw (new Error("unhandled object: " + object)); - break; - } - case "VCALENDAR": { - throw (new Error("unexpected object: " + object)); - break; - } - case "VEVENT": { - throw (new Error("unexpected object: " + object)); - break; - } - } - break; - } - case "END": { - const object = instruction.value[0]; - switch (object) { - default: { - throw (new Error("unhandled value: " + object)); - break; - } - case "VEVENT": { - state = { - "label": enum_decode_state_label.expect_vcalendar_property, - "vcalendar": Object.assign(state.vcalendar, { - "vevents": state.vcalendar.vevents.concat([state.vevent]), - }), - "vevent": null, - }; - break; - } - } - break; - } - default: { - if (instruction.command.startsWith("X-")) { - const key = instruction.command.slice(2).toLowerCase(); - const value = instruction.value.join(";"); - state = { - "label": enum_decode_state_label.expect_vevent_property, - "vcalendar": state.vcalendar, - "vevent": Object.assign(state.vevent, { - "x_props": Object.assign((state.vevent.x_props ?? {}), Object.fromEntries([[key, value]])) - }), - }; - } - else { - console.info({ "instruction": instruction, "state": state }); - throw (new Error("unhandled instruction key: " + instruction.command)); - } - break; - } - } - break; - } - case enum_decode_state_label.done: { - console.info({ "instruction": instruction, "state": state }); - throw (new Error("end expected")); - break; + else { + return lib_plankton.pod.cull(fallback); } } - }); - return state.vcalendar; - } - ical.ics_decode = ics_decode; - /** - * @see https://www.rfc-editor.org/rfc/rfc5545 - * @see https://icalendar.org/iCalendar-RFC-5545/ - */ - function date_encode(date) { - return lib_plankton.string.coin("{{year}}{{month}}{{day}}", { - "year": date.year.toFixed(0).padStart(4, "0"), - "month": date.month.toFixed(0).padStart(2, "0"), - "day": date.day.toFixed(0).padStart(2, "0"), - }); - } - /** - */ - function time_encode(time) { - return lib_plankton.string.coin("{{hour}}{{minute}}{{second}}{{utc}}", { - "hour": time.hour.toFixed(0).padStart(2, "0"), - "minute": time.minute.toFixed(0).padStart(2, "0"), - "second": time.second.toFixed(0).padStart(2, "0"), - "utc": (time.utc ? "Z" : ""), - }); - } - /** - */ - function datetime_encode(datetime) { - return lib_plankton.string.coin("{{date}}T{{time}}", { - "date": date_encode(datetime.date), - "time": time_encode(datetime.time), - }); - } - /** - * @todo method - * @todo add missing fields - */ - function ics_encode(vcalendar) { - let content_lines = []; - content_lines.push("BEGIN:VCALENDAR"); - content_lines.push(lib_plankton.string.coin("VERSION:{{version}}", { "version": vcalendar.version })); - content_lines.push(lib_plankton.string.coin("PRODID:{{prodid}}", { "prodid": vcalendar.prodid })); - content_lines.push(lib_plankton.string.coin("METHOD:{{method}}", { "method": vcalendar.method })); - vcalendar.vevents.forEach((vevent) => { - content_lines.push("BEGIN:VEVENT"); - { - // uid - content_lines.push(lib_plankton.string.coin("UID:{{uid}}", { - "uid": vevent.uid, - })); - // dtstart - content_lines.push(lib_plankton.string.coin( - // "DTSTART;TZID={{tzid}}:{{value}}", - "DTSTART:{{value}}", { - "tzid": vevent.dtstart.tzid, - "value": datetime_encode(vevent.dtstart.value), - })); - // dtend - if (vevent.dtend !== undefined) { - content_lines.push(lib_plankton.string.coin( - // "DTEND;TZID={{tzid}}:{{value}}", - "DTEND:{{value}}", { - "tzid": vevent.dtend.tzid, - "value": datetime_encode(vevent.dtend.value), - })); + } + collatemap.get = get; + /** + */ + function set(subject, key, value) { + var found = (subject.pairs + .some(function (pair) { + if (subject.collation(key, pair.key)) { + // pair.value = value; + return true; } - // dtstamp - content_lines.push(lib_plankton.string.coin("DTSTAMP:{{value}}", { - "value": datetime_encode(vevent.dtstamp), - })); - // class - if (vevent.class !== undefined) { - content_lines.push(lib_plankton.string.coin("CLASS:{{class}}", { - "class": vevent.class, - })); - } - // summary - content_lines.push(lib_plankton.string.coin("SUMMARY:{{summary}}", { - "summary": vevent.summary, - })); - // description - if (vevent.description !== undefined) { - content_lines.push(lib_plankton.string.coin("DESCRIPTION:{{description}}", { - "description": vevent.description, - })); - } - // location - if (vevent.location !== undefined) { - content_lines.push(lib_plankton.string.coin("LOCATION:{{location}}", { - "location": vevent.location, - })); - } - // geo - if (vevent.geo !== undefined) { - content_lines.push(lib_plankton.string.coin("GEO:{{geo_latitude}};{{geo_longitude}}", { - "geo_latitude": vevent.geo.latitude.toFixed(4), - "geo_longitude": vevent.geo.longitude.toFixed(4), - })); - } - // url - if (vevent.url !== undefined) { - content_lines.push(lib_plankton.string.coin("URL:{{url}}", { - "url": vevent.url, - })); + else { + return false; } + })); + if (found) { + // nothing } - content_lines.push("END:VEVENT"); - }); - content_lines.push("END:VCALENDAR"); - let lines = []; - content_lines.forEach((content_line) => { - const slices = lib_plankton.string.slice(content_line, 75 - 1); - lines.push(slices[0]); - slices.slice(1).forEach((slice) => { lines.push(" " + slice); }); - }); - return lines.join("\r\n"); - } - ical.ics_encode = ics_encode; - })(ical = lib_plankton.ical || (lib_plankton.ical = {})); + else { + subject.pairs.push({ + "key": key, + "value": value + }); + } + } + collatemap.set = set; + /** + */ + function delete_(subject, key) { + var index; + var found = (subject.pairs + .some(function (pair, index_) { + if (subject.collation(key, pair.key)) { + index = index_; + return true; + } + else { + return false; + } + })); + if (found) { + subject.pairs.splice(index, 1); + } + else { + // do nothing + } + } + collatemap.delete_ = delete_; + /** + */ + function iterate(subject, function_) { + subject.pairs + .forEach(function (pair) { + function_(pair.value, pair.key); + }); + } + collatemap.iterate = iterate; + /** + */ + function implementation_map(subject) { + return { + "size": function () { return size(subject); }, + "has": function (key) { return has(subject, key); }, + "get": function (key, fallback) { return get(subject, key, fallback); }, + "set": function (key, value) { return set(subject, key, value); }, + "delete": function (key) { return delete_(subject, key); }, + "iterate": function (function_) { return iterate(subject, function_); } + }; + } + collatemap.implementation_map = implementation_map; + })(collatemap = map.collatemap || (map.collatemap = {})); + })(map = lib_plankton.map || (lib_plankton.map = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:http«. @@ -10936,3 +7286,1511 @@ var lib_plankton; url.class_url = class_url; })(url = lib_plankton.url || (lib_plankton.url = {})); })(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:www_form«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:www_form« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:www_form«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var www_form; + (function (www_form) { + /** + * @author fenris + */ + function encode(source) { + return (Object.entries(source) + .map(function (_a) { + var key = _a[0], value = _a[1]; + return (key + "=" + encodeURIComponent(value)); + }) + .join("&")); + } + www_form.encode = encode; + /** + * @author fenris + */ + function decode(target) { + return (Object.fromEntries(target.split("&") + .map(function (part) { + var components = part.split("="); + var key = components[0]; + var value = decodeURIComponent(components.slice(1).join("=")); + return [key, value]; + }))); + } + www_form.decode = decode; + })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {})); +})(lib_plankton || (lib_plankton = {})); +/* +This file is part of »bacterio-plankton:www_form«. + +Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:www_form« is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +»bacterio-plankton:www_form« is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with »bacterio-plankton:www_form«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var www_form; + (function (www_form) { + /** + * @author fenris + */ + var class_www_form = /** @class */ (function () { + /** + * @author fenris + */ + function class_www_form() { + } + /** + * @implementation + * @author fenris + */ + class_www_form.prototype.encode = function (source) { + return www_form.encode(source); + }; + /** + * @implementation + * @author fenris + */ + class_www_form.prototype.decode = function (target) { + return www_form.decode(target); + }; + return class_www_form; + }()); + www_form.class_www_form = class_www_form; + })(www_form = lib_plankton.www_form || (lib_plankton.www_form = {})); +})(lib_plankton || (lib_plankton = {})); diff --git a/source/index.html b/source/index.html index 185ef1a..85765d3 100644 --- a/source/index.html +++ b/source/index.html @@ -9,7 +9,7 @@ document.addEventListener( "DOMContentLoaded", () => { - _zeitbild.frontend.main() + _zeitbild.frontend_web.main() .then( () => {} ) diff --git a/source/logic/backend.ts b/source/logic/backend.ts index ccb2f05..25be5f5 100644 --- a/source/logic/backend.ts +++ b/source/logic/backend.ts @@ -1,106 +1,122 @@ /** */ -namespace _zeitbild.frontend.resources.backend +namespace _zeitbild.frontend_web.backend { /** */ - var _data : _zeitbild.frontend.type_datamodel; + var _session_key : (null | string) = null; /** */ - export async function init( + async function call( + method : lib_plankton.http.enum_method, + action : string, + input : (null | any) + ) : Promise + { + const with_body : boolean = ( + [ + lib_plankton.http.enum_method.post, + lib_plankton.http.enum_method.put, + lib_plankton.http.enum_method.patch, + ].includes(method) + ); + const http_request : lib_plankton.http.type_request = { + "version": "HTTP/2", + "scheme": ( + (_zeitbild.frontend_web.conf.get()["backend"]["scheme"] === "http") + ? + "http" + : + "https" + ), + "host": lib_plankton.string.coin( + "{{host}}:{{port}}", + { + "host": _zeitbild.frontend_web.conf.get()["backend"]["host"], + "port": _zeitbild.frontend_web.conf.get()["backend"]["port"].toFixed(0), + } + ), + "path": lib_plankton.string.coin( + "{{base}}{{action}}", + { + "base": _zeitbild.frontend_web.conf.get()["backend"]["path"], + "action": action, + } + ), + "method": method, + "query": ( + (with_body || (input === null)) + ? + null + : + ("?" + lib_plankton.www_form.encode(input)) + ), + "headers": Object.assign( + {}, + ( + (! with_body) + ? + {} + : + {"Content-Type": "application/json"} + ), + ( + (_session_key === null) + ? + {} + : + {"X-Session-Key": _session_key} + ) + ), + "body": ( + ((! with_body) || (input === null)) + ? + null + : + /*Buffer.from*/(lib_plankton.json.encode(input)) + ), + }; + const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(http_request); + const output : any = lib_plankton.json.decode(http_response.body.toString()); + return Promise.resolve(output); + } + + + /** + */ + export async function session_begin( + name : string, + password : string ) : Promise { - const path : string = "data.json"; - if (_data === undefined) { - _data = lib_plankton.call.convey( - await lib_plankton.file.read(path), - [ - lib_plankton.json.decode, - (data_raw : any) => ( - ({ - "users": data_raw["users"], - "calendars": ( - data_raw["calendars"] - .map( - (calendar_entry_raw : any) => ({ - "id": calendar_entry_raw["id"], - "object": ( - ((calendar_object_raw) => { - switch (calendar_object_raw["kind"]) { - default: { - return calendar_object_raw; - break; - } - case "concrete": { - return { - "kind": "concrete", - "data": { - "name": calendar_object_raw["data"]["name"], - "private": ( - calendar_object_raw["data"]["private"] - ?? - false - ), - "users": calendar_object_raw["data"]["users"], - "events": ( - calendar_object_raw["data"]["events"] - .map( - (event_raw : any) => ({ - "name": event_raw["name"], - "begin": event_raw["begin"], - "end": ( - ( - ( - event_raw["end"] - ?? - null - ) - === - null - ) - ? - null - : - event_raw["end"] - ), - "location": ( - event_raw["location"] - ?? - null - ), - "description": ( - event_raw["description"] - ?? - null - ), - }) - ) - ), - }, - }; - break; - } - } - }) (calendar_entry_raw["object"]) - ), - }) - ) - ), - }) as type_datamodel - ), - ] - ); - } - else { - // do nothing - } + _session_key = await call( + lib_plankton.http.enum_method.post, + "/session/begin", + { + "name": name, + "password": password, + } + ); return Promise.resolve(undefined); } + /** + */ + export async function session_end( + ) : Promise + { + return call( + lib_plankton.http.enum_method.delete, + "/session/end", + null + ); + } + + /** */ export async function calendar_list( @@ -115,65 +131,23 @@ namespace _zeitbild.frontend.resources.backend > > { - await init(); - return Promise.resolve( - _data.calendars - .map( - (calendar_entry) => { - switch (calendar_entry.object.kind) { - case "concrete": { - return { - "key": calendar_entry.id, - "preview": { - "name": calendar_entry.object.data.name, - } - }; - break; - } - case "caldav": { - return { - "key": calendar_entry.id, - "preview": { - "name": "(imported)", - } - }; - } - } - } - ) + return call( + lib_plankton.http.enum_method.get, + "/calendars", + null ); } - /** - */ - export async function calendar_read( - calendar_id : type_calendar_id - ) : Promise - { - await init(); - const hits = ( - _data.calendars - .filter( - (calendar_entry) => (calendar_entry.id === calendar_id) - ) - ); - if (hits.length <= 0) { - return Promise.reject(new Error("not found")); - } - else { - return Promise.resolve(hits[0].object); - } - } - - /** * @todo prevent loops */ - export async function calendar_gather_events( - calendar_ids : Array, - from_pit : _zeitbild.frontend.helpers.type_pit, - to_pit : _zeitbild.frontend.helpers.type_pit + export async function events( + from_pit : _zeitbild.frontend_web.helpers.type_pit, + to_pit : _zeitbild.frontend_web.helpers.type_pit, + options : { + calendar_ids ?: (null | Array); + } = {} ) : Promise< Array< { @@ -184,150 +158,30 @@ namespace _zeitbild.frontend.resources.backend > > { - lib_plankton.log.info( - "calendar_gather_events", + options = Object.assign( { - "calendar_ids": calendar_ids, - } + "calendar_ids": null, + }, + options + ); + + return call( + lib_plankton.http.enum_method.get, + "/events", + Object.assign( + { + "from": from_pit, + "to": to_pit, + }, + ( + (options.calendar_ids === null) + ? + {} + : + {"calendar_ids": options.calendar_ids.join(",")} + ) + ) ); - await init(); - let result : Array< - { - calendar_id : type_calendar_id; - calendar_name : string; - event : type_event; - } - > = []; - for await (const calendar_id of calendar_ids) { - const calendar_object : type_calendar_object = await calendar_read( - calendar_id - ); - if (calendar_object.data.private) { - lib_plankton.log.info( - "calendar_gather_events_private_calendar_blocked", - { - "calendar_id": calendar_id, - } - ); - } - else { - switch (calendar_object.kind) { - case "concrete": { - result = ( - result - .concat( - calendar_object.data.events - .filter( - (event) => _zeitbild.frontend.helpers.pit_is_between( - _zeitbild.frontend.helpers.pit_from_datetime(event.begin), - from_pit, - to_pit - ) - ) - .map( - (event) => ({ - "calendar_id": calendar_id, - "calendar_name": calendar_object.data.name, - "event": event - }) - ) - ) - ); - break; - } - case "caldav": { - const url : lib_plankton.url.type_url = lib_plankton.url.decode( - calendar_object.data.source_url - ); - const http_request : lib_plankton.http.type_request = { - "version": "HTTP/2", - "scheme": ((url.scheme === "https") ? "https" : "http"), - "host": url.host, - "path": (url.path ?? "/"), - "query": url.query, - "method": lib_plankton.http.enum_method.get, - "headers": {}, - "body": null, - }; - // TODO: cache? - const http_response : lib_plankton.http.type_response = await lib_plankton.http.call( - http_request, - { - } - ); - const vcalendar : lib_plankton.ical.type_vcalendar = lib_plankton.ical.ics_decode( - http_response.body.toString(), - { - } - ); - result = ( - result - .concat( - vcalendar.vevents - .map( - (vevent : lib_plankton.ical.type_vevent) => ( - (vevent.dtstart !== undefined) - ? - { - "name": ( - (vevent.summary !== undefined) - ? - vevent.summary - : - "???" - ), - "begin": _zeitbild.frontend.helpers.ical_dt_to_own_datetime(vevent.dtstart), - "end": ( - (vevent.dtend !== undefined) - ? - _zeitbild.frontend.helpers.ical_dt_to_own_datetime(vevent.dtend) - : - null - ), - "location": ( - (vevent.location !== undefined) - ? - vevent.location - : - null - ), - "description": ( - (vevent.description !== undefined) - ? - vevent.description - : - null - ), - } - : - null - ) - ) - .filter( - (event) => (event !== null) - ) - .filter( - (event) => _zeitbild.frontend.helpers.pit_is_between( - _zeitbild.frontend.helpers.pit_from_datetime(event.begin), - from_pit, - to_pit - ) - ) - .map( - (event) => ({ - "calendar_id": calendar_id, - "calendar_name": calendar_object.data.name, - "event": event, - }) - ) - ) - ); - break; - } - } - } - } - return Promise.resolve(result); } } diff --git a/source/logic/conf.ts b/source/logic/conf.ts new file mode 100644 index 0000000..c2b89ac --- /dev/null +++ b/source/logic/conf.ts @@ -0,0 +1,95 @@ + +namespace _zeitbild.frontend_web.conf +{ + + /** + */ + const _schema : lib_plankton.conf.type_schema = { + "nullable": false, + "type": "object", + "properties": { + "version": { + "nullable": false, + "type": "integer", + "enum": [1] + }, + "backend": { + "nullable": false, + "type": "object", + "properties": { + "scheme": { + "nullable": false, + "type": "string", + "default": "http" + }, + "host": { + "nullable": false, + "type": "string", + "default": "localhost" + }, + "port": { + "nullable": false, + "type": "integer", + "default": 7845 + }, + "path": { + "nullable": false, + "type": "string", + "default": "" + } + }, + "required": [ + ], + "additionalProperties": false, + "default": {} + } + }, + "required": [ + "version", + ], + "additionalProperties": false + }; + + + /** + */ + var _data : (null | any) = null; + + + /** + */ + export function schema( + ) : lib_plankton.conf.type_schema + { + return _schema; + } + + + /** + */ + export function get( + ) : any + { + if (_data === null) { + throw (new Error("conf not loaded yet")); + } + else { + return _data; + } + } + + + /** + */ + export async function init( + path : string + ) : Promise + { + _data = await lib_plankton.conf.load( + _schema, + path + ); + return Promise.resolve(undefined); + } + +} diff --git a/source/logic/helpers.ts b/source/logic/helpers.ts index e3ebf88..8c92314 100644 --- a/source/logic/helpers.ts +++ b/source/logic/helpers.ts @@ -1,7 +1,7 @@ /** */ -namespace _zeitbild.frontend.helpers +namespace _zeitbild.frontend_web.helpers { /** @@ -532,59 +532,5 @@ namespace _zeitbild.frontend.helpers ] ); } - - - /** - * @todo timezone - */ - function ical_datetime_to_own_datetime( - ical_datetime : lib_plankton.ical.type_datetime - ) : type_datetime - { - return { - "timezone_shift": 0, - "date": { - "year": ical_datetime.date.year, - "month": ical_datetime.date.month, - "day": ical_datetime.date.day, - }, - "time": ( - (ical_datetime.time === null) - ? - null - : - { - "hour": ical_datetime.time.hour, - "minute": ical_datetime.time.minute, - "second": ical_datetime.time.second, - } - ) - }; - } - - - /** - * @todo timezone - */ - export function ical_dt_to_own_datetime( - ical_dt: lib_plankton.ical.type_dt - ) : type_datetime - { - return { - "timezone_shift": 0, - "date": ical_dt.value.date, - "time": ( - (ical_dt.value.time === null) - ? - null - : - { - "hour": ical_dt.value.time.hour, - "minute": ical_dt.value.time.minute, - "second": ical_dt.value.time.second, - } - ) - }; - } } diff --git a/source/logic/main.ts b/source/logic/main.ts index 4a123f4..a3568b7 100644 --- a/source/logic/main.ts +++ b/source/logic/main.ts @@ -1,6 +1,7 @@ + /** */ -namespace _zeitbild.frontend +namespace _zeitbild.frontend_web { /** @@ -15,30 +16,28 @@ namespace _zeitbild.frontend /** */ async function render( - conf : type_conf, - calendar_ids : Array ) : Promise { - calendar_ids.sort(); const target : HTMLElement = (document.querySelector("body") as HTMLBodyElement); - switch (conf.view_mode) { + const view_type : string = "table"; + switch (view_type) { default: { throw (new Error("invalid view mode")); break; } case "table": { - const content : string = await _zeitbild.frontend.view.calendar_view_table_html( - calendar_ids, + const content : string = await _zeitbild.frontend_web.view.calendar_view_table_html( { + "calendar_ids": null, "from": { "year": 2024, - "week": 35 + "week": 37 }, "to": { "year": 2024, "week": 43 }, - "timezone_shift": conf.timezone_shift, + "timezone_shift": /*conf.timezone_shift*/0, } ); target.innerHTML = content; @@ -74,10 +73,10 @@ namespace _zeitbild.frontend break; } case "list": { - const content : string = await _zeitbild.frontend.view.calendar_view_list_html( - calendar_ids, + const content : string = await _zeitbild.frontend_web.view.calendar_view_list_html( + null, { - "timezone_shift": conf.timezone_shift, + "timezone_shift": /*conf.timezone_shift*/0, } ); target.innerHTML = content; @@ -101,10 +100,16 @@ namespace _zeitbild.frontend ); // conf - const conf : type_conf = lib_plankton.json.decode(await lib_plankton.file.read("conf.json")); + await _zeitbild.frontend_web.conf.init(("conf.json")); + + // setup + await _zeitbild.frontend_web.backend.session_begin( + "alice", + "alice" + ); // args - + /* const url : URL = new URL(window.location.toString()); const calendar_ids : Array = ( (url.searchParams.get("ids") !== null) @@ -117,14 +122,12 @@ namespace _zeitbild.frontend ] ) : - (await _zeitbild.frontend.resources.backend.calendar_list()).map(x => x.key) + (await _zeitbild.frontend_web.backend.calendar_list()).map(x => x.key) ); + */ // exec - await render( - conf, - calendar_ids - ); + await render(); return Promise.resolve(undefined); } diff --git a/source/logic/types.ts b/source/logic/types.ts index 4baa03b..527ec67 100644 --- a/source/logic/types.ts +++ b/source/logic/types.ts @@ -1,7 +1,7 @@ /** */ -namespace _zeitbild.frontend +namespace _zeitbild.frontend_web { /** @@ -29,11 +29,11 @@ namespace _zeitbild.frontend */ export type type_event = { name : string; - begin : _zeitbild.frontend.helpers.type_datetime; + begin : _zeitbild.frontend_web.helpers.type_datetime; end : ( null | - _zeitbild.frontend.helpers.type_datetime + _zeitbild.frontend_web.helpers.type_datetime ); location : ( null diff --git a/source/logic/view.ts b/source/logic/view.ts index 48db65c..f6200a7 100644 --- a/source/logic/view.ts +++ b/source/logic/view.ts @@ -1,7 +1,7 @@ /** */ -namespace _zeitbild.frontend.view +namespace _zeitbild.frontend_web.view { /** @@ -134,21 +134,23 @@ namespace _zeitbild.frontend.view * @todo kein "while" */ async function calendar_view_table_data( - calendar_ids : Array, - options : { - from ?: { - year : int; - week : int; - }, - to ?: { - year : int; - week : int; - }, - timezone_shift ?: int; - } = {} + calendar_ids : ( + null + | + Array + ), + from : { + year : int; + week : int; + }, + to : { + year : int; + week : int; + }, + timezone_shift : int, ) : Promise< { - sources : lib_plankton.structures.type_hashmap< + sources : lib_plankton.map.type_map< type_calendar_id, { name : string; @@ -159,7 +161,7 @@ namespace _zeitbild.frontend.view week : int; data : Array< { - pit : _zeitbild.frontend.helpers.type_pit; + pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; @@ -174,53 +176,25 @@ namespace _zeitbild.frontend.view } > { - const now_pit : _zeitbild.frontend.helpers.type_pit = _zeitbild.frontend.helpers.pit_now(); - options = Object.assign( - { - "from": lib_plankton.call.convey( - now_pit, - [ - (x : _zeitbild.frontend.helpers.type_pit) => _zeitbild.frontend.helpers.pit_shift_week(x, -1), - _zeitbild.frontend.helpers.pit_to_date_object, - (x : Date) => ({ - "year": x.getFullYear(), - "week": _zeitbild.frontend.helpers.date_object_get_week_of_year(x), - }) - ] - ), - "to": lib_plankton.call.convey( - now_pit, - [ - (x : _zeitbild.frontend.helpers.type_pit) => _zeitbild.frontend.helpers.pit_shift_week(x, +4), - _zeitbild.frontend.helpers.pit_to_date_object, - (x : Date) => ({ - "year": x.getFullYear(), - "week": _zeitbild.frontend.helpers.date_object_get_week_of_year(x), - }) - ] - ), - "timezone_shift": 0, - }, - options - ); + const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); /* const calendar_object : type_calendar_object = calendar_read( data, calendar_id ); */ - const from_pit : _zeitbild.frontend.helpers.type_pit = _zeitbild.frontend.helpers.pit_from_year_and_week( - (options.from as {year : int; week : int}).year, - (options.from as {year : int; week : int}).week, + const from_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week( + (from as {year : int; week : int}).year, + (from as {year : int; week : int}).week, { - "timezone_shift": (options.timezone_shift as int), + "timezone_shift": (timezone_shift as int), } ); - const to_pit : _zeitbild.frontend.helpers.type_pit = _zeitbild.frontend.helpers.pit_from_year_and_week( - (options.to as {year : int; week : int}).year, - (options.to as {year : int; week : int}).week, + const to_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week( + (to as {year : int; week : int}).year, + (to as {year : int; week : int}).week, { - "timezone_shift": (options.timezone_shift as int), + "timezone_shift": (timezone_shift as int), } ); @@ -231,13 +205,15 @@ namespace _zeitbild.frontend.view calendar_name : string; event : type_event; } - > = await _zeitbild.frontend.resources.backend.calendar_gather_events( - calendar_ids, + > = await _zeitbild.frontend_web.backend.events( from_pit, - to_pit + to_pit, + { + "calendar_ids": calendar_ids, + } ); let result : { - sources : lib_plankton.structures.type_hashmap< + sources : lib_plankton.map.type_map< type_calendar_id, { name : string; @@ -248,7 +224,7 @@ namespace _zeitbild.frontend.view week : int; data : Array< { - pit : _zeitbild.frontend.helpers.type_pit; + pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; @@ -261,27 +237,31 @@ namespace _zeitbild.frontend.view } >; } = { - "sources": lib_plankton.structures.hashmap_construct( - x => x.toFixed(0), - ( - entries - .map( - (entry) => ( - { - "key": entry.calendar_id, - "value": { - "name": entry.calendar_name, - } - } + "sources": lib_plankton.map.hashmap.implementation_map( + lib_plankton.map.hashmap.make( + x => x.toFixed(0), + { + "pairs": ( + entries + .map( + (entry) => ( + { + "key": entry.calendar_id, + "value": { + "name": entry.calendar_name, + } + } + ) + ) ) - ) + } ) ), "rows": [], }; let row : Array< { - pit : _zeitbild.frontend.helpers.type_pit; + pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; @@ -293,12 +273,12 @@ namespace _zeitbild.frontend.view > = []; let day : int = 0; while (true) { - const pit_current : _zeitbild.frontend.helpers.type_pit = _zeitbild.frontend.helpers.pit_shift_day( + const pit_current : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_shift_day( from_pit, day ); if ( - _zeitbild.frontend.helpers.pit_is_before( + _zeitbild.frontend_web.helpers.pit_is_before( pit_current, to_pit ) @@ -315,7 +295,7 @@ namespace _zeitbild.frontend.view result.rows.push( { "week": ( - (options.from as {year : int; week : int}).week + (from as {year : int; week : int}).week + Math.floor(day / 7) - @@ -343,7 +323,7 @@ namespace _zeitbild.frontend.view .forEach( (entry) => { const distance_seconds : int = ( - _zeitbild.frontend.helpers.pit_from_datetime(entry.event.begin) + _zeitbild.frontend_web.helpers.pit_from_datetime(entry.event.begin) - from_pit ); @@ -389,8 +369,12 @@ namespace _zeitbild.frontend.view /** */ export async function calendar_view_table_html( - calendar_ids : Array, options : { + calendar_ids ?: ( + null + | + Array + ); from ?: { year : int; week : int; @@ -403,8 +387,38 @@ namespace _zeitbild.frontend.view } = {} ) : Promise { + const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); + options = Object.assign( + { + "calendar_ids": null, + "from": lib_plankton.call.convey( + now_pit, + [ + (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, -1), + _zeitbild.frontend_web.helpers.pit_to_date_object, + (x : Date) => ({ + "year": x.getFullYear(), + "week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x), + }) + ] + ), + "to": lib_plankton.call.convey( + now_pit, + [ + (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4), + _zeitbild.frontend_web.helpers.pit_to_date_object, + (x : Date) => ({ + "year": x.getFullYear(), + "week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x), + }) + ] + ), + "timezone_shift": 0, + }, + options + ); const stuff : { - sources : lib_plankton.structures.type_hashmap< + sources : lib_plankton.map.type_map< type_calendar_id, { name : string; @@ -415,7 +429,7 @@ namespace _zeitbild.frontend.view week : int; data : Array< { - pit : _zeitbild.frontend.helpers.type_pit; + pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; @@ -428,44 +442,52 @@ namespace _zeitbild.frontend.view } >; } = await calendar_view_table_data( - calendar_ids, - options + options.calendar_ids, + options.from, + options.to, + options.timezone_shift ); - const sources : lib_plankton.structures.type_hashmap< + const sources : lib_plankton.map.type_map< type_calendar_id, { name : string; color : lib_plankton.color.type_color; } - > = lib_plankton.structures.hashmap_construct( - (x => x.toFixed(0)), - lib_plankton.structures.hashmap_dump( - stuff.sources - ) - .map( - (pair) => ({ - "key": pair.key, - "value": { - "name": pair.value.name, - "color": lib_plankton.color.give_generic( - (pair.key - 1), - { - "saturation": 0.375, - "value": 0.375, - } - ), - } - }) + > = lib_plankton.map.hashmap.implementation_map( + lib_plankton.map.hashmap.make( + (x => x.toFixed(0)), + { + "pairs": ( + lib_plankton.map.dump( + stuff.sources + ) + .map( + (pair) => ({ + "key": pair.key, + "value": { + "name": pair.value.name, + "color": lib_plankton.color.give_generic( + (pair.key - 1), + { + "saturation": 0.375, + "value": 0.375, + } + ), + } + }) + ) + ) + } ) ); - return _zeitbild.frontend.helpers.template_coin( + return _zeitbild.frontend_web.helpers.template_coin( "tableview", { "sources": ( - await _zeitbild.frontend.helpers.promise_row( - lib_plankton.structures.hashmap_dump(sources) + await _zeitbild.frontend_web.helpers.promise_row( + lib_plankton.map.dump(sources) .map( - ({"key": calendar_id, "value": data}) => async () => _zeitbild.frontend.helpers.template_coin( + ({"key": calendar_id, "value": data}) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-sources-entry", { "name": data.name, @@ -477,18 +499,18 @@ namespace _zeitbild.frontend.view ) ).join(""), "rows": ( - await _zeitbild.frontend.helpers.promise_row( + await _zeitbild.frontend_web.helpers.promise_row( stuff.rows .map( - (row) => async () => _zeitbild.frontend.helpers.template_coin( + (row) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-row", { "week": row.week.toFixed(0).padStart(2, "0"), "cells": ( - await _zeitbild.frontend.helpers.promise_row( + await _zeitbild.frontend_web.helpers.promise_row( row.data .map( - (cell) => async () => _zeitbild.frontend.helpers.template_coin( + (cell) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-cell", { "extra_classes": ( @@ -499,8 +521,8 @@ namespace _zeitbild.frontend.view "title": lib_plankton.call.convey( cell.pit, [ - _zeitbild.frontend.helpers.pit_to_datetime, - (x : _zeitbild.frontend.helpers.type_datetime) => lib_plankton.string.coin( + _zeitbild.frontend_web.helpers.pit_to_datetime, + (x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin( "{{year}}-{{month}}-{{day}}", { "year": x.date.year.toFixed(0).padStart(4, "0"), @@ -513,8 +535,8 @@ namespace _zeitbild.frontend.view "day": lib_plankton.call.convey( cell.pit, [ - _zeitbild.frontend.helpers.pit_to_datetime, - (x : _zeitbild.frontend.helpers.type_datetime) => lib_plankton.string.coin( + _zeitbild.frontend_web.helpers.pit_to_datetime, + (x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin( "{{day}}", { "year": x.date.year.toFixed(0).padStart(4, "0"), @@ -525,21 +547,19 @@ namespace _zeitbild.frontend.view ] ), "entries": ( - await _zeitbild.frontend.helpers.promise_row( + await _zeitbild.frontend_web.helpers.promise_row( cell.entries .map( - (entry) => () => _zeitbild.frontend.helpers.template_coin( + (entry) => () => _zeitbild.frontend_web.helpers.template_coin( "tableview-cell-entry", { "color": lib_plankton.color.output_hex( - lib_plankton.structures.hashmap_get( - sources, + sources.get( entry.calendar_id ).color ), "title": event_generate_tooltip( - lib_plankton.structures.hashmap_get( - sources, + sources.get( entry.calendar_id ).name, entry.event @@ -570,8 +590,8 @@ namespace _zeitbild.frontend.view async function calendar_view_list_data( calendar_ids : Array, options : { - from ?: _zeitbild.frontend.helpers.type_pit; - to ?: _zeitbild.frontend.helpers.type_pit; + from ?: _zeitbild.frontend_web.helpers.type_pit; + to ?: _zeitbild.frontend_web.helpers.type_pit; timezone_shift ?: int; } = {} ) : Promise< @@ -583,19 +603,19 @@ namespace _zeitbild.frontend.view > > { - const now_pit : _zeitbild.frontend.helpers.type_pit = _zeitbild.frontend.helpers.pit_now(); + const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); options = Object.assign( { "from": lib_plankton.call.convey( now_pit, [ - (x : _zeitbild.frontend.helpers.type_pit) => _zeitbild.frontend.helpers.pit_shift_day(x, -1), + (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_day(x, -1), ] ), "to": lib_plankton.call.convey( now_pit, [ - (x : _zeitbild.frontend.helpers.type_pit) => _zeitbild.frontend.helpers.pit_shift_week(x, +4), + (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4), ] ), "timezone_shift": 0, @@ -608,17 +628,19 @@ namespace _zeitbild.frontend.view calendar_id : type_calendar_id; event : type_event; } - > = await _zeitbild.frontend.resources.backend.calendar_gather_events( - calendar_ids, - (options.from as _zeitbild.frontend.helpers.type_pit), - (options.to as _zeitbild.frontend.helpers.type_pit) + > = await _zeitbild.frontend_web.backend.events( + (options.from as _zeitbild.frontend_web.helpers.type_pit), + (options.to as _zeitbild.frontend_web.helpers.type_pit), + { + "calendar_ids": calendar_ids, + } ); // TODO: optimize entries.sort( (entry_1, entry_2) => ( - _zeitbild.frontend.helpers.pit_from_datetime(entry_1.event.begin) + _zeitbild.frontend_web.helpers.pit_from_datetime(entry_1.event.begin) - - _zeitbild.frontend.helpers.pit_from_datetime(entry_2.event.begin) + _zeitbild.frontend_web.helpers.pit_from_datetime(entry_2.event.begin) ) ); @@ -631,8 +653,8 @@ namespace _zeitbild.frontend.view export async function calendar_view_list_html( calendar_ids : Array, options : { - from ?: _zeitbild.frontend.helpers.type_pit; - to ?: _zeitbild.frontend.helpers.type_pit; + from ?: _zeitbild.frontend_web.helpers.type_pit; + to ?: _zeitbild.frontend_web.helpers.type_pit; timezone_shift ?: int; } = {} ) : Promise diff --git a/tools/build b/tools/build index 3447f54..46c7d41 100755 --- a/tools/build +++ b/tools/build @@ -24,14 +24,6 @@ def main(): metavar = "", help = "conf path", ) - argument_parser.add_argument( - "-d", - "--data-path", - type = str, - default = None, - metavar = "", - help = "data path", - ) args = argument_parser.parse_args() ## exec @@ -55,17 +47,6 @@ def main(): args.output_directory, ) ) - if True: - if (args.data_path is None): - pass - else: - _os.system( - "cp %s %s/data.json" - % ( - args.data_path, - args.output_directory, - ) - ) _sys.stdout.write("%s\n" % args.output_directory) diff --git a/tools/makefile b/tools/makefile index 67fe072..cc29957 100644 --- a/tools/makefile +++ b/tools/makefile @@ -48,13 +48,14 @@ logic: ${dir_build}/logic.js ${dir_temp}/logic-unlinked.js: \ ${dir_lib}/plankton/plankton.d.ts \ ${dir_source}/logic/helpers.ts \ + ${dir_source}/logic/conf.ts \ ${dir_source}/logic/types.ts \ ${dir_source}/logic/backend.ts \ ${dir_source}/logic/view.ts \ ${dir_source}/logic/main.ts @ ${cmd_log} "logic | compile …" @ ${cmd_mkdir} $(dir $@) - @ ${cmd_tsc} --lib dom,es2020 --strict $^ --outFile $@ + @ ${cmd_tsc} --lib dom,es2020 $^ --outFile $@ # --strict ${dir_build}/logic.js: \ ${dir_lib}/plankton/plankton.js \ diff --git a/tools/update-plankton b/tools/update-plankton index ccf3d0d..452a3e2 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -8,16 +8,18 @@ modules="" modules="${modules} base" modules="${modules} call" modules="${modules} file" -modules="${modules} structures" modules="${modules} json" modules="${modules} args" modules="${modules} string" modules="${modules} color" modules="${modules} xml" -modules="${modules} ical" +modules="${modules} map" +# modules="${modules} ical" modules="${modules} http" modules="${modules} log" modules="${modules} url" +modules="${modules} conf" +modules="${modules} www_form" ## exec