radashi 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +38 -0
  3. package/dist/cjs/array.cjs +281 -0
  4. package/dist/cjs/array.cjs.map +1 -0
  5. package/dist/cjs/async.cjs +169 -0
  6. package/dist/cjs/async.cjs.map +1 -0
  7. package/dist/cjs/curry.cjs +113 -0
  8. package/dist/cjs/curry.cjs.map +1 -0
  9. package/dist/cjs/index.cjs +109 -0
  10. package/dist/cjs/index.cjs.map +1 -0
  11. package/dist/cjs/number.cjs +34 -0
  12. package/dist/cjs/number.cjs.map +1 -0
  13. package/dist/cjs/object.cjs +204 -0
  14. package/dist/cjs/object.cjs.map +1 -0
  15. package/dist/cjs/random.cjs +34 -0
  16. package/dist/cjs/random.cjs.map +1 -0
  17. package/dist/cjs/series.cjs +62 -0
  18. package/dist/cjs/series.cjs.map +1 -0
  19. package/dist/cjs/string.cjs +72 -0
  20. package/dist/cjs/string.cjs.map +1 -0
  21. package/dist/cjs/typed.cjs +104 -0
  22. package/dist/cjs/typed.cjs.map +1 -0
  23. package/dist/esm/array.mjs +251 -0
  24. package/dist/esm/array.mjs.map +1 -0
  25. package/dist/esm/async.mjs +158 -0
  26. package/dist/esm/async.mjs.map +1 -0
  27. package/dist/esm/curry.mjs +103 -0
  28. package/dist/esm/curry.mjs.map +1 -0
  29. package/dist/esm/index.mjs +10 -0
  30. package/dist/esm/index.mjs.map +1 -0
  31. package/dist/esm/number.mjs +30 -0
  32. package/dist/esm/number.mjs.map +1 -0
  33. package/dist/esm/object.mjs +186 -0
  34. package/dist/esm/object.mjs.map +1 -0
  35. package/dist/esm/random.mjs +29 -0
  36. package/dist/esm/random.mjs.map +1 -0
  37. package/dist/esm/series.mjs +60 -0
  38. package/dist/esm/series.mjs.map +1 -0
  39. package/dist/esm/string.mjs +63 -0
  40. package/dist/esm/string.mjs.map +1 -0
  41. package/dist/esm/typed.mjs +90 -0
  42. package/dist/esm/typed.mjs.map +1 -0
  43. package/dist/index.d.ts +682 -0
  44. package/package.json +54 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 radash
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # radashi
2
+
3
+ :loud_sound: `/raw-dash-ee/`
4
+
5
+ - **What is this?**
6
+ A fork of the renowned [`radash`](https://github.com/sodiray/radash) library by Ray Epps [@sodiray](https://github.com/sodiray).
7
+ - **Why does this exist?**
8
+ This fork aims to be a more consistently maintained version of the library, with bug fixes and improvements. Pull requests are encouraged, but please keep them small and focused. Sweeping changes are discouraged and won't be merged.
9
+ - **Can I help you maintain this?**
10
+ Yes! I'll add you as a contributor to the repository. You can review pull requests and even merge them. You can help with closing issues, too. Committing directly to the main branch is a privilege you can earn, as is publishing versions to NPM.
11
+ - **Is backwards compatibility a goal?**
12
+ Yes! We want the transition from `radash` to this library to be smooth. We'll make sure to avoid breaking changes. If any are made, they will be clearly documented at the bottom of this page.
13
+ - **Is there official documentation?**
14
+ Currently, there is no documentation beyond this page. I will get to it eventually, but for now, you can refer to the original `radash` documentation [here](https://radash-docs.vercel.app).
15
+
16
+ ## Install
17
+
18
+ ```sh
19
+ pnpm add radashi
20
+ ```
21
+ ```sh
22
+ yarn add radashi
23
+ ```
24
+ ```sh
25
+ npm install radashi
26
+ ```
27
+
28
+ ## Contributing
29
+
30
+ Contributions are welcome and appreciated! Check out the [contributing guide](./.github/contributing.md) before you dive in.
31
+
32
+ ## Changelog
33
+
34
+ This section documents the changes between the original `radash` library and this fork.
35
+
36
+ ### 12.1.0
37
+
38
+ - Initial release. No differences.
@@ -0,0 +1,281 @@
1
+ 'use strict';
2
+
3
+ const typed = require('./typed.cjs');
4
+
5
+ const group = (array, getGroupId) => {
6
+ return array.reduce((acc, item) => {
7
+ const groupId = getGroupId(item);
8
+ if (!acc[groupId])
9
+ acc[groupId] = [];
10
+ acc[groupId].push(item);
11
+ return acc;
12
+ }, {});
13
+ };
14
+ function zip(...arrays) {
15
+ if (!arrays || !arrays.length)
16
+ return [];
17
+ return new Array(Math.max(...arrays.map(({ length }) => length))).fill([]).map((_, idx) => arrays.map((array) => array[idx]));
18
+ }
19
+ function zipToObject(keys, values) {
20
+ if (!keys || !keys.length) {
21
+ return {};
22
+ }
23
+ const getValue = typed.isFunction(values) ? values : typed.isArray(values) ? (_k, i) => values[i] : (_k, _i) => values;
24
+ return keys.reduce((acc, key, idx) => {
25
+ acc[key] = getValue(key, idx);
26
+ return acc;
27
+ }, {});
28
+ }
29
+ const boil = (array, compareFunc) => {
30
+ if (!array || (array.length ?? 0) === 0)
31
+ return null;
32
+ return array.reduce(compareFunc);
33
+ };
34
+ function sum(array, fn) {
35
+ return (array || []).reduce((acc, item) => acc + (fn ? fn(item) : item), 0);
36
+ }
37
+ const first = (array, defaultValue = void 0) => {
38
+ return array?.length > 0 ? array[0] : defaultValue;
39
+ };
40
+ const last = (array, defaultValue = void 0) => {
41
+ return array?.length > 0 ? array[array.length - 1] : defaultValue;
42
+ };
43
+ const sort = (array, getter, desc = false) => {
44
+ if (!array)
45
+ return [];
46
+ const asc = (a, b) => getter(a) - getter(b);
47
+ const dsc = (a, b) => getter(b) - getter(a);
48
+ return array.slice().sort(desc === true ? dsc : asc);
49
+ };
50
+ const alphabetical = (array, getter, dir = "asc") => {
51
+ if (!array)
52
+ return [];
53
+ const asc = (a, b) => `${getter(a)}`.localeCompare(getter(b));
54
+ const dsc = (a, b) => `${getter(b)}`.localeCompare(getter(a));
55
+ return array.slice().sort(dir === "desc" ? dsc : asc);
56
+ };
57
+ const counting = (list2, identity) => {
58
+ if (!list2)
59
+ return {};
60
+ return list2.reduce((acc, item) => {
61
+ const id = identity(item);
62
+ acc[id] = (acc[id] ?? 0) + 1;
63
+ return acc;
64
+ }, {});
65
+ };
66
+ const replace = (list2, newItem, match) => {
67
+ if (!list2)
68
+ return [];
69
+ if (newItem === void 0)
70
+ return [...list2];
71
+ for (let idx = 0; idx < list2.length; idx++) {
72
+ const item = list2[idx];
73
+ if (match(item, idx)) {
74
+ return [
75
+ ...list2.slice(0, idx),
76
+ newItem,
77
+ ...list2.slice(idx + 1, list2.length)
78
+ ];
79
+ }
80
+ }
81
+ return [...list2];
82
+ };
83
+ const objectify = (array, getKey, getValue = (item) => item) => {
84
+ return array.reduce((acc, item) => {
85
+ acc[getKey(item)] = getValue(item);
86
+ return acc;
87
+ }, {});
88
+ };
89
+ const select = (array, mapper, condition) => {
90
+ if (!array)
91
+ return [];
92
+ return array.reduce((acc, item, index) => {
93
+ if (!condition(item, index))
94
+ return acc;
95
+ acc.push(mapper(item, index));
96
+ return acc;
97
+ }, []);
98
+ };
99
+ function max(array, getter) {
100
+ const get = getter ?? ((v) => v);
101
+ return boil(array, (a, b) => get(a) > get(b) ? a : b);
102
+ }
103
+ function min(array, getter) {
104
+ const get = getter ?? ((v) => v);
105
+ return boil(array, (a, b) => get(a) < get(b) ? a : b);
106
+ }
107
+ const cluster = (list2, size = 2) => {
108
+ const clusterCount = Math.ceil(list2.length / size);
109
+ return new Array(clusterCount).fill(null).map((_c, i) => {
110
+ return list2.slice(i * size, i * size + size);
111
+ });
112
+ };
113
+ const unique = (array, toKey) => {
114
+ const valueMap = array.reduce((acc, item) => {
115
+ const key = toKey ? toKey(item) : item;
116
+ if (acc[key])
117
+ return acc;
118
+ acc[key] = item;
119
+ return acc;
120
+ }, {});
121
+ return Object.values(valueMap);
122
+ };
123
+ function* range(startOrLength, end, valueOrMapper = (i) => i, step = 1) {
124
+ const mapper = typed.isFunction(valueOrMapper) ? valueOrMapper : () => valueOrMapper;
125
+ const start = end ? startOrLength : 0;
126
+ const final = end ?? startOrLength;
127
+ for (let i = start; i <= final; i += step) {
128
+ yield mapper(i);
129
+ if (i + step > final)
130
+ break;
131
+ }
132
+ }
133
+ const list = (startOrLength, end, valueOrMapper, step) => {
134
+ return Array.from(range(startOrLength, end, valueOrMapper, step));
135
+ };
136
+ const flat = (lists) => {
137
+ return lists.reduce((acc, list2) => {
138
+ acc.push(...list2);
139
+ return acc;
140
+ }, []);
141
+ };
142
+ const intersects = (listA, listB, identity) => {
143
+ if (!listA || !listB)
144
+ return false;
145
+ const ident = identity ?? ((x) => x);
146
+ const dictB = listB.reduce((acc, item) => {
147
+ acc[ident(item)] = true;
148
+ return acc;
149
+ }, {});
150
+ return listA.some((value) => dictB[ident(value)]);
151
+ };
152
+ const fork = (list2, condition) => {
153
+ if (!list2)
154
+ return [[], []];
155
+ return list2.reduce(
156
+ (acc, item) => {
157
+ const [a, b] = acc;
158
+ if (condition(item)) {
159
+ return [[...a, item], b];
160
+ } else {
161
+ return [a, [...b, item]];
162
+ }
163
+ },
164
+ [[], []]
165
+ );
166
+ };
167
+ const merge = (root, others, matcher) => {
168
+ if (!others && !root)
169
+ return [];
170
+ if (!others)
171
+ return root;
172
+ if (!root)
173
+ return [];
174
+ if (!matcher)
175
+ return root;
176
+ return root.reduce((acc, r) => {
177
+ const matched = others.find((o) => matcher(r) === matcher(o));
178
+ if (matched)
179
+ acc.push(matched);
180
+ else
181
+ acc.push(r);
182
+ return acc;
183
+ }, []);
184
+ };
185
+ const replaceOrAppend = (list2, newItem, match) => {
186
+ if (!list2 && !newItem)
187
+ return [];
188
+ if (!newItem)
189
+ return [...list2];
190
+ if (!list2)
191
+ return [newItem];
192
+ for (let idx = 0; idx < list2.length; idx++) {
193
+ const item = list2[idx];
194
+ if (match(item, idx)) {
195
+ return [
196
+ ...list2.slice(0, idx),
197
+ newItem,
198
+ ...list2.slice(idx + 1, list2.length)
199
+ ];
200
+ }
201
+ }
202
+ return [...list2, newItem];
203
+ };
204
+ const toggle = (list2, item, toKey, options) => {
205
+ if (!list2 && !item)
206
+ return [];
207
+ if (!list2)
208
+ return [item];
209
+ if (!item)
210
+ return [...list2];
211
+ const matcher = toKey ? (x, idx) => toKey(x, idx) === toKey(item, idx) : (x) => x === item;
212
+ const existing = list2.find(matcher);
213
+ if (existing)
214
+ return list2.filter((x, idx) => !matcher(x, idx));
215
+ const strategy = options?.strategy ?? "append";
216
+ if (strategy === "append")
217
+ return [...list2, item];
218
+ return [item, ...list2];
219
+ };
220
+ const sift = (list2) => {
221
+ return list2?.filter((x) => !!x) ?? [];
222
+ };
223
+ const iterate = (count, func, initValue) => {
224
+ let value = initValue;
225
+ for (let i = 1; i <= count; i++) {
226
+ value = func(value, i);
227
+ }
228
+ return value;
229
+ };
230
+ const diff = (root, other, identity = (t) => t) => {
231
+ if (!root?.length && !other?.length)
232
+ return [];
233
+ if (root?.length === void 0)
234
+ return [...other];
235
+ if (!other?.length)
236
+ return [...root];
237
+ const bKeys = other.reduce((acc, item) => {
238
+ acc[identity(item)] = true;
239
+ return acc;
240
+ }, {});
241
+ return root.filter((a) => !bKeys[identity(a)]);
242
+ };
243
+ function shift(arr, n) {
244
+ if (arr.length === 0)
245
+ return arr;
246
+ const shiftNumber = n % arr.length;
247
+ if (shiftNumber === 0)
248
+ return arr;
249
+ return [...arr.slice(-shiftNumber, arr.length), ...arr.slice(0, -shiftNumber)];
250
+ }
251
+
252
+ exports.alphabetical = alphabetical;
253
+ exports.boil = boil;
254
+ exports.cluster = cluster;
255
+ exports.counting = counting;
256
+ exports.diff = diff;
257
+ exports.first = first;
258
+ exports.flat = flat;
259
+ exports.fork = fork;
260
+ exports.group = group;
261
+ exports.intersects = intersects;
262
+ exports.iterate = iterate;
263
+ exports.last = last;
264
+ exports.list = list;
265
+ exports.max = max;
266
+ exports.merge = merge;
267
+ exports.min = min;
268
+ exports.objectify = objectify;
269
+ exports.range = range;
270
+ exports.replace = replace;
271
+ exports.replaceOrAppend = replaceOrAppend;
272
+ exports.select = select;
273
+ exports.shift = shift;
274
+ exports.sift = sift;
275
+ exports.sort = sort;
276
+ exports.sum = sum;
277
+ exports.toggle = toggle;
278
+ exports.unique = unique;
279
+ exports.zip = zip;
280
+ exports.zipToObject = zipToObject;
281
+ //# sourceMappingURL=array.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.cjs","sources":["../../src/array.ts"],"sourcesContent":["import { isArray, isFunction } from './typed'\n\n/**\n * Sorts an array of items into groups. The return value is a map where the keys are\n * the group ids the given getGroupId function produced and the value is an array of\n * each item in that group.\n */\nexport const group = <T, Key extends string | number | symbol>(\n array: readonly T[],\n getGroupId: (item: T) => Key\n): Partial<Record<Key, T[]>> => {\n return array.reduce((acc, item) => {\n const groupId = getGroupId(item)\n if (!acc[groupId]) acc[groupId] = []\n acc[groupId].push(item)\n return acc\n }, {} as Record<Key, T[]>)\n}\n\n/**\n * Creates an array of grouped elements, the first of which contains the\n * first elements of the given arrays, the second of which contains the\n * second elements of the given arrays, and so on.\n *\n * Ex. const zipped = zip(['a', 'b'], [1, 2], [true, false]) // [['a', 1, true], ['b', 2, false]]\n */\nexport function zip<T1, T2, T3, T4, T5>(\n array1: T1[],\n array2: T2[],\n array3: T3[],\n array4: T4[],\n array5: T5[]\n): [T1, T2, T3, T4, T5][]\nexport function zip<T1, T2, T3, T4>(\n array1: T1[],\n array2: T2[],\n array3: T3[],\n array4: T4[]\n): [T1, T2, T3, T4][]\nexport function zip<T1, T2, T3>(\n array1: T1[],\n array2: T2[],\n array3: T3[]\n): [T1, T2, T3][]\nexport function zip<T1, T2>(array1: T1[], array2: T2[]): [T1, T2][]\nexport function zip<T>(...arrays: T[][]): T[][] {\n if (!arrays || !arrays.length) return []\n return new Array(Math.max(...arrays.map(({ length }) => length)))\n .fill([])\n .map((_, idx) => arrays.map(array => array[idx]))\n}\n\n/**\n * Creates an object mapping the specified keys to their corresponding values\n *\n * Ex. const zipped = zipToObject(['a', 'b'], [1, 2]) // { a: 1, b: 2 }\n * Ex. const zipped = zipToObject(['a', 'b'], (k, i) => k + i) // { a: 'a0', b: 'b1' }\n * Ex. const zipped = zipToObject(['a', 'b'], 1) // { a: 1, b: 1 }\n */\nexport function zipToObject<K extends string | number | symbol, V>(\n keys: K[],\n values: V | ((key: K, idx: number) => V) | V[]\n): Record<K, V> {\n if (!keys || !keys.length) {\n return {} as Record<K, V>\n }\n\n const getValue = isFunction(values)\n ? values\n : isArray(values)\n ? (_k: K, i: number) => values[i]\n : (_k: K, _i: number) => values\n\n return keys.reduce((acc, key, idx) => {\n acc[key] = getValue(key, idx)\n return acc\n }, {} as Record<K, V>)\n}\n\n/**\n * Go through a list of items, starting with the first item,\n * and comparing with the second. Keep the one you want then\n * compare that to the next item in the list with the same\n *\n * Ex. const greatest = () => boil(numbers, (a, b) => a > b)\n */\nexport const boil = <T>(\n array: readonly T[],\n compareFunc: (a: T, b: T) => T\n) => {\n if (!array || (array.length ?? 0) === 0) return null\n return array.reduce(compareFunc)\n}\n\n/**\n * Sum all numbers in an array. Optionally provide a function\n * to convert objects in the array to number values.\n */\nexport function sum<T extends number>(array: readonly T[]): number\nexport function sum<T extends object>(\n array: readonly T[],\n fn: (item: T) => number\n): number\nexport function sum<T extends object | number>(\n array: readonly any[],\n fn?: (item: T) => number\n): number {\n return (array || []).reduce((acc, item) => acc + (fn ? fn(item) : item), 0)\n}\n\n/**\n * Get the first item in an array or a default value\n */\nexport const first = <T>(\n array: readonly T[],\n defaultValue: T | null | undefined = undefined\n) => {\n return array?.length > 0 ? array[0] : defaultValue\n}\n\n/**\n * Get the last item in an array or a default value\n */\nexport const last = <T>(\n array: readonly T[],\n defaultValue: T | null | undefined = undefined\n) => {\n return array?.length > 0 ? array[array.length - 1] : defaultValue\n}\n\n/**\n * Sort an array without modifying it and return\n * the newly sorted value\n */\nexport const sort = <T>(\n array: readonly T[],\n getter: (item: T) => number,\n desc = false\n) => {\n if (!array) return []\n const asc = (a: T, b: T) => getter(a) - getter(b)\n const dsc = (a: T, b: T) => getter(b) - getter(a)\n return array.slice().sort(desc === true ? dsc : asc)\n}\n\n/**\n * Sort an array without modifying it and return\n * the newly sorted value. Allows for a string\n * sorting value.\n */\nexport const alphabetical = <T>(\n array: readonly T[],\n getter: (item: T) => string,\n dir: 'asc' | 'desc' = 'asc'\n) => {\n if (!array) return []\n const asc = (a: T, b: T) => `${getter(a)}`.localeCompare(getter(b))\n const dsc = (a: T, b: T) => `${getter(b)}`.localeCompare(getter(a))\n return array.slice().sort(dir === 'desc' ? dsc : asc)\n}\n\nexport const counting = <T, TId extends string | number | symbol>(\n list: readonly T[],\n identity: (item: T) => TId\n): Record<TId, number> => {\n if (!list) return {} as Record<TId, number>\n return list.reduce((acc, item) => {\n const id = identity(item)\n acc[id] = (acc[id] ?? 0) + 1\n return acc\n }, {} as Record<TId, number>)\n}\n\n/**\n * Replace an element in an array with a new\n * item without modifying the array and return\n * the new value\n */\nexport const replace = <T>(\n list: readonly T[],\n newItem: T,\n match: (item: T, idx: number) => boolean\n): T[] => {\n if (!list) return []\n if (newItem === undefined) return [...list]\n for (let idx = 0; idx < list.length; idx++) {\n const item = list[idx]\n if (match(item, idx)) {\n return [\n ...list.slice(0, idx),\n newItem,\n ...list.slice(idx + 1, list.length)\n ]\n }\n }\n return [...list]\n}\n\n/**\n * Convert an array to a dictionary by mapping each item\n * into a dictionary key & value\n */\nexport const objectify = <T, Key extends string | number | symbol, Value = T>(\n array: readonly T[],\n getKey: (item: T) => Key,\n getValue: (item: T) => Value = item => item as unknown as Value\n): Record<Key, Value> => {\n return array.reduce((acc, item) => {\n acc[getKey(item)] = getValue(item)\n return acc\n }, {} as Record<Key, Value>)\n}\n\n/**\n * Select performs a filter and a mapper inside of a reduce,\n * only iterating the list one time.\n *\n * @example\n * select([1, 2, 3, 4], x => x*x, x > 2) == [9, 16]\n */\nexport const select = <T, K>(\n array: readonly T[],\n mapper: (item: T, index: number) => K,\n condition: (item: T, index: number) => boolean\n) => {\n if (!array) return []\n return array.reduce((acc, item, index) => {\n if (!condition(item, index)) return acc\n acc.push(mapper(item, index))\n return acc\n }, [] as K[])\n}\n\n/**\n * Max gets the greatest value from a list\n *\n * @example\n * max([ 2, 3, 5]) == 5\n * max([{ num: 1 }, { num: 2 }], x => x.num) == { num: 2 }\n */\nexport function max(array: readonly [number, ...number[]]): number\nexport function max(array: readonly number[]): number | null\nexport function max<T>(\n array: readonly T[],\n getter: (item: T) => number\n): T | null\nexport function max<T>(\n array: readonly T[],\n getter?: (item: T) => number\n): T | null {\n const get = getter ?? ((v: any) => v)\n return boil(array, (a, b) => (get(a) > get(b) ? a : b))\n}\n\n/**\n * Min gets the smallest value from a list\n *\n * @example\n * min([1, 2, 3, 4]) == 1\n * min([{ num: 1 }, { num: 2 }], x => x.num) == { num: 1 }\n */\nexport function min(array: readonly [number, ...number[]]): number\nexport function min(array: readonly number[]): number | null\nexport function min<T>(\n array: readonly T[],\n getter: (item: T) => number\n): T | null\nexport function min<T>(\n array: readonly T[],\n getter?: (item: T) => number\n): T | null {\n const get = getter ?? ((v: any) => v)\n return boil(array, (a, b) => (get(a) < get(b) ? a : b))\n}\n\n/**\n * Splits a single list into many lists of the desired size. If\n * given a list of 10 items and a size of 2, it will return 5\n * lists with 2 items each\n */\nexport const cluster = <T>(list: readonly T[], size: number = 2): T[][] => {\n const clusterCount = Math.ceil(list.length / size)\n return new Array(clusterCount).fill(null).map((_c: null, i: number) => {\n return list.slice(i * size, i * size + size)\n })\n}\n\n/**\n * Given a list of items returns a new list with only\n * unique items. Accepts an optional identity function\n * to convert each item in the list to a comparable identity\n * value\n */\nexport const unique = <T, K extends string | number | symbol>(\n array: readonly T[],\n toKey?: (item: T) => K\n): T[] => {\n const valueMap = array.reduce((acc, item) => {\n const key = toKey ? toKey(item) : (item as any as string | number | symbol)\n if (acc[key]) return acc\n acc[key] = item\n return acc\n }, {} as Record<string | number | symbol, T>)\n return Object.values(valueMap)\n}\n\n/**\n * Creates a generator that will produce an iteration through\n * the range of number as requested.\n *\n * @example\n * range(3) // yields 0, 1, 2, 3\n * range(0, 3) // yields 0, 1, 2, 3\n * range(0, 3, 'y') // yields y, y, y, y\n * range(0, 3, () => 'y') // yields y, y, y, y\n * range(0, 3, i => i) // yields 0, 1, 2, 3\n * range(0, 3, i => `y${i}`) // yields y0, y1, y2, y3\n * range(0, 3, obj) // yields obj, obj, obj, obj\n * range(0, 6, i => i, 2) // yields 0, 2, 4, 6\n */\nexport function* range<T = number>(\n startOrLength: number,\n end?: number,\n valueOrMapper: T | ((i: number) => T) = i => i as T,\n step: number = 1\n): Generator<T> {\n const mapper = isFunction(valueOrMapper) ? valueOrMapper : () => valueOrMapper\n const start = end ? startOrLength : 0\n const final = end ?? startOrLength\n for (let i = start; i <= final; i += step) {\n yield mapper(i)\n if (i + step > final) break\n }\n}\n\n/**\n * Creates a list of given start, end, value, and\n * step parameters.\n *\n * @example\n * list(3) // 0, 1, 2, 3\n * list(0, 3) // 0, 1, 2, 3\n * list(0, 3, 'y') // y, y, y, y\n * list(0, 3, () => 'y') // y, y, y, y\n * list(0, 3, i => i) // 0, 1, 2, 3\n * list(0, 3, i => `y${i}`) // y0, y1, y2, y3\n * list(0, 3, obj) // obj, obj, obj, obj\n * list(0, 6, i => i, 2) // 0, 2, 4, 6\n */\nexport const list = <T = number>(\n startOrLength: number,\n end?: number,\n valueOrMapper?: T | ((i: number) => T),\n step?: number\n): T[] => {\n return Array.from(range(startOrLength, end, valueOrMapper, step))\n}\n\n/**\n * Given an array of arrays, returns a single\n * dimentional array with all items in it.\n */\nexport const flat = <T>(lists: readonly T[][]): T[] => {\n return lists.reduce((acc, list) => {\n acc.push(...list)\n return acc\n }, [])\n}\n\n/**\n * Given two arrays, returns true if any\n * elements intersect\n */\nexport const intersects = <T, K extends string | number | symbol>(\n listA: readonly T[],\n listB: readonly T[],\n identity?: (t: T) => K\n): boolean => {\n if (!listA || !listB) return false\n const ident = identity ?? ((x: T) => x as unknown as K)\n const dictB = listB.reduce((acc, item) => {\n acc[ident(item)] = true\n return acc\n }, {} as Record<string | number | symbol, boolean>)\n return listA.some(value => dictB[ident(value)])\n}\n\n/**\n * Split an array into two array based on\n * a true/false condition function\n */\nexport const fork = <T>(\n list: readonly T[],\n condition: (item: T) => boolean\n): [T[], T[]] => {\n if (!list) return [[], []]\n return list.reduce(\n (acc, item) => {\n const [a, b] = acc\n if (condition(item)) {\n return [[...a, item], b]\n } else {\n return [a, [...b, item]]\n }\n },\n [[], []] as [T[], T[]]\n )\n}\n\n/**\n * Given two lists of the same type, iterate the first list\n * and replace items matched by the matcher func in the\n * first place.\n */\nexport const merge = <T>(\n root: readonly T[],\n others: readonly T[],\n matcher: (item: T) => any\n) => {\n if (!others && !root) return []\n if (!others) return root\n if (!root) return []\n if (!matcher) return root\n return root.reduce((acc, r) => {\n const matched = others.find(o => matcher(r) === matcher(o))\n if (matched) acc.push(matched)\n else acc.push(r)\n return acc\n }, [] as T[])\n}\n\n/**\n * Replace an item in an array by a match function condition. If\n * no items match the function condition, appends the new item to\n * the end of the list.\n */\nexport const replaceOrAppend = <T>(\n list: readonly T[],\n newItem: T,\n match: (a: T, idx: number) => boolean\n) => {\n if (!list && !newItem) return []\n if (!newItem) return [...list]\n if (!list) return [newItem]\n for (let idx = 0; idx < list.length; idx++) {\n const item = list[idx]\n if (match(item, idx)) {\n return [\n ...list.slice(0, idx),\n newItem,\n ...list.slice(idx + 1, list.length)\n ]\n }\n }\n return [...list, newItem]\n}\n\n/**\n * If the item matching the condition already exists\n * in the list it will be removed. If it does not it\n * will be added.\n */\nexport const toggle = <T>(\n list: readonly T[],\n item: T,\n /**\n * Converts an item of type T item into a value that\n * can be checked for equality\n */\n toKey?: null | ((item: T, idx: number) => number | string | symbol),\n options?: {\n strategy?: 'prepend' | 'append'\n }\n) => {\n if (!list && !item) return []\n if (!list) return [item]\n if (!item) return [...list]\n const matcher = toKey\n ? (x: T, idx: number) => toKey(x, idx) === toKey(item, idx)\n : (x: T) => x === item\n const existing = list.find(matcher)\n if (existing) return list.filter((x, idx) => !matcher(x, idx))\n const strategy = options?.strategy ?? 'append'\n if (strategy === 'append') return [...list, item]\n return [item, ...list]\n}\n\ntype Falsy = null | undefined | false | '' | 0 | 0n\n\n/**\n * Given a list returns a new list with\n * only truthy values\n */\nexport const sift = <T>(list: readonly (T | Falsy)[]): T[] => {\n return (list?.filter(x => !!x) as T[]) ?? []\n}\n\n/**\n * Like a reduce but does not require an array.\n * Only need a number and will iterate the function\n * as many times as specified.\n *\n * NOTE: This is NOT zero indexed. If you pass count=5\n * you will get 1, 2, 3, 4, 5 iteration in the callback\n * function\n */\nexport const iterate = <T>(\n count: number,\n func: (currentValue: T, iteration: number) => T,\n initValue: T\n) => {\n let value = initValue\n for (let i = 1; i <= count; i++) {\n value = func(value, i)\n }\n return value\n}\n\n/**\n * Returns all items from the first list that\n * do not exist in the second list.\n */\nexport const diff = <T>(\n root: readonly T[],\n other: readonly T[],\n identity: (item: T) => string | number | symbol = (t: T) =>\n t as unknown as string | number | symbol\n): T[] => {\n if (!root?.length && !other?.length) return []\n if (root?.length === undefined) return [...other]\n if (!other?.length) return [...root]\n const bKeys = other.reduce((acc, item) => {\n acc[identity(item)] = true\n return acc\n }, {} as Record<string | number | symbol, boolean>)\n return root.filter(a => !bKeys[identity(a)])\n}\n\n/**\n * Shift array items by n steps\n * If n > 0 items will shift n steps to the right\n * If n < 0 items will shift n steps to the left\n */\nexport function shift<T>(arr: Array<T>, n: number) {\n if (arr.length === 0) return arr\n\n const shiftNumber = n % arr.length\n\n if (shiftNumber === 0) return arr\n\n return [...arr.slice(-shiftNumber, arr.length), ...arr.slice(0, -shiftNumber)]\n}\n"],"names":["isFunction","isArray","list"],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ 'use strict';
2
+
3
+ const array = require('./array.cjs');
4
+ const typed = require('./typed.cjs');
5
+
6
+ const reduce = async (array, asyncReducer, initValue) => {
7
+ const initProvided = initValue !== void 0;
8
+ if (!initProvided && array?.length < 1) {
9
+ throw new Error("Cannot reduce empty array with no init value");
10
+ }
11
+ const iter = initProvided ? array : array.slice(1);
12
+ let value = initProvided ? initValue : array[0];
13
+ for (const [i, item] of iter.entries()) {
14
+ value = await asyncReducer(value, item, i);
15
+ }
16
+ return value;
17
+ };
18
+ const map = async (array, asyncMapFunc) => {
19
+ if (!array)
20
+ return [];
21
+ let result = [];
22
+ let index = 0;
23
+ for (const value of array) {
24
+ const newValue = await asyncMapFunc(value, index++);
25
+ result.push(newValue);
26
+ }
27
+ return result;
28
+ };
29
+ const defer = async (func) => {
30
+ const callbacks = [];
31
+ const register = (fn, options) => callbacks.push({
32
+ fn,
33
+ rethrow: options?.rethrow ?? false
34
+ });
35
+ const [err, response] = await tryit(func)(register);
36
+ for (const { fn, rethrow } of callbacks) {
37
+ const [rethrown] = await tryit(fn)(err);
38
+ if (rethrown && rethrow)
39
+ throw rethrown;
40
+ }
41
+ if (err)
42
+ throw err;
43
+ return response;
44
+ };
45
+ class AggregateError extends Error {
46
+ constructor(errors = []) {
47
+ super();
48
+ const name = errors.find((e) => e.name)?.name ?? "";
49
+ this.name = `AggregateError(${name}...)`;
50
+ this.message = `AggregateError with ${errors.length} errors`;
51
+ this.stack = errors.find((e) => e.stack)?.stack ?? this.stack;
52
+ this.errors = errors;
53
+ }
54
+ }
55
+ const parallel = async (limit, array$1, func) => {
56
+ const work = array$1.map((item, index) => ({
57
+ index,
58
+ item
59
+ }));
60
+ const processor = async (res) => {
61
+ const results2 = [];
62
+ while (true) {
63
+ const next = work.pop();
64
+ if (!next)
65
+ return res(results2);
66
+ const [error, result] = await tryit(func)(next.item);
67
+ results2.push({
68
+ error,
69
+ result,
70
+ index: next.index
71
+ });
72
+ }
73
+ };
74
+ const queues = array.list(1, limit).map(() => new Promise(processor));
75
+ const itemResults = await Promise.all(queues);
76
+ const [errors, results] = array.fork(
77
+ array.sort(itemResults.flat(), (r) => r.index),
78
+ (x) => !!x.error
79
+ );
80
+ if (errors.length > 0) {
81
+ throw new AggregateError(errors.map((error) => error.error));
82
+ }
83
+ return results.map((r) => r.result);
84
+ };
85
+ async function all(promises) {
86
+ const entries = typed.isArray(promises) ? promises.map((p) => [null, p]) : Object.entries(promises);
87
+ const results = await Promise.all(
88
+ entries.map(
89
+ ([key, value]) => value.then((result) => ({ result, exc: null, key })).catch((exc) => ({ result: null, exc, key }))
90
+ )
91
+ );
92
+ const exceptions = results.filter((r) => r.exc);
93
+ if (exceptions.length > 0) {
94
+ throw new AggregateError(exceptions.map((e) => e.exc));
95
+ }
96
+ if (typed.isArray(promises)) {
97
+ return results.map((r) => r.result);
98
+ }
99
+ return results.reduce(
100
+ (acc, item) => ({
101
+ ...acc,
102
+ [item.key]: item.result
103
+ }),
104
+ {}
105
+ );
106
+ }
107
+ const retry = async (options, func) => {
108
+ const times = options?.times ?? 3;
109
+ const delay = options?.delay;
110
+ const backoff = options?.backoff ?? null;
111
+ for (const i of array.range(1, times)) {
112
+ const [err, result] = await tryit(func)((err2) => {
113
+ throw { _exited: err2 };
114
+ });
115
+ if (!err)
116
+ return result;
117
+ if (err._exited)
118
+ throw err._exited;
119
+ if (i === times)
120
+ throw err;
121
+ if (delay)
122
+ await sleep(delay);
123
+ if (backoff)
124
+ await sleep(backoff(i));
125
+ }
126
+ return void 0;
127
+ };
128
+ const sleep = (milliseconds) => {
129
+ return new Promise((res) => setTimeout(res, milliseconds));
130
+ };
131
+ const tryit = (func) => {
132
+ return (...args) => {
133
+ try {
134
+ const result = func(...args);
135
+ if (typed.isPromise(result)) {
136
+ return result.then((value) => [void 0, value]).catch((err) => [err, void 0]);
137
+ }
138
+ return [void 0, result];
139
+ } catch (err) {
140
+ return [err, void 0];
141
+ }
142
+ };
143
+ };
144
+ const guard = (func, shouldGuard) => {
145
+ const _guard = (err) => {
146
+ if (shouldGuard && !shouldGuard(err))
147
+ throw err;
148
+ return void 0;
149
+ };
150
+ const isPromise2 = (result) => result instanceof Promise;
151
+ try {
152
+ const result = func();
153
+ return isPromise2(result) ? result.catch(_guard) : result;
154
+ } catch (err) {
155
+ return _guard(err);
156
+ }
157
+ };
158
+
159
+ exports.AggregateError = AggregateError;
160
+ exports.all = all;
161
+ exports.defer = defer;
162
+ exports.guard = guard;
163
+ exports.map = map;
164
+ exports.parallel = parallel;
165
+ exports.reduce = reduce;
166
+ exports.retry = retry;
167
+ exports.sleep = sleep;
168
+ exports.tryit = tryit;
169
+ //# sourceMappingURL=async.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.cjs","sources":["../../src/async.ts"],"sourcesContent":["import { fork, list, range, sort } from './array'\nimport { isArray, isPromise } from './typed'\n\ndeclare const setTimeout: (fn: () => void, ms: number) => unknown\n\n/**\n * An async reduce function. Works like the\n * built-in Array.reduce function but handles\n * an async reducer function\n */\nexport const reduce = async <T, K>(\n array: readonly T[],\n asyncReducer: (acc: K, item: T, index: number) => Promise<K>,\n initValue?: K\n): Promise<K> => {\n const initProvided = initValue !== undefined\n if (!initProvided && array?.length < 1) {\n throw new Error('Cannot reduce empty array with no init value')\n }\n const iter = initProvided ? array : array.slice(1)\n let value: any = initProvided ? initValue : array[0]\n for (const [i, item] of iter.entries()) {\n value = await asyncReducer(value, item, i)\n }\n return value\n}\n\n/**\n * An async map function. Works like the\n * built-in Array.map function but handles\n * an async mapper function\n */\nexport const map = async <T, K>(\n array: readonly T[],\n asyncMapFunc: (item: T, index: number) => Promise<K>\n): Promise<K[]> => {\n if (!array) return []\n let result = []\n let index = 0\n for (const value of array) {\n const newValue = await asyncMapFunc(value, index++)\n result.push(newValue)\n }\n return result\n}\n\n/**\n * Useful when for script like things where cleanup\n * should be done on fail or sucess no matter.\n *\n * You can call defer many times to register many\n * defered functions that will all be called when\n * the function exits in any state.\n */\nexport const defer = async <TResponse>(\n func: (\n register: (\n fn: (error?: any) => any,\n options?: { rethrow?: boolean }\n ) => void\n ) => Promise<TResponse>\n): Promise<TResponse> => {\n const callbacks: {\n fn: (error?: any) => any\n rethrow: boolean\n }[] = []\n const register = (\n fn: (error?: any) => any,\n options?: { rethrow?: boolean }\n ) =>\n callbacks.push({\n fn,\n rethrow: options?.rethrow ?? false\n })\n const [err, response] = await tryit(func)(register)\n for (const { fn, rethrow } of callbacks) {\n const [rethrown] = await tryit(fn)(err)\n if (rethrown && rethrow) throw rethrown\n }\n if (err) throw err\n return response\n}\n\ntype WorkItemResult<K> = {\n index: number\n result: K\n error: any\n}\n\n/**\n * Support for the built-in AggregateError\n * is still new. Node < 15 doesn't have it\n * so patching here.\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError#browser_compatibility\n */\nexport class AggregateError extends Error {\n errors: Error[]\n constructor(errors: Error[] = []) {\n super()\n const name = errors.find(e => e.name)?.name ?? ''\n this.name = `AggregateError(${name}...)`\n this.message = `AggregateError with ${errors.length} errors`\n this.stack = errors.find(e => e.stack)?.stack ?? this.stack\n this.errors = errors\n }\n}\n\n/**\n * Executes many async functions in parallel. Returns the\n * results from all functions as an array. After all functions\n * have resolved, if any errors were thrown, they are rethrown\n * in an instance of AggregateError\n */\nexport const parallel = async <T, K>(\n limit: number,\n array: readonly T[],\n func: (item: T) => Promise<K>\n): Promise<K[]> => {\n const work = array.map((item, index) => ({\n index,\n item\n }))\n // Process array items\n const processor = async (res: (value: WorkItemResult<K>[]) => void) => {\n const results: WorkItemResult<K>[] = []\n while (true) {\n const next = work.pop()\n if (!next) return res(results)\n const [error, result] = await tryit(func)(next.item)\n results.push({\n error,\n result: result as K,\n index: next.index\n })\n }\n }\n // Create queues\n const queues = list(1, limit).map(() => new Promise(processor))\n // Wait for all queues to complete\n const itemResults = (await Promise.all(queues)) as WorkItemResult<K>[][]\n const [errors, results] = fork(\n sort(itemResults.flat(), r => r.index),\n x => !!x.error\n )\n if (errors.length > 0) {\n throw new AggregateError(errors.map(error => error.error))\n }\n return results.map(r => r.result)\n}\n\ntype PromiseValues<T extends Promise<any>[]> = {\n [K in keyof T]: T[K] extends Promise<infer U> ? U : never\n}\n\n/**\n * Functionally similar to Promise.all or Promise.allSettled. If any\n * errors are thrown, all errors are gathered and thrown in an\n * AggregateError.\n *\n * @example\n * const [user] = await all([\n * api.users.create(...),\n * s3.buckets.create(...),\n * slack.customerSuccessChannel.sendMessage(...)\n * ])\n */\nexport async function all<T extends [Promise<any>, ...Promise<any>[]]>(\n promises: T\n): Promise<PromiseValues<T>>\nexport async function all<T extends Promise<any>[]>(\n promises: T\n): Promise<PromiseValues<T>>\n/**\n * Functionally similar to Promise.all or Promise.allSettled. If any\n * errors are thrown, all errors are gathered and thrown in an\n * AggregateError.\n *\n * @example\n * const { user } = await all({\n * user: api.users.create(...),\n * bucket: s3.buckets.create(...),\n * message: slack.customerSuccessChannel.sendMessage(...)\n * })\n */\nexport async function all<T extends Record<string, Promise<any>>>(\n promises: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }>\nexport async function all<\n T extends Record<string, Promise<any>> | Promise<any>[]\n>(promises: T) {\n const entries = isArray(promises)\n ? promises.map(p => [null, p] as [null, Promise<any>])\n : Object.entries(promises)\n\n const results = await Promise.all(\n entries.map(([key, value]) =>\n value\n .then(result => ({ result, exc: null, key }))\n .catch(exc => ({ result: null, exc, key }))\n )\n )\n\n const exceptions = results.filter(r => r.exc)\n if (exceptions.length > 0) {\n throw new AggregateError(exceptions.map(e => e.exc))\n }\n\n if (isArray(promises)) {\n return results.map(r => r.result) as T extends Promise<any>[]\n ? PromiseValues<T>\n : unknown\n }\n\n return results.reduce(\n (acc, item) => ({\n ...acc,\n [item.key!]: item.result\n }),\n {} as { [K in keyof T]: Awaited<T[K]> }\n )\n}\n\n/**\n * Retries the given function the specified number\n * of times.\n */\nexport const retry = async <TResponse>(\n options: {\n times?: number\n delay?: number | null\n backoff?: (count: number) => number\n },\n func: (exit: (err: any) => void) => Promise<TResponse>\n): Promise<TResponse> => {\n const times = options?.times ?? 3\n const delay = options?.delay\n const backoff = options?.backoff ?? null\n for (const i of range(1, times)) {\n const [err, result] = (await tryit(func)((err: any) => {\n throw { _exited: err }\n })) as [any, TResponse]\n if (!err) return result\n if (err._exited) throw err._exited\n if (i === times) throw err\n if (delay) await sleep(delay)\n if (backoff) await sleep(backoff(i))\n }\n // Logically, we should never reach this\n // code path. It makes the function meet\n // strict mode requirements.\n /* istanbul ignore next */\n return undefined as unknown as TResponse\n}\n\n/**\n * Async wait\n */\nexport const sleep = (milliseconds: number) => {\n return new Promise<void>(res => setTimeout(res, milliseconds))\n}\n\n/**\n * A helper to try an async function without forking\n * the control flow. Returns an error first callback _like_\n * array response as [Error, result]\n */\nexport const tryit = <Args extends any[], Return>(\n func: (...args: Args) => Return\n) => {\n return (\n ...args: Args\n ): Return extends Promise<any>\n ? Promise<[Error, undefined] | [undefined, Awaited<Return>]>\n : [Error, undefined] | [undefined, Return] => {\n try {\n const result = func(...args)\n if (isPromise(result)) {\n return result\n .then(value => [undefined, value])\n .catch(err => [err, undefined]) as Return extends Promise<any>\n ? Promise<[Error, undefined] | [undefined, Awaited<Return>]>\n : [Error, undefined] | [undefined, Return]\n }\n return [undefined, result] as Return extends Promise<any>\n ? Promise<[Error, undefined] | [undefined, Awaited<Return>]>\n : [Error, undefined] | [undefined, Return]\n } catch (err) {\n return [err as any, undefined] as Return extends Promise<any>\n ? Promise<[Error, undefined] | [undefined, Awaited<Return>]>\n : [Error, undefined] | [undefined, Return]\n }\n }\n}\n\n/**\n * A helper to try an async function that returns undefined\n * if it fails.\n *\n * e.g. const result = await guard(fetchUsers)() ?? [];\n */\nexport const guard = <TFunction extends () => any>(\n func: TFunction,\n shouldGuard?: (err: any) => boolean\n): ReturnType<TFunction> extends Promise<any>\n ? Promise<Awaited<ReturnType<TFunction>> | undefined>\n : ReturnType<TFunction> | undefined => {\n const _guard = (err: any) => {\n if (shouldGuard && !shouldGuard(err)) throw err\n return undefined as any\n }\n const isPromise = (result: any): result is Promise<any> =>\n result instanceof Promise\n try {\n const result = func()\n return isPromise(result) ? result.catch(_guard) : result\n } catch (err) {\n return _guard(err)\n }\n}\n"],"names":["array","results","list","fork","sort","isArray","range","err","isPromise"],"mappings":";;;;;AAUO,MAAM,MAAS,GAAA,OACpB,KACA,EAAA,YAAA,EACA,SACe,KAAA;AACf,EAAA,MAAM,eAAe,SAAc,KAAA,KAAA,CAAA,CAAA;AACnC,EAAA,IAAI,CAAC,YAAA,IAAgB,KAAO,EAAA,MAAA,GAAS,CAAG,EAAA;AACtC,IAAM,MAAA,IAAI,MAAM,8CAA8C,CAAA,CAAA;AAAA,GAChE;AACA,EAAA,MAAM,IAAO,GAAA,YAAA,GAAe,KAAQ,GAAA,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AACjD,EAAA,IAAI,KAAa,GAAA,YAAA,GAAe,SAAY,GAAA,KAAA,CAAM,CAAC,CAAA,CAAA;AACnD,EAAA,KAAA,MAAW,CAAC,CAAG,EAAA,IAAI,CAAK,IAAA,IAAA,CAAK,SAAW,EAAA;AACtC,IAAA,KAAA,GAAQ,MAAM,YAAA,CAAa,KAAO,EAAA,IAAA,EAAM,CAAC,CAAA,CAAA;AAAA,GAC3C;AACA,EAAO,OAAA,KAAA,CAAA;AACT,EAAA;AAOa,MAAA,GAAA,GAAM,OACjB,KAAA,EACA,YACiB,KAAA;AACjB,EAAA,IAAI,CAAC,KAAA;AAAO,IAAA,OAAO,EAAC,CAAA;AACpB,EAAA,IAAI,SAAS,EAAC,CAAA;AACd,EAAA,IAAI,KAAQ,GAAA,CAAA,CAAA;AACZ,EAAA,KAAA,MAAW,SAAS,KAAO,EAAA;AACzB,IAAA,MAAM,QAAW,GAAA,MAAM,YAAa,CAAA,KAAA,EAAO,KAAO,EAAA,CAAA,CAAA;AAClD,IAAA,MAAA,CAAO,KAAK,QAAQ,CAAA,CAAA;AAAA,GACtB;AACA,EAAO,OAAA,MAAA,CAAA;AACT,EAAA;AAUa,MAAA,KAAA,GAAQ,OACnB,IAMuB,KAAA;AACvB,EAAA,MAAM,YAGA,EAAC,CAAA;AACP,EAAA,MAAM,QAAW,GAAA,CACf,EACA,EAAA,OAAA,KAEA,UAAU,IAAK,CAAA;AAAA,IACb,EAAA;AAAA,IACA,OAAA,EAAS,SAAS,OAAW,IAAA,KAAA;AAAA,GAC9B,CAAA,CAAA;AACH,EAAM,MAAA,CAAC,KAAK,QAAQ,CAAA,GAAI,MAAM,KAAM,CAAA,IAAI,EAAE,QAAQ,CAAA,CAAA;AAClD,EAAA,KAAA,MAAW,EAAE,EAAA,EAAI,OAAQ,EAAA,IAAK,SAAW,EAAA;AACvC,IAAA,MAAM,CAAC,QAAQ,CAAA,GAAI,MAAM,KAAM,CAAA,EAAE,EAAE,GAAG,CAAA,CAAA;AACtC,IAAA,IAAI,QAAY,IAAA,OAAA;AAAS,MAAM,MAAA,QAAA,CAAA;AAAA,GACjC;AACA,EAAI,IAAA,GAAA;AAAK,IAAM,MAAA,GAAA,CAAA;AACf,EAAO,OAAA,QAAA,CAAA;AACT,EAAA;AAcO,MAAM,uBAAuB,KAAM,CAAA;AAAA,EAExC,WAAA,CAAY,MAAkB,GAAA,EAAI,EAAA;AAChC,IAAM,KAAA,EAAA,CAAA;AACN,IAAA,MAAM,OAAO,MAAO,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,IAAI,GAAG,IAAQ,IAAA,EAAA,CAAA;AAC/C,IAAA,IAAA,CAAK,OAAO,CAAkB,eAAA,EAAA,IAAA,CAAA,IAAA,CAAA,CAAA;AAC9B,IAAK,IAAA,CAAA,OAAA,GAAU,uBAAuB,MAAO,CAAA,MAAA,CAAA,OAAA,CAAA,CAAA;AAC7C,IAAK,IAAA,CAAA,KAAA,GAAQ,OAAO,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA,EAAG,SAAS,IAAK,CAAA,KAAA,CAAA;AACtD,IAAA,IAAA,CAAK,MAAS,GAAA,MAAA,CAAA;AAAA,GAChB;AACF,CAAA;AAQO,MAAM,QAAW,GAAA,OACtB,KACA,EAAAA,OAAA,EACA,IACiB,KAAA;AACjB,EAAA,MAAM,IAAO,GAAAA,OAAA,CAAM,GAAI,CAAA,CAAC,MAAM,KAAW,MAAA;AAAA,IACvC,KAAA;AAAA,IACA,IAAA;AAAA,GACA,CAAA,CAAA,CAAA;AAEF,EAAM,MAAA,SAAA,GAAY,OAAO,GAA8C,KAAA;AACrE,IAAA,MAAMC,WAA+B,EAAC,CAAA;AACtC,IAAA,OAAO,IAAM,EAAA;AACX,MAAM,MAAA,IAAA,GAAO,KAAK,GAAI,EAAA,CAAA;AACtB,MAAA,IAAI,CAAC,IAAA;AAAM,QAAA,OAAO,IAAIA,QAAO,CAAA,CAAA;AAC7B,MAAM,MAAA,CAAC,OAAO,MAAM,CAAA,GAAI,MAAM,KAAM,CAAA,IAAI,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AACnD,MAAAA,SAAQ,IAAK,CAAA;AAAA,QACX,KAAA;AAAA,QACA,MAAA;AAAA,QACA,OAAO,IAAK,CAAA,KAAA;AAAA,OACb,CAAA,CAAA;AAAA,KACH;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,MAAA,GAASC,UAAK,CAAA,CAAA,EAAG,KAAK,CAAA,CAAE,IAAI,MAAM,IAAI,OAAQ,CAAA,SAAS,CAAC,CAAA,CAAA;AAE9D,EAAA,MAAM,WAAe,GAAA,MAAM,OAAQ,CAAA,GAAA,CAAI,MAAM,CAAA,CAAA;AAC7C,EAAM,MAAA,CAAC,MAAQ,EAAA,OAAO,CAAI,GAAAC,UAAA;AAAA,IACxBC,WAAK,WAAY,CAAA,IAAA,EAAQ,EAAA,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA;AAAA,IACrC,CAAA,CAAA,KAAK,CAAC,CAAC,CAAE,CAAA,KAAA;AAAA,GACX,CAAA;AACA,EAAI,IAAA,MAAA,CAAO,SAAS,CAAG,EAAA;AACrB,IAAA,MAAM,IAAI,cAAe,CAAA,MAAA,CAAO,IAAI,CAAS,KAAA,KAAA,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AAAA,GAC3D;AACA,EAAA,OAAO,OAAQ,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,MAAM,CAAA,CAAA;AAClC,EAAA;AAuCA,eAAsB,IAEpB,QAAa,EAAA;AACb,EAAA,MAAM,OAAU,GAAAC,aAAA,CAAQ,QAAQ,CAAA,GAC5B,SAAS,GAAI,CAAA,CAAA,CAAA,KAAK,CAAC,IAAA,EAAM,CAAC,CAAyB,CACnD,GAAA,MAAA,CAAO,QAAQ,QAAQ,CAAA,CAAA;AAE3B,EAAM,MAAA,OAAA,GAAU,MAAM,OAAQ,CAAA,GAAA;AAAA,IAC5B,OAAQ,CAAA,GAAA;AAAA,MAAI,CAAC,CAAC,GAAK,EAAA,KAAK,MACtB,KACG,CAAA,IAAA,CAAK,CAAW,MAAA,MAAA,EAAE,MAAQ,EAAA,GAAA,EAAK,MAAM,GAAI,EAAA,CAAE,EAC3C,KAAM,CAAA,CAAA,GAAA,MAAQ,EAAE,MAAQ,EAAA,IAAA,EAAM,GAAK,EAAA,GAAA,EAAM,CAAA,CAAA;AAAA,KAC9C;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,MAAO,CAAA,CAAA,CAAA,KAAK,EAAE,GAAG,CAAA,CAAA;AAC5C,EAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,IAAA,MAAM,IAAI,cAAe,CAAA,UAAA,CAAW,IAAI,CAAK,CAAA,KAAA,CAAA,CAAE,GAAG,CAAC,CAAA,CAAA;AAAA,GACrD;AAEA,EAAI,IAAAA,aAAA,CAAQ,QAAQ,CAAG,EAAA;AACrB,IAAA,OAAO,OAAQ,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,MAAM,CAAA,CAAA;AAAA,GAGlC;AAEA,EAAA,OAAO,OAAQ,CAAA,MAAA;AAAA,IACb,CAAC,KAAK,IAAU,MAAA;AAAA,MACd,GAAG,GAAA;AAAA,MACH,CAAC,IAAA,CAAK,GAAI,GAAG,IAAK,CAAA,MAAA;AAAA,KACpB,CAAA;AAAA,IACA,EAAC;AAAA,GACH,CAAA;AACF,CAAA;AAMa,MAAA,KAAA,GAAQ,OACnB,OAAA,EAKA,IACuB,KAAA;AACvB,EAAM,MAAA,KAAA,GAAQ,SAAS,KAAS,IAAA,CAAA,CAAA;AAChC,EAAA,MAAM,QAAQ,OAAS,EAAA,KAAA,CAAA;AACvB,EAAM,MAAA,OAAA,GAAU,SAAS,OAAW,IAAA,IAAA,CAAA;AACpC,EAAA,KAAA,MAAW,CAAK,IAAAC,WAAA,CAAM,CAAG,EAAA,KAAK,CAAG,EAAA;AAC/B,IAAM,MAAA,CAAC,KAAK,MAAM,CAAA,GAAK,MAAM,KAAM,CAAA,IAAI,CAAE,CAAA,CAACC,IAAa,KAAA;AACrD,MAAM,MAAA,EAAE,SAASA,IAAI,EAAA,CAAA;AAAA,KACtB,CAAA,CAAA;AACD,IAAA,IAAI,CAAC,GAAA;AAAK,MAAO,OAAA,MAAA,CAAA;AACjB,IAAA,IAAI,GAAI,CAAA,OAAA;AAAS,MAAA,MAAM,GAAI,CAAA,OAAA,CAAA;AAC3B,IAAA,IAAI,CAAM,KAAA,KAAA;AAAO,MAAM,MAAA,GAAA,CAAA;AACvB,IAAI,IAAA,KAAA;AAAO,MAAA,MAAM,MAAM,KAAK,CAAA,CAAA;AAC5B,IAAI,IAAA,OAAA;AAAS,MAAM,MAAA,KAAA,CAAM,OAAQ,CAAA,CAAC,CAAC,CAAA,CAAA;AAAA,GACrC;AAKA,EAAO,OAAA,KAAA,CAAA,CAAA;AACT,EAAA;AAKa,MAAA,KAAA,GAAQ,CAAC,YAAyB,KAAA;AAC7C,EAAA,OAAO,IAAI,OAAc,CAAA,CAAA,GAAA,KAAO,UAAW,CAAA,GAAA,EAAK,YAAY,CAAC,CAAA,CAAA;AAC/D,EAAA;AAOa,MAAA,KAAA,GAAQ,CACnB,IACG,KAAA;AACH,EAAA,OAAO,IACF,IAG2C,KAAA;AAC9C,IAAI,IAAA;AACF,MAAM,MAAA,MAAA,GAAS,IAAK,CAAA,GAAG,IAAI,CAAA,CAAA;AAC3B,MAAI,IAAAC,eAAA,CAAU,MAAM,CAAG,EAAA;AACrB,QAAA,OAAO,MACJ,CAAA,IAAA,CAAK,CAAS,KAAA,KAAA,CAAC,KAAW,CAAA,EAAA,KAAK,CAAC,CAAA,CAChC,KAAM,CAAA,CAAA,GAAA,KAAO,CAAC,GAAA,EAAK,MAAS,CAAC,CAAA,CAAA;AAAA,OAGlC;AACA,MAAO,OAAA,CAAC,QAAW,MAAM,CAAA,CAAA;AAAA,aAGlB,GAAP,EAAA;AACA,MAAO,OAAA,CAAC,KAAY,KAAS,CAAA,CAAA,CAAA;AAAA,KAG/B;AAAA,GACF,CAAA;AACF,EAAA;AAQa,MAAA,KAAA,GAAQ,CACnB,IAAA,EACA,WAGuC,KAAA;AACvC,EAAM,MAAA,MAAA,GAAS,CAAC,GAAa,KAAA;AAC3B,IAAI,IAAA,WAAA,IAAe,CAAC,WAAA,CAAY,GAAG,CAAA;AAAG,MAAM,MAAA,GAAA,CAAA;AAC5C,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT,CAAA;AACA,EAAMA,MAAAA,UAAAA,GAAY,CAAC,MAAA,KACjB,MAAkB,YAAA,OAAA,CAAA;AACpB,EAAI,IAAA;AACF,IAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AACpB,IAAA,OAAOA,WAAU,MAAM,CAAA,GAAI,MAAO,CAAA,KAAA,CAAM,MAAM,CAAI,GAAA,MAAA,CAAA;AAAA,WAC3C,GAAP,EAAA;AACA,IAAA,OAAO,OAAO,GAAG,CAAA,CAAA;AAAA,GACnB;AACF;;;;;;;;;;;;;"}