trie-typed 2.5.2 → 2.6.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 (63) hide show
  1. package/dist/cjs/index.cjs +106 -0
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +106 -0
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +106 -0
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +106 -0
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
  10. package/dist/types/data-structures/base/linear-base.d.ts +6 -0
  11. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +86 -2
  12. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +98 -0
  13. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +191 -15
  14. package/dist/types/data-structures/binary-tree/bst.d.ts +171 -3
  15. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +136 -8
  16. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +42 -0
  17. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1061 -167
  18. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1232 -355
  19. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +916 -194
  20. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1078 -141
  21. package/dist/types/data-structures/graph/directed-graph.d.ts +70 -0
  22. package/dist/types/data-structures/graph/undirected-graph.d.ts +63 -0
  23. package/dist/types/data-structures/hash/hash-map.d.ts +84 -6
  24. package/dist/types/data-structures/heap/heap.d.ts +140 -12
  25. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +150 -2
  26. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +106 -1
  27. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +126 -0
  28. package/dist/types/data-structures/matrix/matrix.d.ts +56 -0
  29. package/dist/types/data-structures/queue/deque.d.ts +171 -0
  30. package/dist/types/data-structures/queue/queue.d.ts +97 -0
  31. package/dist/types/data-structures/stack/stack.d.ts +72 -2
  32. package/dist/types/data-structures/trie/trie.d.ts +84 -0
  33. package/dist/types/interfaces/binary-tree.d.ts +2 -3
  34. package/dist/umd/trie-typed.js +106 -0
  35. package/dist/umd/trie-typed.js.map +1 -1
  36. package/dist/umd/trie-typed.min.js +1 -1
  37. package/dist/umd/trie-typed.min.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/data-structures/base/iterable-element-base.ts +32 -0
  40. package/src/data-structures/base/linear-base.ts +11 -0
  41. package/src/data-structures/binary-tree/avl-tree.ts +88 -5
  42. package/src/data-structures/binary-tree/binary-indexed-tree.ts +98 -0
  43. package/src/data-structures/binary-tree/binary-tree.ts +242 -81
  44. package/src/data-structures/binary-tree/bst.ts +173 -7
  45. package/src/data-structures/binary-tree/red-black-tree.ts +139 -15
  46. package/src/data-structures/binary-tree/segment-tree.ts +42 -0
  47. package/src/data-structures/binary-tree/tree-map.ts +948 -36
  48. package/src/data-structures/binary-tree/tree-multi-map.ts +893 -13
  49. package/src/data-structures/binary-tree/tree-multi-set.ts +761 -33
  50. package/src/data-structures/binary-tree/tree-set.ts +1260 -251
  51. package/src/data-structures/graph/directed-graph.ts +71 -1
  52. package/src/data-structures/graph/undirected-graph.ts +64 -1
  53. package/src/data-structures/hash/hash-map.ts +100 -12
  54. package/src/data-structures/heap/heap.ts +149 -19
  55. package/src/data-structures/linked-list/doubly-linked-list.ts +178 -2
  56. package/src/data-structures/linked-list/singly-linked-list.ts +106 -1
  57. package/src/data-structures/linked-list/skip-linked-list.ts +126 -0
  58. package/src/data-structures/matrix/matrix.ts +56 -0
  59. package/src/data-structures/queue/deque.ts +187 -0
  60. package/src/data-structures/queue/queue.ts +109 -0
  61. package/src/data-structures/stack/stack.ts +75 -5
  62. package/src/data-structures/trie/trie.ts +84 -0
  63. package/src/interfaces/binary-tree.ts +1 -9
@@ -245,6 +245,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
245
245
 
246
246
 
247
247
 
248
+
249
+
250
+
251
+
252
+
253
+
254
+
248
255
 
249
256
 
250
257
 
@@ -299,6 +306,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
299
306
 
300
307
 
301
308
 
309
+
310
+
311
+
312
+
313
+
314
+
315
+
302
316
 
303
317
 
304
318
 
@@ -348,6 +362,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
348
362
 
349
363
 
350
364
 
365
+
366
+
367
+
368
+
369
+
370
+
371
+
351
372
 
352
373
 
353
374
 
@@ -393,6 +414,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
393
414
 
394
415
 
395
416
 
417
+
418
+
419
+
420
+
421
+
422
+
423
+
396
424
 
397
425
 
398
426
 
@@ -437,6 +465,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
437
465
 
438
466
 
439
467
 
468
+
469
+
470
+
471
+
472
+
473
+
474
+
440
475
 
441
476
 
442
477
 
@@ -484,6 +519,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
484
519
 
485
520
 
486
521
 
522
+
523
+
524
+
525
+
526
+
527
+
528
+
487
529
 
488
530
 
489
531
 
@@ -556,6 +598,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
556
598
 
557
599
 
558
600
 
601
+
602
+
603
+
604
+
605
+
606
+
607
+
559
608
 
560
609
 
561
610
 
@@ -611,6 +660,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
611
660
 
612
661
 
613
662
 
663
+
664
+
665
+
666
+
667
+
668
+
669
+
614
670
 
615
671
 
616
672
 
@@ -660,6 +716,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
660
716
 
661
717
 
662
718
 
719
+
720
+
721
+
722
+
723
+
724
+
725
+
663
726
 
664
727
 
665
728
 
@@ -709,6 +772,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
709
772
 
710
773
 
711
774
 
775
+
776
+
777
+
778
+
779
+
780
+
781
+
712
782
 
713
783
 
714
784
 
@@ -755,6 +825,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
755
825
 
756
826
 
757
827
 
828
+
829
+
830
+
831
+
832
+
833
+
834
+
758
835
 
759
836
 
760
837
 
@@ -796,6 +873,13 @@ export declare class Trie<R = any> extends IterableElementBase<string, R> {
796
873
 
797
874
 
798
875
 
876
+
877
+
878
+
879
+
880
+
881
+
882
+
799
883
 
800
884
 
801
885
 
@@ -1,5 +1,5 @@
1
1
  import { BinaryTreeNode } from '../data-structures';
2
- import type { BinaryTreeDeleteResult, BinaryTreeOptions, BTNRep, DFSOrderPattern, EntryCallback, IterationType, NodeCallback, NodePredicate, OptNodeOrNull, ReduceEntryCallback, ToEntryFn } from '../types';
2
+ import type { BinaryTreeOptions, BTNRep, DFSOrderPattern, EntryCallback, IterationType, NodeCallback, NodePredicate, OptNodeOrNull, ReduceEntryCallback, ToEntryFn } from '../types';
3
3
  /**
4
4
  * Public, implementation-agnostic binary tree API.
5
5
  * K = key, V = value, R = raw/record used with toEntryFn (optional).
@@ -19,7 +19,7 @@ export interface IBinaryTree<K = any, V = any, R = any> {
19
19
  add(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V, count?: number): boolean;
20
20
  set(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V, count?: number): boolean;
21
21
  addMany(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): boolean[];
22
- delete(keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
22
+ delete(keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): boolean;
23
23
  clear(): void;
24
24
  isEmpty(): boolean;
25
25
  get(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): V | undefined;
@@ -56,5 +56,4 @@ export interface IBinaryTree<K = any, V = any, R = any> {
56
56
  filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): this;
57
57
  map<MK = K, MV = V, MR = any>(callback: EntryCallback<K, V | undefined, [MK, MV]>, options?: Partial<BinaryTreeOptions<MK, MV, MR>>, thisArg?: unknown): IBinaryTree<MK, MV, MR>;
58
58
  merge(anotherTree: IBinaryTree<K, V, R>): void;
59
- refill(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): void;
60
59
  }
@@ -231,6 +231,35 @@ var trieTyped = (() => {
231
231
  for (const ele of this) if (ele === element) return true;
232
232
  return false;
233
233
  }
234
+ /**
235
+ * Check whether a value exists (Array-compatible alias for `has`).
236
+ * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1).
237
+ * @param element - Element to search for (uses `===`).
238
+ * @returns `true` if found.
239
+ */
240
+ includes(element) {
241
+ return this.has(element);
242
+ }
243
+ /**
244
+ * Return an iterator of `[index, value]` pairs (Array-compatible).
245
+ * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1) per step.
246
+ */
247
+ *entries() {
248
+ let index = 0;
249
+ for (const value of this) {
250
+ yield [index++, value];
251
+ }
252
+ }
253
+ /**
254
+ * Return an iterator of numeric indices (Array-compatible).
255
+ * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1) per step.
256
+ */
257
+ *keys() {
258
+ let index = 0;
259
+ for (const _ of this) {
260
+ yield index++;
261
+ }
262
+ }
234
263
  /**
235
264
  * Reduces all elements to a single accumulated value.
236
265
  *
@@ -454,6 +483,13 @@ var trieTyped = (() => {
454
483
 
455
484
 
456
485
 
486
+
487
+
488
+
489
+
490
+
491
+
492
+
457
493
 
458
494
 
459
495
 
@@ -526,6 +562,13 @@ var trieTyped = (() => {
526
562
 
527
563
 
528
564
 
565
+
566
+
567
+
568
+
569
+
570
+
571
+
529
572
 
530
573
 
531
574
 
@@ -585,6 +628,13 @@ var trieTyped = (() => {
585
628
 
586
629
 
587
630
 
631
+
632
+
633
+
634
+
635
+
636
+
637
+
588
638
 
589
639
 
590
640
 
@@ -639,6 +689,13 @@ var trieTyped = (() => {
639
689
 
640
690
 
641
691
 
692
+
693
+
694
+
695
+
696
+
697
+
698
+
642
699
 
643
700
 
644
701
 
@@ -685,6 +742,13 @@ var trieTyped = (() => {
685
742
 
686
743
 
687
744
 
745
+
746
+
747
+
748
+
749
+
750
+
751
+
688
752
 
689
753
 
690
754
 
@@ -735,6 +799,13 @@ var trieTyped = (() => {
735
799
 
736
800
 
737
801
 
802
+
803
+
804
+
805
+
806
+
807
+
808
+
738
809
 
739
810
 
740
811
 
@@ -867,6 +938,13 @@ var trieTyped = (() => {
867
938
 
868
939
 
869
940
 
941
+
942
+
943
+
944
+
945
+
946
+
947
+
870
948
 
871
949
 
872
950
 
@@ -943,6 +1021,13 @@ var trieTyped = (() => {
943
1021
 
944
1022
 
945
1023
 
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
946
1031
 
947
1032
 
948
1033
 
@@ -1002,6 +1087,13 @@ var trieTyped = (() => {
1002
1087
 
1003
1088
 
1004
1089
 
1090
+
1091
+
1092
+
1093
+
1094
+
1095
+
1096
+
1005
1097
 
1006
1098
 
1007
1099
 
@@ -1079,6 +1171,13 @@ var trieTyped = (() => {
1079
1171
 
1080
1172
 
1081
1173
 
1174
+
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+
1082
1181
 
1083
1182
 
1084
1183
 
@@ -1129,6 +1228,13 @@ var trieTyped = (() => {
1129
1228
 
1130
1229
 
1131
1230
 
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1132
1238
 
1133
1239
 
1134
1240
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/common/error.ts","../../src/common/index.ts","../../src/data-structures/base/iterable-element-base.ts","../../src/data-structures/trie/trie.ts"],"sourcesContent":["/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nexport * from './data-structures/trie';\nexport * from './types/data-structures/trie';\nexport * from './types/common';\nexport * from './types/utils';\nexport * from './common';","/**\n * Centralized error dispatch.\n * All library errors go through this function for consistent messaging and easy grep.\n * @remarks Always throws — data structure errors are never recoverable.\n * @param ErrorClass - The error constructor (Error, TypeError, RangeError, etc.)\n * @param message - The error message.\n */\nexport function raise(\n ErrorClass: new (msg: string) => Error,\n message: string\n): never {\n throw new ErrorClass(message);\n}\n\n/**\n * Centralized error message templates.\n * Keep using native Error/TypeError/RangeError — this only standardizes messages.\n */\nexport const ERR = {\n // Range / index\n indexOutOfRange: (index: number, min: number, max: number, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Index ${index} is out of range [${min}, ${max}].`,\n\n invalidIndex: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Index must be an integer.`,\n\n // Type / argument\n invalidArgument: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n comparatorRequired: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Comparator is required for non-number/non-string/non-Date keys.`,\n\n invalidKey: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n notAFunction: (name: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${name} must be a function.`,\n\n invalidEntry: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Each entry must be a [key, value] tuple.`,\n\n invalidNaN: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}NaN is not a valid key.`,\n\n invalidDate: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Invalid Date key.`,\n\n reduceEmpty: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Reduce of empty structure with no initial value.`,\n\n callbackReturnType: (expected: string, got: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Callback must return ${expected}; got ${got}.`,\n\n // State / operation\n invalidOperation: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n // Matrix\n matrixDimensionMismatch: (op: string) =>\n `Matrix: Dimensions must be compatible for ${op}.`,\n\n matrixSingular: () =>\n 'Matrix: Singular matrix, inverse does not exist.',\n\n matrixNotSquare: () =>\n 'Matrix: Must be square for inversion.',\n\n matrixNotRectangular: () =>\n 'Matrix: Must be rectangular for transposition.',\n\n matrixRowMismatch: (expected: number, got: number) =>\n `Matrix: Expected row length ${expected}, but got ${got}.`,\n\n // Order statistic\n orderStatisticNotEnabled: (method: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${method}() requires enableOrderStatistic: true.`\n} as const;\n","export { ERR, raise } from './error';\n\nexport enum DFSOperation {\n VISIT = 0,\n PROCESS = 1\n}\n\nexport class Range<K> {\n constructor(\n public low: K,\n public high: K,\n public includeLow: boolean = true,\n public includeHigh: boolean = true\n ) {\n // if (!(isComparable(low) && isComparable(high))) throw new RangeError('low or high is not comparable');\n // if (low > high) throw new RangeError('low must be less than or equal to high');\n }\n\n // Determine whether a key is within the range\n isInRange(key: K, comparator: (a: K, b: K) => number): boolean {\n const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;\n const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;\n return lowCheck && highCheck;\n }\n}\n","import type { ElementCallback, IterableElementBaseOptions, ReduceElementCallback } from '../../types';\nimport { raise } from '../../common';\n\n/**\n * Base class that makes a data structure iterable and provides common\n * element-wise utilities (e.g., map/filter/reduce/find).\n *\n * @template E The public element type yielded by the structure.\n * @template R The underlying \"raw\" element type used internally or by converters.\n *\n * @remarks\n * This class implements the JavaScript iteration protocol (via `Symbol.iterator`)\n * and offers array-like helpers with predictable time/space complexity.\n */\nexport abstract class IterableElementBase<E, R> implements Iterable<E> {\n /**\n * Create a new iterable base.\n *\n * @param options Optional behavior overrides. When provided, a `toElementFn`\n * is used to convert a raw element (`R`) into a public element (`E`).\n *\n * @remarks\n * Time O(1), Space O(1).\n */\n protected constructor(options?: IterableElementBaseOptions<E, R>) {\n if (options) {\n const { toElementFn } = options;\n if (typeof toElementFn === 'function') this._toElementFn = toElementFn;\n else if (toElementFn) raise(TypeError, 'toElementFn must be a function type');\n }\n }\n\n /**\n * The converter used to transform a raw element (`R`) into a public element (`E`).\n *\n * @remarks\n * Time O(1), Space O(1).\n */\n protected _toElementFn?: (rawElement: R) => E;\n\n /**\n * Exposes the current `toElementFn`, if configured.\n *\n * @returns The converter function or `undefined` when not set.\n * @remarks\n * Time O(1), Space O(1).\n */\n get toElementFn(): ((rawElement: R) => E) | undefined {\n return this._toElementFn;\n }\n\n /**\n * Returns an iterator over the structure's elements.\n *\n * @param args Optional iterator arguments forwarded to the internal iterator.\n * @returns An `IterableIterator<E>` that yields the elements in traversal order.\n *\n * @remarks\n * Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space.\n */\n *[Symbol.iterator](...args: unknown[]): IterableIterator<E> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Returns an iterator over the values (alias of the default iterator).\n *\n * @returns An `IterableIterator<E>` over all elements.\n * @remarks\n * Creating the iterator is O(1); full iteration is Time O(n), Space O(1).\n */\n *values(): IterableIterator<E> {\n for (const item of this) yield item;\n }\n\n /**\n * Tests whether all elements satisfy the predicate.\n *\n * @template TReturn\n * @param predicate Function invoked for each element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns `true` if every element passes; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early when the first failure is found. Space O(1).\n */\n every(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): boolean {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (!predicate(item, index++, this)) return false;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (!fn.call(thisArg, item, index++, this)) return false;\n }\n }\n return true;\n }\n\n /**\n * Tests whether at least one element satisfies the predicate.\n *\n * @param predicate Function invoked for each element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns `true` if any element passes; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early on first success. Space O(1).\n */\n some(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): boolean {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (predicate(item, index++, this)) return true;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (fn.call(thisArg, item, index++, this)) return true;\n }\n }\n return false;\n }\n\n /**\n * Invokes a callback for each element in iteration order.\n *\n * @param callbackfn Function invoked per element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns `void`.\n *\n * @remarks\n * Time O(n), Space O(1).\n */\n forEach(callbackfn: ElementCallback<E, R, void>, thisArg?: unknown): void {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n callbackfn(item, index++, this);\n } else {\n const fn = callbackfn as (this: unknown, v: E, i: number, self: this) => void;\n fn.call(thisArg, item, index++, this);\n }\n }\n }\n\n /**\n * Finds the first element that satisfies the predicate and returns it.\n *\n * @overload\n * Finds the first element of type `S` (a subtype of `E`) that satisfies the predicate and returns it.\n * @template S\n * @param predicate Type-guard predicate: `(value, index, self) => value is S`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns The matched element typed as `S`, or `undefined` if not found.\n *\n * @overload\n * @param predicate Boolean predicate: `(value, index, self) => boolean`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns The first matching element as `E`, or `undefined` if not found.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early on the first match. Space O(1).\n */\n find<S extends E>(predicate: ElementCallback<E, R, S>, thisArg?: unknown): S | undefined;\n find(predicate: ElementCallback<E, R, unknown>, thisArg?: unknown): E | undefined;\n\n // Implementation signature\n find(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): E | undefined {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (predicate(item, index++, this)) return item;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (fn.call(thisArg, item, index++, this)) return item;\n }\n }\n return;\n }\n\n /**\n * Checks whether a strictly-equal element exists in the structure.\n *\n * @param element The element to test with `===` equality.\n * @returns `true` if an equal element is found; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case. Space O(1).\n */\n has(element: E): boolean {\n for (const ele of this) if (ele === element) return true;\n return false;\n }\n\n reduce(callbackfn: ReduceElementCallback<E, R>): E;\n reduce(callbackfn: ReduceElementCallback<E, R>, initialValue: E): E;\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue: U): U;\n\n /**\n * Reduces all elements to a single accumulated value.\n *\n * @overload\n * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`. The first element is used as the initial accumulator.\n * @returns The final accumulated value typed as `E`.\n *\n * @overload\n * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`.\n * @param initialValue The initial accumulator value of type `E`.\n * @returns The final accumulated value typed as `E`.\n *\n * @overload\n * @template U The accumulator type when it differs from `E`.\n * @param callbackfn Reducer of signature `(acc: U, value, index, self) => U`.\n * @param initialValue The initial accumulator value of type `U`.\n * @returns The final accumulated value typed as `U`.\n *\n * @remarks\n * Time O(n), Space O(1). Throws if called on an empty structure without `initialValue`.\n */\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue?: U): U {\n let index = 0;\n const iter = this[Symbol.iterator]();\n let acc: U;\n\n if (arguments.length >= 2) {\n acc = initialValue as U;\n } else {\n const first = iter.next();\n if (first.done) raise(TypeError, 'Reduce of empty structure with no initial value');\n acc = first.value as unknown as U;\n index = 1;\n }\n\n for (const value of iter as unknown as Iterable<E>) {\n acc = callbackfn(acc, value, index++, this);\n }\n return acc;\n }\n\n /**\n * Materializes the elements into a new array.\n *\n * @returns A shallow array copy of the iteration order.\n * @remarks\n * Time O(n), Space O(n).\n */\n toArray(): E[] {\n return [...this];\n }\n\n /**\n * Returns a representation of the structure suitable for quick visualization.\n * Defaults to an array of elements; subclasses may override to provide richer visuals.\n *\n * @returns A visual representation (array by default).\n * @remarks\n * Time O(n), Space O(n).\n */\n toVisual(): E[] {\n return [...this];\n }\n\n /**\n * Prints `toVisual()` to the console. Intended for quick debugging.\n *\n * @returns `void`.\n * @remarks\n * Time O(n) due to materialization, Space O(n) for the intermediate representation.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n /**\n * Indicates whether the structure currently contains no elements.\n *\n * @returns `true` if empty; otherwise `false`.\n * @remarks\n * Expected Time O(1), Space O(1) for most implementations.\n */\n abstract isEmpty(): boolean;\n\n /**\n * Removes all elements from the structure.\n *\n * @returns `void`.\n * @remarks\n * Expected Time O(1) or O(n) depending on the implementation; Space O(1).\n */\n abstract clear(): void;\n\n /**\n * Creates a structural copy with the same element values and configuration.\n *\n * @returns A clone of the current instance (same concrete type).\n * @remarks\n * Expected Time O(n) to copy elements; Space O(n).\n */\n abstract clone(): this;\n\n /**\n * Maps each element to a new element and returns a new iterable structure.\n *\n * @template EM The mapped element type.\n * @template RM The mapped raw element type used internally by the target structure.\n * @param callback Function with signature `(value, index, self) => mapped`.\n * @param options Optional options for the returned structure, including its `toElementFn`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns A new `IterableElementBase<EM, RM>` containing mapped elements.\n *\n * @remarks\n * Time O(n), Space O(n).\n */\n abstract map<EM, RM>(\n callback: ElementCallback<E, R, EM>,\n options?: IterableElementBaseOptions<EM, RM>,\n thisArg?: unknown\n ): IterableElementBase<EM, RM>;\n\n /**\n * Maps each element to the same element type and returns the same concrete structure type.\n *\n * @param callback Function with signature `(value, index, self) => mappedValue`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns A new instance of the same concrete type with mapped elements.\n *\n * @remarks\n * Time O(n), Space O(n).\n */\n abstract mapSame(callback: ElementCallback<E, R, E>, thisArg?: unknown): this;\n\n /**\n * Filters elements using the provided predicate and returns the same concrete structure type.\n *\n * @param predicate Function with signature `(value, index, self) => boolean`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns A new instance of the same concrete type containing only elements that pass the predicate.\n *\n * @remarks\n * Time O(n), Space O(k) where `k` is the number of kept elements.\n */\n abstract filter(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): this;\n\n /**\n * Internal iterator factory used by the default iterator.\n *\n * @param args Optional iterator arguments.\n * @returns An iterator over elements.\n *\n * @remarks\n * Implementations should yield in O(1) per element with O(1) extra space when possible.\n */\n protected abstract _getIterator(...args: unknown[]): IterableIterator<E>;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { ElementCallback, TrieOptions } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { ERR, raise } from '../../common';\n\n/**\n * Node used by Trie to store one character and its children.\n * @remarks Time O(1), Space O(1)\n */\nexport class TrieNode {\n /**\n * Create a Trie node with a character key.\n * @remarks Time O(1), Space O(1)\n * @returns New TrieNode instance.\n */\n\n constructor(key: string) {\n this._key = key;\n this._isEnd = false;\n this._children = new Map<string, TrieNode>();\n }\n\n protected _key: string;\n\n /**\n * Get the character key of this node.\n * @remarks Time O(1), Space O(1)\n * @returns Character key string.\n */\n\n get key(): string {\n return this._key;\n }\n\n /**\n * Set the character key of this node.\n * @remarks Time O(1), Space O(1)\n * @param value - New character key.\n * @returns void\n */\n\n set key(value: string) {\n this._key = value;\n }\n\n protected _children: Map<string, TrieNode>;\n\n /**\n * Get the child map of this node.\n * @remarks Time O(1), Space O(1)\n * @returns Map from character to child node.\n */\n\n get children(): Map<string, TrieNode> {\n return this._children;\n }\n\n /**\n * Replace the child map of this node.\n * @remarks Time O(1), Space O(1)\n * @param value - New map of character → node.\n * @returns void\n */\n\n set children(value: Map<string, TrieNode>) {\n this._children = value;\n }\n\n protected _isEnd: boolean;\n\n /**\n * Check whether this node marks the end of a word.\n * @remarks Time O(1), Space O(1)\n * @returns True if this node ends a word.\n */\n\n get isEnd(): boolean {\n return this._isEnd;\n }\n\n /**\n * Mark this node as the end of a word or not.\n * @remarks Time O(1), Space O(1)\n * @param value - Whether this node ends a word.\n * @returns void\n */\n\n set isEnd(value: boolean) {\n this._isEnd = value;\n }\n}\n\n/**\n * Prefix tree (Trie) for fast prefix queries and word storage.\n * @remarks Time O(1), Space O(1)\n * @template R\n * 1. Node Structure: Each node in a Trie represents a string (or a part of a string). The root node typically represents an empty string.\n * 2. Child Node Relationship: Each node's children represent the strings that can be formed by adding one character to the string at the current node. For example, if a node represents the string 'ca', one of its children might represent 'cat'.\n * 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.\n * 4. Space Efficiency: Trie can store a large number of strings very space-efficiently, especially when these strings share common prefixes.\n * 5. Autocomplete and Prediction: Trie can be used for implementing autocomplete and word prediction features, as it can quickly find all strings with a common prefix.\n * 6. Sorting: Trie can be used to sort a set of strings in alphabetical order.\n * 7. String Retrieval: For example, searching for a specific string in a large set of strings.\n * 8. Autocomplete: Providing recommended words or phrases as a user types.\n * 9. Spell Check: Checking the spelling of words.\n * 10. IP Routing: Used in certain types of IP routing algorithms.\n * 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.\n * @example\n * // Trie isPrefix and isAbsolutePrefix checks\n * const trie = new Trie(['tree', 'trial', 'trick', 'trip', 'trie']);\n *\n * // Check if string is a prefix of any word\n * console.log(trie.hasPrefix('tri')); // true;\n * console.log(trie.hasPrefix('tr')); // true;\n * console.log(trie.hasPrefix('xyz')); // false;\n *\n * // Check if string is an absolute prefix (not a complete word)\n * console.log(trie.hasPurePrefix('tri')); // true;\n * console.log(trie.hasPurePrefix('tree')); // false; // 'tree' is a complete word\n *\n * // Verify size\n * console.log(trie.size); // 5;\n * @example\n * // Trie for autocomplete search index\n * // Trie is perfect for autocomplete: O(m + k) where m is prefix length, k is results\n * const searchIndex = new Trie(['typescript', 'javascript', 'python', 'java', 'rust', 'ruby', 'golang', 'kotlin']);\n *\n * // User types 'j' - get all suggestions\n * const jResults = searchIndex.getWords('j');\n * console.log(jResults); // contains 'javascript';\n * console.log(jResults); // contains 'java';\n * console.log(jResults.length); // 2;\n *\n * // User types 'ja' - get more specific suggestions\n * const jaResults = searchIndex.getWords('ja');\n * console.log(jaResults); // contains 'javascript';\n * console.log(jaResults); // contains 'java';\n * console.log(jaResults.length); // 2;\n *\n * // User types 'jav' - even more specific\n * const javResults = searchIndex.getWords('jav');\n * console.log(javResults); // contains 'javascript';\n * console.log(javResults); // contains 'java';\n * console.log(javResults.length); // 2;\n *\n * // Check for common prefix\n *\n * console.log(searchIndex.hasCommonPrefix('ja')); // false; // Not all words start with 'ja'\n *\n * // Total words in index\n * console.log(searchIndex.size); // 8;\n *\n * // Get height (depth of tree)\n * const height = searchIndex.getHeight();\n * console.log(typeof height); // 'number';\n * @example\n * // Dictionary: Case-insensitive word lookup\n * // Create a case-insensitive dictionary\n * const dictionary = new Trie<string>([], { caseSensitive: false });\n *\n * // Add words with mixed casing\n * dictionary.add('Hello');\n * dictionary.add('WORLD');\n * dictionary.add('JavaScript');\n *\n * // Test lookups with different casings\n * console.log(dictionary.has('hello')); // true;\n * console.log(dictionary.has('HELLO')); // true;\n * console.log(dictionary.has('Hello')); // true;\n * console.log(dictionary.has('javascript')); // true;\n * console.log(dictionary.has('JAVASCRIPT')); // true;\n * @example\n * // File System Path Operations\n * const fileSystem = new Trie<string>([\n * '/home/user/documents/file1.txt',\n * '/home/user/documents/file2.txt',\n * '/home/user/pictures/photo.jpg',\n * '/home/user/pictures/vacation/',\n * '/home/user/downloads'\n * ]);\n *\n * // Find common directory prefix\n * console.log(fileSystem.getLongestCommonPrefix()); // '/home/user/';\n *\n * // List all files in a directory\n * const documentsFiles = fileSystem.getWords('/home/user/documents/');\n * console.log(documentsFiles); // ['/home/user/documents/file1.txt', '/home/user/documents/file2.txt'];\n * @example\n * // IP Address Routing Table\n * // Add IP address prefixes and their corresponding routes\n * const routes = {\n * '192.168.1': 'LAN_SUBNET_1',\n * '192.168.2': 'LAN_SUBNET_2',\n * '10.0.0': 'PRIVATE_NETWORK_1',\n * '10.0.1': 'PRIVATE_NETWORK_2'\n * };\n *\n * const ipRoutingTable = new Trie<string>(Object.keys(routes));\n *\n * // Check IP address prefix matching\n * console.log(ipRoutingTable.hasPrefix('192.168.1')); // true;\n * console.log(ipRoutingTable.hasPrefix('192.168.2')); // true;\n *\n * // Validate IP address belongs to subnet\n * const ip = '192.168.1.100';\n * const subnet = ip.split('.').slice(0, 3).join('.');\n * console.log(ipRoutingTable.hasPrefix(subnet)); // true;\n */\nexport class Trie<R = any> extends IterableElementBase<string, R> {\n /**\n * Create a Trie and optionally bulk-insert words.\n * @remarks Time O(totalChars), Space O(totalChars)\n * @param [words] - Iterable of strings (or raw records if toElementFn is provided).\n * @param [options] - Options such as toElementFn and caseSensitive.\n * @returns New Trie instance.\n */\n\n constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {\n super(options);\n if (options) {\n const { caseSensitive } = options;\n if (caseSensitive !== undefined) this._caseSensitive = caseSensitive;\n }\n if (words) {\n this.addMany(words);\n }\n }\n\n protected _size: number = 0;\n\n /**\n * Get the number of stored words.\n * @remarks Time O(1), Space O(1)\n * @returns Word count.\n */\n\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean = true;\n\n /**\n * Get whether comparisons are case-sensitive.\n * @remarks Time O(1), Space O(1)\n * @returns True if case-sensitive.\n */\n\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode = new TrieNode('');\n\n /**\n * Get the root node.\n * @remarks Time O(1), Space O(1)\n * @returns Root TrieNode.\n */\n\n get root() {\n return this._root;\n }\n\n /**\n * (Protected) Get total count for base class iteration.\n * @remarks Time O(1), Space O(1)\n * @returns Total number of elements.\n */\n\n protected get _total() {\n return this._size;\n }\n\n /**\n * Insert one word into the trie.\n * @remarks Time O(L), Space O(L)\n * @param word - Word to insert.\n * @returns True if the word was newly added.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // basic Trie creation and add words\n * // Create a simple Trie with initial words\n * const trie = new Trie(['apple', 'app', 'apply']);\n *\n * // Verify size\n * console.log(trie.size); // 3;\n *\n * // Check if words exist\n * console.log(trie.has('apple')); // true;\n * console.log(trie.has('app')); // true;\n *\n * // Add a new word\n * trie.add('application');\n * console.log(trie.size); // 4;\n */\n\n add(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n let isNewWord = false;\n for (const c of word) {\n let nodeC = cur.children.get(c);\n if (!nodeC) {\n nodeC = new TrieNode(c);\n cur.children.set(c, nodeC);\n }\n cur = nodeC;\n }\n if (!cur.isEnd) {\n isNewWord = true;\n cur.isEnd = true;\n this._size++;\n }\n return isNewWord;\n }\n\n /**\n * Insert many words from an iterable.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param words - Iterable of strings (or raw records if toElementFn is provided).\n * @returns Array of per-word 'added' flags.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Add multiple words\n * const trie = new Trie();\n * trie.addMany(['cat', 'car', 'card']);\n * console.log(trie.has('cat')); // true;\n * console.log(trie.has('car')); // true;\n * console.log(trie.size); // 3;\n */\n\n addMany(words: Iterable<string> | Iterable<R>): boolean[] {\n const ans: boolean[] = [];\n for (const word of words) {\n if (this.toElementFn) {\n ans.push(this.add(this.toElementFn(word as R)));\n } else {\n ans.push(this.add(word as string));\n }\n }\n return ans;\n }\n\n /**\n * Check whether a word exists.\n * @remarks Time O(L), Space O(1)\n * @param word - Word to search for.\n * @returns True if present.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if a word exists\n * const dict = new Trie(['apple', 'app', 'application']);\n *\n * console.log(dict.has('app')); // true;\n * console.log(dict.has('apple')); // true;\n * console.log(dict.has('ap')); // false;\n */\n\n override has(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n for (const c of word) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return cur.isEnd;\n }\n\n /**\n * Check whether the trie is empty.\n * @remarks Time O(1), Space O(1)\n * @returns True if size is 0.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if empty\n * const trie = new Trie();\n * console.log(trie.isEmpty()); // true;\n * trie.add('word');\n * console.log(trie.isEmpty()); // false;\n */\n\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Remove all words and reset to a fresh root.\n * @remarks Time O(1), Space O(1)\n * @returns void\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Remove all words\n * const trie = new Trie(['a', 'b', 'c']);\n * trie.clear();\n * console.log(trie.isEmpty()); // true;\n */\n\n clear(): void {\n this._size = 0;\n this._root = new TrieNode('');\n }\n\n /**\n * Delete one word if present.\n * @remarks Time O(L), Space O(1)\n * @param word - Word to delete.\n * @returns True if a word was removed.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Trie delete and iteration\n * const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);\n *\n * // Delete a word\n * trie.delete('card');\n * console.log(trie.has('card')); // false;\n *\n * // Word with same prefix still exists\n * console.log(trie.has('care')); // true;\n *\n * // Size decreased\n * console.log(trie.size); // 5;\n *\n * // Iterate through all words\n * const allWords = [...trie];\n * console.log(allWords.length); // 5;\n */\n\n delete(word: string): boolean {\n word = this._caseProcess(word);\n let isDeleted = false;\n const dfs = (cur: TrieNode, i: number): boolean => {\n const char = word[i];\n const child = cur.children.get(char);\n if (child) {\n if (i === word.length - 1) {\n if (child.isEnd) {\n if (child.children.size > 0) {\n child.isEnd = false;\n } else {\n cur.children.delete(char);\n }\n isDeleted = true;\n return true;\n }\n return false;\n }\n const res = dfs(child, i + 1);\n if (res && !cur.isEnd && child.children.size === 0) {\n cur.children.delete(char);\n return true;\n }\n return false;\n }\n return false;\n };\n\n dfs(this.root, 0);\n if (isDeleted) {\n this._size--;\n }\n return isDeleted;\n }\n\n /**\n * Compute the height (max depth) of the trie.\n * @remarks Time O(N), Space O(H)\n * @returns Maximum depth from root to a leaf.\n */\n\n getHeight(): number {\n const startNode = this.root;\n let maxDepth = 0;\n if (startNode) {\n const bfs = (node: TrieNode, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { children } = node;\n if (children) {\n for (const child of children.entries()) {\n bfs(child[1], level + 1);\n }\n }\n };\n bfs(startNode, 0);\n }\n return maxDepth;\n }\n\n /**\n * Check whether input is a proper prefix of at least one word.\n * @remarks Time O(L), Space O(1)\n * @param input - String to test as prefix.\n * @returns True if input is a prefix but not a full word.\n */\n\n hasPurePrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return !cur.isEnd;\n }\n\n /**\n * Check whether any word starts with input.\n * @remarks Time O(L), Space O(1)\n * @param input - String to test as prefix.\n * @returns True if input matches a path from root.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if a prefix exists\n * const trie = new Trie(['hello', 'help', 'world']);\n *\n * console.log(trie.hasPrefix('hel')); // true;\n * console.log(trie.hasPrefix('wor')); // true;\n * console.log(trie.hasPrefix('xyz')); // false;\n */\n\n hasPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return true;\n }\n\n /**\n * Check whether the trie’s longest common prefix equals input.\n * @remarks Time O(min(H,L)), Space O(1)\n * @param input - Candidate longest common prefix.\n * @returns True if input equals the common prefix.\n */\n\n hasCommonPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (commonPre === input) return;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre === input;\n }\n\n /**\n * Return the longest common prefix among all words.\n * @remarks Time O(H), Space O(1)\n * @returns The longest common prefix string.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Find shared prefix\n * const trie = new Trie(['flower', 'flow', 'flight']);\n *\n * console.log(trie.getLongestCommonPrefix()); // 'fl';\n */\n\n getLongestCommonPrefix(): string {\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre;\n }\n\n /**\n * Collect words under a prefix up to a maximum count.\n * @remarks Time O(K·L), Space O(K·L)\n * @param [prefix] - Prefix to match; default empty string for root.\n * @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.\n * @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.\n * @returns Array of collected words (at most max).\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Trie getWords and prefix search\n * const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);\n *\n * // Get all words with prefix 'app'\n * const appWords = trie.getWords('app');\n * console.log(appWords); // contains 'app';\n * console.log(appWords); // contains 'apple';\n * console.log(appWords); // contains 'apply';\n * console.log(appWords); // contains 'application';\n * expect(appWords).not.toContain('apricot');\n */\n\n getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {\n prefix = this._caseProcess(prefix);\n const words: string[] = [];\n let found = 0;\n\n const dfs = (node: TrieNode, word: string): void => {\n for (const [char, childNode] of node.children) {\n if (found >= max) return;\n dfs(childNode, word + char);\n }\n if (node.isEnd) {\n if (found >= max) return;\n words.push(word);\n found++;\n }\n };\n\n let startNode = this.root;\n\n if (prefix) {\n for (const c of prefix) {\n const nodeC = startNode.children.get(c);\n if (nodeC) {\n startNode = nodeC;\n } else {\n return [];\n }\n }\n }\n\n if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);\n\n return words;\n }\n\n /**\n * Deep clone this trie by iterating and inserting all words.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @returns A new trie with the same words and options.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Create independent copy\n * const trie = new Trie(['hello', 'world']);\n * const copy = trie.clone();\n * copy.delete('hello');\n * console.log(trie.has('hello')); // true;\n */\n\n clone(): this {\n const next = this._createInstance();\n for (const x of this) next.add(x);\n return next;\n }\n\n /**\n * Filter words into a new trie of the same class.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param predicate - Predicate (word, index, trie) → boolean to keep word.\n * @param [thisArg] - Value for `this` inside the predicate.\n * @returns A new trie containing words that satisfy the predicate.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Filter words\n * const trie = new Trie(['cat', 'car', 'dog', 'card']);\n * const result = trie.filter(w => w.startsWith('ca'));\n * console.log(result.size); // 3;\n */\n\n filter(predicate: ElementCallback<string, R, boolean>, thisArg?: unknown): this {\n const results = this._createInstance();\n let index = 0;\n for (const word of this) {\n if (predicate.call(thisArg, word, index, this)) {\n results.add(word);\n }\n index++;\n }\n return results;\n }\n\n /**\n * Transform words\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Transform words\n * const trie = new Trie(['hello', 'world']);\n * const upper = trie.map(w => w.toUpperCase());\n * console.log(upper.has('HELLO')); // true;\n */\n map<RM>(callback: ElementCallback<string, R, string>, options?: TrieOptions<RM>, thisArg?: unknown): Trie<RM>;\n\n /**\n * Map words into a new trie (possibly different record type).\n * @remarks Time O(ΣL), Space O(ΣL)\n * @template EM\n * @template RM\n * @param callback - Mapping function (word, index, trie) → newWord (string).\n * @param [options] - Options for the output trie (e.g., toElementFn, caseSensitive).\n * @param [thisArg] - Value for `this` inside the callback.\n * @returns A new Trie constructed from mapped words.\n */\n\n map<EM, RM>(\n callback: ElementCallback<string, R, EM>,\n options?: TrieOptions<RM>,\n thisArg?: unknown\n ): IterableElementBase<EM, RM>;\n\n map<EM, RM>(callback: ElementCallback<string, R, EM>, options?: TrieOptions<RM>, thisArg?: unknown): any {\n const newTrie = this._createLike<RM>([], options);\n let i = 0;\n for (const x of this) {\n const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);\n if (typeof v !== 'string') {\n raise(TypeError, ERR.callbackReturnType('string', typeof v, 'Trie.map'));\n }\n newTrie.add(v);\n }\n return newTrie;\n }\n\n /**\n * Map words into a new trie of the same element type.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param callback - Mapping function (word, index, trie) → string.\n * @param [thisArg] - Value for `this` inside the callback.\n * @returns A new trie with mapped words.\n */\n\n mapSame(callback: ElementCallback<string, R, string>, thisArg?: unknown): this {\n const next = this._createInstance();\n let i = 0;\n for (const key of this) {\n const mapped = thisArg === undefined ? callback(key, i++, this) : callback.call(thisArg, key, i++, this);\n next.add(mapped);\n }\n return next;\n }\n\n /**\n * (Protected) Create an empty instance of the same concrete class.\n * @remarks Time O(1), Space O(1)\n * @param [options] - Options forwarded to the constructor.\n * @returns An empty like-kind trie instance.\n */\n\n protected _createInstance(options?: TrieOptions<R>): this {\n const Ctor = this.constructor as new (\n elements?: Iterable<string> | Iterable<R>,\n options?: TrieOptions<R>\n ) => this;\n return new Ctor([], {\n toElementFn: this.toElementFn,\n caseSensitive: this.caseSensitive,\n ...(options ?? {})\n });\n }\n\n /**\n * (Protected) Create a like-kind trie and seed it from an iterable.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @template RM\n * @param [elements] - Iterable used to seed the new trie.\n * @param [options] - Options forwarded to the constructor.\n * @returns A like-kind Trie instance.\n */\n\n protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {\n const Ctor = this.constructor as new (\n elements?: Iterable<string> | Iterable<RM>,\n options?: TrieOptions<RM>\n ) => Trie<RM>;\n return new Ctor(elements, options);\n }\n\n /**\n * (Protected) Spawn an empty like-kind trie instance.\n * @remarks Time O(1), Space O(1)\n * @template RM\n * @param [options] - Options forwarded to the constructor.\n * @returns An empty like-kind Trie instance.\n */\n\n protected _spawnLike<RM>(options?: TrieOptions<RM>): Trie<RM> {\n return this._createLike<RM>([], options);\n }\n\n /**\n * (Protected) Iterate all words in lexicographic order of edges.\n * @remarks Time O(ΣL), Space O(H)\n * @returns Iterator of words.\n */\n\n protected *_getIterator(): IterableIterator<string> {\n function* _dfs(node: TrieNode, path: string): IterableIterator<string> {\n if (node.isEnd) {\n yield path;\n }\n for (const [char, childNode] of node.children) {\n yield* _dfs(childNode, path + char);\n }\n }\n\n yield* _dfs(this.root, '');\n }\n\n /**\n * (Protected) Normalize a string according to case sensitivity.\n * @remarks Time O(L), Space O(L)\n * @param str - Input string to normalize.\n * @returns Normalized string based on caseSensitive.\n */\n\n protected _caseProcess(str: string) {\n if (!this._caseSensitive) {\n str = str.toLowerCase();\n }\n return str;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOO,WAAS,MACd,YACA,SACO;AACP,UAAM,IAAI,WAAW,OAAO;AAAA,EAC9B;AAMO,MAAM,MAAM;AAAA;AAAA,IAEjB,iBAAiB,CAAC,OAAe,KAAa,KAAa,QACzD,GAAG,MAAM,MAAM,OAAO,EAAE,SAAS,KAAK,qBAAqB,GAAG,KAAK,GAAG;AAAA,IAExE,cAAc,CAAC,QACb,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA;AAAA,IAG1B,iBAAiB,CAAC,QAAgB,QAChC,GAAG,MAAM,MAAM,OAAO,EAAE,GAAG,MAAM;AAAA,IAEnC,oBAAoB,CAAC,QACnB,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA,IAE1B,YAAY,CAAC,QAAgB,QAC3B,GAAG,MAAM,MAAM,OAAO,EAAE,GAAG,MAAM;AAAA,IAEnC,cAAc,CAAC,MAAc,QAC3B,GAAG,MAAM,MAAM,OAAO,EAAE,GAAG,IAAI;AAAA,IAEjC,cAAc,CAAC,QACb,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA,IAE1B,YAAY,CAAC,QACX,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA,IAE1B,aAAa,CAAC,QACZ,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA,IAE1B,aAAa,CAAC,QACZ,GAAG,MAAM,MAAM,OAAO,EAAE;AAAA,IAE1B,oBAAoB,CAAC,UAAkB,KAAa,QAClD,GAAG,MAAM,MAAM,OAAO,EAAE,wBAAwB,QAAQ,SAAS,GAAG;AAAA;AAAA,IAGtE,kBAAkB,CAAC,QAAgB,QACjC,GAAG,MAAM,MAAM,OAAO,EAAE,GAAG,MAAM;AAAA;AAAA,IAGnC,yBAAyB,CAAC,OACxB,6CAA6C,EAAE;AAAA,IAEjD,gBAAgB,MACd;AAAA,IAEF,iBAAiB,MACf;AAAA,IAEF,sBAAsB,MACpB;AAAA,IAEF,mBAAmB,CAAC,UAAkB,QACpC,+BAA+B,QAAQ,aAAa,GAAG;AAAA;AAAA,IAGzD,0BAA0B,CAAC,QAAgB,QACzC,GAAG,MAAM,MAAM,OAAO,EAAE,GAAG,MAAM;AAAA,EACrC;;;AC3EO,MAAK,eAAL,kBAAKA,kBAAL;AACL,IAAAA,4BAAA,WAAQ,KAAR;AACA,IAAAA,4BAAA,aAAU,KAAV;AAFU,WAAAA;AAAA,KAAA;AAKL,MAAM,QAAN,MAAe;AAAA,IACpB,YACS,KACA,MACA,aAAsB,MACtB,cAAuB,MAC9B;AAJO;AACA;AACA;AACA;AAAA,IAIT;AAAA;AAAA,IAGA,UAAU,KAAQ,YAA6C;AAC7D,YAAM,WAAW,KAAK,aAAa,WAAW,KAAK,KAAK,GAAG,KAAK,IAAI,WAAW,KAAK,KAAK,GAAG,IAAI;AAChG,YAAM,YAAY,KAAK,cAAc,WAAW,KAAK,KAAK,IAAI,KAAK,IAAI,WAAW,KAAK,KAAK,IAAI,IAAI;AACpG,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;;;ACVO,MAAe,sBAAf,MAAgE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU3D,YAAY,SAA4C;AAclE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAU;AAbR,UAAI,SAAS;AACX,cAAM,EAAE,YAAY,IAAI;AACxB,YAAI,OAAO,gBAAgB,WAAY,MAAK,eAAe;AAAA,iBAClD,YAAa,OAAM,WAAW,qCAAqC;AAAA,MAC9E;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiBA,IAAI,cAAkD;AACpD,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,OAAO,QAAQ,KAAK,MAAsC;AAC1D,aAAO,KAAK,aAAa,GAAG,IAAI;AAAA,IAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,CAAC,SAA8B;AAC7B,iBAAW,QAAQ,KAAM,OAAM;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,MAAM,WAA2C,SAA4B;AAC3E,UAAI,QAAQ;AACZ,iBAAW,QAAQ,MAAM;AACvB,YAAI,YAAY,QAAW;AACzB,cAAI,CAAC,UAAU,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QAC9C,OAAO;AACL,gBAAM,KAAK;AACX,cAAI,CAAC,GAAG,KAAK,SAAS,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QACrD;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYA,KAAK,WAA2C,SAA4B;AAC1E,UAAI,QAAQ;AACZ,iBAAW,QAAQ,MAAM;AACvB,YAAI,YAAY,QAAW;AACzB,cAAI,UAAU,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QAC7C,OAAO;AACL,gBAAM,KAAK;AACX,cAAI,GAAG,KAAK,SAAS,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QACpD;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYA,QAAQ,YAAyC,SAAyB;AACxE,UAAI,QAAQ;AACZ,iBAAW,QAAQ,MAAM;AACvB,YAAI,YAAY,QAAW;AACzB,qBAAW,MAAM,SAAS,IAAI;AAAA,QAChC,OAAO;AACL,gBAAM,KAAK;AACX,aAAG,KAAK,SAAS,MAAM,SAAS,IAAI;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAwBA,KAAK,WAA2C,SAAkC;AAChF,UAAI,QAAQ;AACZ,iBAAW,QAAQ,MAAM;AACvB,YAAI,YAAY,QAAW;AACzB,cAAI,UAAU,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QAC7C,OAAO;AACL,gBAAM,KAAK;AACX,cAAI,GAAG,KAAK,SAAS,MAAM,SAAS,IAAI,EAAG,QAAO;AAAA,QACpD;AAAA,MACF;AACA;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,IAAI,SAAqB;AACvB,iBAAW,OAAO,KAAM,KAAI,QAAQ,QAAS,QAAO;AACpD,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2BA,OAAU,YAA4C,cAAqB;AACzE,UAAI,QAAQ;AACZ,YAAM,OAAO,KAAK,OAAO,QAAQ,EAAE;AACnC,UAAI;AAEJ,UAAI,UAAU,UAAU,GAAG;AACzB,cAAM;AAAA,MACR,OAAO;AACL,cAAM,QAAQ,KAAK,KAAK;AACxB,YAAI,MAAM,KAAM,OAAM,WAAW,iDAAiD;AAClF,cAAM,MAAM;AACZ,gBAAQ;AAAA,MACV;AAEA,iBAAW,SAAS,MAAgC;AAClD,cAAM,WAAW,KAAK,OAAO,SAAS,IAAI;AAAA,MAC5C;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,UAAe;AACb,aAAO,CAAC,GAAG,IAAI;AAAA,IACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,WAAgB;AACd,aAAO,CAAC,GAAG,IAAI;AAAA,IACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,QAAc;AACZ,cAAQ,IAAI,KAAK,SAAS,CAAC;AAAA,IAC7B;AAAA,EAkFF;;;AChVO,MAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOpB,YAAY,KAAa;AAMzB,0BAAU;AAuBV,0BAAU;AAuBV,0BAAU;AAnDR,WAAK,OAAO;AACZ,WAAK,SAAS;AACd,WAAK,YAAY,oBAAI,IAAsB;AAAA,IAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,MAAc;AAChB,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,IAAI,IAAI,OAAe;AACrB,WAAK,OAAO;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,WAAkC;AACpC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,IAAI,SAAS,OAA8B;AACzC,WAAK,YAAY;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,QAAiB;AACnB,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,IAAI,MAAM,OAAgB;AACxB,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAsHO,MAAM,OAAN,cAA4B,oBAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAShE,YAAY,QAAwC,CAAC,GAAG,SAA0B;AAChF,YAAM,OAAO;AAUf,0BAAU,SAAgB;AAY1B,0BAAU,kBAA0B;AAYpC,0BAAU,SAAkB,IAAI,SAAS,EAAE;AAjCzC,UAAI,SAAS;AACX,cAAM,EAAE,cAAc,IAAI;AAC1B,YAAI,kBAAkB,OAAW,MAAK,iBAAiB;AAAA,MACzD;AACA,UAAI,OAAO;AACT,aAAK,QAAQ,KAAK;AAAA,MACpB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,OAAe;AACjB,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,gBAAyB;AAC3B,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,IAAI,OAAO;AACT,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,IAAc,SAAS;AACrB,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA2DA,IAAI,MAAuB;AACzB,aAAO,KAAK,aAAa,IAAI;AAC7B,UAAI,MAAM,KAAK;AACf,UAAI,YAAY;AAChB,iBAAW,KAAK,MAAM;AACpB,YAAI,QAAQ,IAAI,SAAS,IAAI,CAAC;AAC9B,YAAI,CAAC,OAAO;AACV,kBAAQ,IAAI,SAAS,CAAC;AACtB,cAAI,SAAS,IAAI,GAAG,KAAK;AAAA,QAC3B;AACA,cAAM;AAAA,MACR;AACA,UAAI,CAAC,IAAI,OAAO;AACd,oBAAY;AACZ,YAAI,QAAQ;AACZ,aAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgDA,QAAQ,OAAkD;AACxD,YAAM,MAAiB,CAAC;AACxB,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,aAAa;AACpB,cAAI,KAAK,KAAK,IAAI,KAAK,YAAY,IAAS,CAAC,CAAC;AAAA,QAChD,OAAO;AACL,cAAI,KAAK,KAAK,IAAI,IAAc,CAAC;AAAA,QACnC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmDS,IAAI,MAAuB;AAClC,aAAO,KAAK,aAAa,IAAI;AAC7B,UAAI,MAAM,KAAK;AACf,iBAAW,KAAK,MAAM;AACpB,cAAM,QAAQ,IAAI,SAAS,IAAI,CAAC;AAChC,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM;AAAA,MACR;AACA,aAAO,IAAI;AAAA,IACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8CA,UAAmB;AACjB,aAAO,KAAK,UAAU;AAAA,IACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA6CA,QAAc;AACZ,WAAK,QAAQ;AACb,WAAK,QAAQ,IAAI,SAAS,EAAE;AAAA,IAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA6DA,OAAO,MAAuB;AAC5B,aAAO,KAAK,aAAa,IAAI;AAC7B,UAAI,YAAY;AAChB,YAAM,MAAM,CAAC,KAAe,MAAuB;AACjD,cAAM,OAAO,KAAK,CAAC;AACnB,cAAM,QAAQ,IAAI,SAAS,IAAI,IAAI;AACnC,YAAI,OAAO;AACT,cAAI,MAAM,KAAK,SAAS,GAAG;AACzB,gBAAI,MAAM,OAAO;AACf,kBAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,sBAAM,QAAQ;AAAA,cAChB,OAAO;AACL,oBAAI,SAAS,OAAO,IAAI;AAAA,cAC1B;AACA,0BAAY;AACZ,qBAAO;AAAA,YACT;AACA,mBAAO;AAAA,UACT;AACA,gBAAM,MAAM,IAAI,OAAO,IAAI,CAAC;AAC5B,cAAI,OAAO,CAAC,IAAI,SAAS,MAAM,SAAS,SAAS,GAAG;AAClD,gBAAI,SAAS,OAAO,IAAI;AACxB,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,MAAM,CAAC;AAChB,UAAI,WAAW;AACb,aAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,YAAoB;AAClB,YAAM,YAAY,KAAK;AACvB,UAAI,WAAW;AACf,UAAI,WAAW;AACb,cAAM,MAAM,CAAC,MAAgB,UAAkB;AAC7C,cAAI,QAAQ,UAAU;AACpB,uBAAW;AAAA,UACb;AACA,gBAAM,EAAE,SAAS,IAAI;AACrB,cAAI,UAAU;AACZ,uBAAW,SAAS,SAAS,QAAQ,GAAG;AACtC,kBAAI,MAAM,CAAC,GAAG,QAAQ,CAAC;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AACA,YAAI,WAAW,CAAC;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,cAAc,OAAwB;AACpC,cAAQ,KAAK,aAAa,KAAK;AAC/B,UAAI,MAAM,KAAK;AACf,iBAAW,KAAK,OAAO;AACrB,cAAM,QAAQ,IAAI,SAAS,IAAI,CAAC;AAChC,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM;AAAA,MACR;AACA,aAAO,CAAC,IAAI;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmDA,UAAU,OAAwB;AAChC,cAAQ,KAAK,aAAa,KAAK;AAC/B,UAAI,MAAM,KAAK;AACf,iBAAW,KAAK,OAAO;AACrB,cAAM,QAAQ,IAAI,SAAS,IAAI,CAAC;AAChC,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM;AAAA,MACR;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,gBAAgB,OAAwB;AACtC,cAAQ,KAAK,aAAa,KAAK;AAC/B,UAAI,YAAY;AAChB,YAAM,MAAM,CAAC,QAAkB;AAC7B,qBAAa,IAAI;AACjB,YAAI,cAAc,MAAO;AACzB,YAAI,IAAI,MAAO;AACf,YAAI,OAAO,IAAI,YAAY,IAAI,SAAS,SAAS,EAAG,KAAI,MAAM,KAAK,IAAI,SAAS,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,YACvF;AAAA,MACP;AACA,UAAI,KAAK,IAAI;AACb,aAAO,cAAc;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgDA,yBAAiC;AAC/B,UAAI,YAAY;AAChB,YAAM,MAAM,CAAC,QAAkB;AAC7B,qBAAa,IAAI;AACjB,YAAI,IAAI,MAAO;AACf,YAAI,OAAO,IAAI,YAAY,IAAI,SAAS,SAAS,EAAG,KAAI,MAAM,KAAK,IAAI,SAAS,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,YACvF;AAAA,MACP;AACA,UAAI,KAAK,IAAI;AACb,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAyDA,SAAS,SAAS,IAAI,MAAM,OAAO,kBAAkB,uBAAuB,OAAiB;AAC3F,eAAS,KAAK,aAAa,MAAM;AACjC,YAAM,QAAkB,CAAC;AACzB,UAAI,QAAQ;AAEZ,YAAM,MAAM,CAAC,MAAgB,SAAuB;AAClD,mBAAW,CAAC,MAAM,SAAS,KAAK,KAAK,UAAU;AAC7C,cAAI,SAAS,IAAK;AAClB,cAAI,WAAW,OAAO,IAAI;AAAA,QAC5B;AACA,YAAI,KAAK,OAAO;AACd,cAAI,SAAS,IAAK;AAClB,gBAAM,KAAK,IAAI;AACf;AAAA,QACF;AAAA,MACF;AAEA,UAAI,YAAY,KAAK;AAErB,UAAI,QAAQ;AACV,mBAAW,KAAK,QAAQ;AACtB,gBAAM,QAAQ,UAAU,SAAS,IAAI,CAAC;AACtC,cAAI,OAAO;AACT,wBAAY;AAAA,UACd,OAAO;AACL,mBAAO,CAAC;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAEA,UAAI,wBAAwB,cAAc,KAAK,KAAM,KAAI,WAAW,MAAM;AAE1E,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8CA,QAAc;AACZ,YAAM,OAAO,KAAK,gBAAgB;AAClC,iBAAW,KAAK,KAAM,MAAK,IAAI,CAAC;AAChC,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA+CA,OAAO,WAAgD,SAAyB;AAC9E,YAAM,UAAU,KAAK,gBAAgB;AACrC,UAAI,QAAQ;AACZ,iBAAW,QAAQ,MAAM;AACvB,YAAI,UAAU,KAAK,SAAS,MAAM,OAAO,IAAI,GAAG;AAC9C,kBAAQ,IAAI,IAAI;AAAA,QAClB;AACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IA6DA,IAAY,UAA0C,SAA2B,SAAwB;AACvG,YAAM,UAAU,KAAK,YAAgB,CAAC,GAAG,OAAO;AAChD,UAAI,IAAI;AACR,iBAAW,KAAK,MAAM;AACpB,cAAM,IAAI,YAAY,SAAY,SAAS,GAAG,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,GAAG,KAAK,IAAI;AAC9F,YAAI,OAAO,MAAM,UAAU;AACzB,gBAAM,WAAW,IAAI,mBAAmB,UAAU,OAAO,GAAG,UAAU,CAAC;AAAA,QACzE;AACA,gBAAQ,IAAI,CAAC;AAAA,MACf;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,QAAQ,UAA8C,SAAyB;AAC7E,YAAM,OAAO,KAAK,gBAAgB;AAClC,UAAI,IAAI;AACR,iBAAW,OAAO,MAAM;AACtB,cAAM,SAAS,YAAY,SAAY,SAAS,KAAK,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,KAAK,KAAK,IAAI;AACvG,aAAK,IAAI,MAAM;AAAA,MACjB;AACA,aAAO;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASU,gBAAgB,SAAgC;AACxD,YAAM,OAAO,KAAK;AAIlB,aAAO,IAAI,KAAK,CAAC,GAAG;AAAA,QAClB,aAAa,KAAK;AAAA,QAClB,eAAe,KAAK;AAAA,QACpB,GAAI,4BAAW,CAAC;AAAA,MAClB,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWU,YAAgB,WAA4C,CAAC,GAAG,SAAqC;AAC7G,YAAM,OAAO,KAAK;AAIlB,aAAO,IAAI,KAAK,UAAU,OAAO;AAAA,IACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUU,WAAe,SAAqC;AAC5D,aAAO,KAAK,YAAgB,CAAC,GAAG,OAAO;AAAA,IACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,CAAW,eAAyC;AAClD,gBAAU,KAAK,MAAgB,MAAwC;AACrE,YAAI,KAAK,OAAO;AACd,gBAAM;AAAA,QACR;AACA,mBAAW,CAAC,MAAM,SAAS,KAAK,KAAK,UAAU;AAC7C,iBAAO,KAAK,WAAW,OAAO,IAAI;AAAA,QACpC;AAAA,MACF;AAEA,aAAO,KAAK,KAAK,MAAM,EAAE;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASU,aAAa,KAAa;AAClC,UAAI,CAAC,KAAK,gBAAgB;AACxB,cAAM,IAAI,YAAY;AAAA,MACxB;AACA,aAAO;AAAA,IACT;AAAA,EACF;","names":["DFSOperation"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/common/error.ts","../../src/common/index.ts","../../src/data-structures/base/iterable-element-base.ts","../../src/data-structures/trie/trie.ts"],"sourcesContent":["/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nexport * from './data-structures/trie';\nexport * from './types/data-structures/trie';\nexport * from './types/common';\nexport * from './types/utils';\nexport * from './common';","/**\n * Centralized error dispatch.\n * All library errors go through this function for consistent messaging and easy grep.\n * @remarks Always throws — data structure errors are never recoverable.\n * @param ErrorClass - The error constructor (Error, TypeError, RangeError, etc.)\n * @param message - The error message.\n */\nexport function raise(\n ErrorClass: new (msg: string) => Error,\n message: string\n): never {\n throw new ErrorClass(message);\n}\n\n/**\n * Centralized error message templates.\n * Keep using native Error/TypeError/RangeError — this only standardizes messages.\n */\nexport const ERR = {\n // Range / index\n indexOutOfRange: (index: number, min: number, max: number, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Index ${index} is out of range [${min}, ${max}].`,\n\n invalidIndex: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Index must be an integer.`,\n\n // Type / argument\n invalidArgument: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n comparatorRequired: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Comparator is required for non-number/non-string/non-Date keys.`,\n\n invalidKey: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n notAFunction: (name: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${name} must be a function.`,\n\n invalidEntry: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Each entry must be a [key, value] tuple.`,\n\n invalidNaN: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}NaN is not a valid key.`,\n\n invalidDate: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Invalid Date key.`,\n\n reduceEmpty: (ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Reduce of empty structure with no initial value.`,\n\n callbackReturnType: (expected: string, got: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}Callback must return ${expected}; got ${got}.`,\n\n // State / operation\n invalidOperation: (reason: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${reason}`,\n\n // Matrix\n matrixDimensionMismatch: (op: string) =>\n `Matrix: Dimensions must be compatible for ${op}.`,\n\n matrixSingular: () =>\n 'Matrix: Singular matrix, inverse does not exist.',\n\n matrixNotSquare: () =>\n 'Matrix: Must be square for inversion.',\n\n matrixNotRectangular: () =>\n 'Matrix: Must be rectangular for transposition.',\n\n matrixRowMismatch: (expected: number, got: number) =>\n `Matrix: Expected row length ${expected}, but got ${got}.`,\n\n // Order statistic\n orderStatisticNotEnabled: (method: string, ctx?: string) =>\n `${ctx ? ctx + ': ' : ''}${method}() requires enableOrderStatistic: true.`\n} as const;\n","export { ERR, raise } from './error';\n\nexport enum DFSOperation {\n VISIT = 0,\n PROCESS = 1\n}\n\nexport class Range<K> {\n constructor(\n public low: K,\n public high: K,\n public includeLow: boolean = true,\n public includeHigh: boolean = true\n ) {\n // if (!(isComparable(low) && isComparable(high))) throw new RangeError('low or high is not comparable');\n // if (low > high) throw new RangeError('low must be less than or equal to high');\n }\n\n // Determine whether a key is within the range\n isInRange(key: K, comparator: (a: K, b: K) => number): boolean {\n const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;\n const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;\n return lowCheck && highCheck;\n }\n}\n","import type { ElementCallback, IterableElementBaseOptions, ReduceElementCallback } from '../../types';\nimport { raise } from '../../common';\n\n/**\n * Base class that makes a data structure iterable and provides common\n * element-wise utilities (e.g., map/filter/reduce/find).\n *\n * @template E The public element type yielded by the structure.\n * @template R The underlying \"raw\" element type used internally or by converters.\n *\n * @remarks\n * This class implements the JavaScript iteration protocol (via `Symbol.iterator`)\n * and offers array-like helpers with predictable time/space complexity.\n */\nexport abstract class IterableElementBase<E, R> implements Iterable<E> {\n /**\n * Create a new iterable base.\n *\n * @param options Optional behavior overrides. When provided, a `toElementFn`\n * is used to convert a raw element (`R`) into a public element (`E`).\n *\n * @remarks\n * Time O(1), Space O(1).\n */\n protected constructor(options?: IterableElementBaseOptions<E, R>) {\n if (options) {\n const { toElementFn } = options;\n if (typeof toElementFn === 'function') this._toElementFn = toElementFn;\n else if (toElementFn) raise(TypeError, 'toElementFn must be a function type');\n }\n }\n\n /**\n * The converter used to transform a raw element (`R`) into a public element (`E`).\n *\n * @remarks\n * Time O(1), Space O(1).\n */\n protected _toElementFn?: (rawElement: R) => E;\n\n /**\n * Exposes the current `toElementFn`, if configured.\n *\n * @returns The converter function or `undefined` when not set.\n * @remarks\n * Time O(1), Space O(1).\n */\n get toElementFn(): ((rawElement: R) => E) | undefined {\n return this._toElementFn;\n }\n\n /**\n * Returns an iterator over the structure's elements.\n *\n * @param args Optional iterator arguments forwarded to the internal iterator.\n * @returns An `IterableIterator<E>` that yields the elements in traversal order.\n *\n * @remarks\n * Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space.\n */\n *[Symbol.iterator](...args: unknown[]): IterableIterator<E> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Returns an iterator over the values (alias of the default iterator).\n *\n * @returns An `IterableIterator<E>` over all elements.\n * @remarks\n * Creating the iterator is O(1); full iteration is Time O(n), Space O(1).\n */\n *values(): IterableIterator<E> {\n for (const item of this) yield item;\n }\n\n /**\n * Tests whether all elements satisfy the predicate.\n *\n * @template TReturn\n * @param predicate Function invoked for each element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns `true` if every element passes; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early when the first failure is found. Space O(1).\n */\n every(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): boolean {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (!predicate(item, index++, this)) return false;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (!fn.call(thisArg, item, index++, this)) return false;\n }\n }\n return true;\n }\n\n /**\n * Tests whether at least one element satisfies the predicate.\n *\n * @param predicate Function invoked for each element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns `true` if any element passes; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early on first success. Space O(1).\n */\n some(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): boolean {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (predicate(item, index++, this)) return true;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (fn.call(thisArg, item, index++, this)) return true;\n }\n }\n return false;\n }\n\n /**\n * Invokes a callback for each element in iteration order.\n *\n * @param callbackfn Function invoked per element with signature `(value, index, self)`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns `void`.\n *\n * @remarks\n * Time O(n), Space O(1).\n */\n forEach(callbackfn: ElementCallback<E, R, void>, thisArg?: unknown): void {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n callbackfn(item, index++, this);\n } else {\n const fn = callbackfn as (this: unknown, v: E, i: number, self: this) => void;\n fn.call(thisArg, item, index++, this);\n }\n }\n }\n\n /**\n * Finds the first element that satisfies the predicate and returns it.\n *\n * @overload\n * Finds the first element of type `S` (a subtype of `E`) that satisfies the predicate and returns it.\n * @template S\n * @param predicate Type-guard predicate: `(value, index, self) => value is S`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns The matched element typed as `S`, or `undefined` if not found.\n *\n * @overload\n * @param predicate Boolean predicate: `(value, index, self) => boolean`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns The first matching element as `E`, or `undefined` if not found.\n *\n * @remarks\n * Time O(n) in the worst case; may exit early on the first match. Space O(1).\n */\n find<S extends E>(predicate: ElementCallback<E, R, S>, thisArg?: unknown): S | undefined;\n find(predicate: ElementCallback<E, R, unknown>, thisArg?: unknown): E | undefined;\n\n // Implementation signature\n find(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): E | undefined {\n let index = 0;\n for (const item of this) {\n if (thisArg === undefined) {\n if (predicate(item, index++, this)) return item;\n } else {\n const fn = predicate as (this: unknown, v: E, i: number, self: this) => boolean;\n if (fn.call(thisArg, item, index++, this)) return item;\n }\n }\n return;\n }\n\n /**\n * Checks whether a strictly-equal element exists in the structure.\n *\n * @param element The element to test with `===` equality.\n * @returns `true` if an equal element is found; otherwise `false`.\n *\n * @remarks\n * Time O(n) in the worst case. Space O(1).\n */\n has(element: E): boolean {\n for (const ele of this) if (ele === element) return true;\n return false;\n }\n\n /**\n * Check whether a value exists (Array-compatible alias for `has`).\n * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1).\n * @param element - Element to search for (uses `===`).\n * @returns `true` if found.\n */\n includes(element: E): boolean {\n return this.has(element);\n }\n\n /**\n * Return an iterator of `[index, value]` pairs (Array-compatible).\n * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1) per step.\n */\n *entries(): IterableIterator<[number, E]> {\n let index = 0;\n for (const value of this) {\n yield [index++, value];\n }\n }\n\n /**\n * Return an iterator of numeric indices (Array-compatible).\n * @remarks Provided for familiarity when migrating from Array. Time O(n), Space O(1) per step.\n */\n *keys(): IterableIterator<number> {\n let index = 0;\n for (const _ of this) {\n yield index++;\n }\n }\n\n reduce(callbackfn: ReduceElementCallback<E, R>): E;\n reduce(callbackfn: ReduceElementCallback<E, R>, initialValue: E): E;\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue: U): U;\n\n /**\n * Reduces all elements to a single accumulated value.\n *\n * @overload\n * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`. The first element is used as the initial accumulator.\n * @returns The final accumulated value typed as `E`.\n *\n * @overload\n * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`.\n * @param initialValue The initial accumulator value of type `E`.\n * @returns The final accumulated value typed as `E`.\n *\n * @overload\n * @template U The accumulator type when it differs from `E`.\n * @param callbackfn Reducer of signature `(acc: U, value, index, self) => U`.\n * @param initialValue The initial accumulator value of type `U`.\n * @returns The final accumulated value typed as `U`.\n *\n * @remarks\n * Time O(n), Space O(1). Throws if called on an empty structure without `initialValue`.\n */\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U>, initialValue?: U): U {\n let index = 0;\n const iter = this[Symbol.iterator]();\n let acc: U;\n\n if (arguments.length >= 2) {\n acc = initialValue as U;\n } else {\n const first = iter.next();\n if (first.done) raise(TypeError, 'Reduce of empty structure with no initial value');\n acc = first.value as unknown as U;\n index = 1;\n }\n\n for (const value of iter as unknown as Iterable<E>) {\n acc = callbackfn(acc, value, index++, this);\n }\n return acc;\n }\n\n /**\n * Materializes the elements into a new array.\n *\n * @returns A shallow array copy of the iteration order.\n * @remarks\n * Time O(n), Space O(n).\n */\n toArray(): E[] {\n return [...this];\n }\n\n /**\n * Returns a representation of the structure suitable for quick visualization.\n * Defaults to an array of elements; subclasses may override to provide richer visuals.\n *\n * @returns A visual representation (array by default).\n * @remarks\n * Time O(n), Space O(n).\n */\n toVisual(): E[] {\n return [...this];\n }\n\n /**\n * Prints `toVisual()` to the console. Intended for quick debugging.\n *\n * @returns `void`.\n * @remarks\n * Time O(n) due to materialization, Space O(n) for the intermediate representation.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n /**\n * Indicates whether the structure currently contains no elements.\n *\n * @returns `true` if empty; otherwise `false`.\n * @remarks\n * Expected Time O(1), Space O(1) for most implementations.\n */\n abstract isEmpty(): boolean;\n\n /**\n * Removes all elements from the structure.\n *\n * @returns `void`.\n * @remarks\n * Expected Time O(1) or O(n) depending on the implementation; Space O(1).\n */\n abstract clear(): void;\n\n /**\n * Creates a structural copy with the same element values and configuration.\n *\n * @returns A clone of the current instance (same concrete type).\n * @remarks\n * Expected Time O(n) to copy elements; Space O(n).\n */\n abstract clone(): this;\n\n /**\n * Maps each element to a new element and returns a new iterable structure.\n *\n * @template EM The mapped element type.\n * @template RM The mapped raw element type used internally by the target structure.\n * @param callback Function with signature `(value, index, self) => mapped`.\n * @param options Optional options for the returned structure, including its `toElementFn`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns A new `IterableElementBase<EM, RM>` containing mapped elements.\n *\n * @remarks\n * Time O(n), Space O(n).\n */\n abstract map<EM, RM>(\n callback: ElementCallback<E, R, EM>,\n options?: IterableElementBaseOptions<EM, RM>,\n thisArg?: unknown\n ): IterableElementBase<EM, RM>;\n\n /**\n * Maps each element to the same element type and returns the same concrete structure type.\n *\n * @param callback Function with signature `(value, index, self) => mappedValue`.\n * @param thisArg Optional `this` binding for the callback.\n * @returns A new instance of the same concrete type with mapped elements.\n *\n * @remarks\n * Time O(n), Space O(n).\n */\n abstract mapSame(callback: ElementCallback<E, R, E>, thisArg?: unknown): this;\n\n /**\n * Filters elements using the provided predicate and returns the same concrete structure type.\n *\n * @param predicate Function with signature `(value, index, self) => boolean`.\n * @param thisArg Optional `this` binding for the predicate.\n * @returns A new instance of the same concrete type containing only elements that pass the predicate.\n *\n * @remarks\n * Time O(n), Space O(k) where `k` is the number of kept elements.\n */\n abstract filter(predicate: ElementCallback<E, R, boolean>, thisArg?: unknown): this;\n\n /**\n * Internal iterator factory used by the default iterator.\n *\n * @param args Optional iterator arguments.\n * @returns An iterator over elements.\n *\n * @remarks\n * Implementations should yield in O(1) per element with O(1) extra space when possible.\n */\n protected abstract _getIterator(...args: unknown[]): IterableIterator<E>;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { ElementCallback, TrieOptions } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { ERR, raise } from '../../common';\n\n/**\n * Node used by Trie to store one character and its children.\n * @remarks Time O(1), Space O(1)\n */\nexport class TrieNode {\n /**\n * Create a Trie node with a character key.\n * @remarks Time O(1), Space O(1)\n * @returns New TrieNode instance.\n */\n\n constructor(key: string) {\n this._key = key;\n this._isEnd = false;\n this._children = new Map<string, TrieNode>();\n }\n\n protected _key: string;\n\n /**\n * Get the character key of this node.\n * @remarks Time O(1), Space O(1)\n * @returns Character key string.\n */\n\n get key(): string {\n return this._key;\n }\n\n /**\n * Set the character key of this node.\n * @remarks Time O(1), Space O(1)\n * @param value - New character key.\n * @returns void\n */\n\n set key(value: string) {\n this._key = value;\n }\n\n protected _children: Map<string, TrieNode>;\n\n /**\n * Get the child map of this node.\n * @remarks Time O(1), Space O(1)\n * @returns Map from character to child node.\n */\n\n get children(): Map<string, TrieNode> {\n return this._children;\n }\n\n /**\n * Replace the child map of this node.\n * @remarks Time O(1), Space O(1)\n * @param value - New map of character → node.\n * @returns void\n */\n\n set children(value: Map<string, TrieNode>) {\n this._children = value;\n }\n\n protected _isEnd: boolean;\n\n /**\n * Check whether this node marks the end of a word.\n * @remarks Time O(1), Space O(1)\n * @returns True if this node ends a word.\n */\n\n get isEnd(): boolean {\n return this._isEnd;\n }\n\n /**\n * Mark this node as the end of a word or not.\n * @remarks Time O(1), Space O(1)\n * @param value - Whether this node ends a word.\n * @returns void\n */\n\n set isEnd(value: boolean) {\n this._isEnd = value;\n }\n}\n\n/**\n * Prefix tree (Trie) for fast prefix queries and word storage.\n * @remarks Time O(1), Space O(1)\n * @template R\n * 1. Node Structure: Each node in a Trie represents a string (or a part of a string). The root node typically represents an empty string.\n * 2. Child Node Relationship: Each node's children represent the strings that can be formed by adding one character to the string at the current node. For example, if a node represents the string 'ca', one of its children might represent 'cat'.\n * 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.\n * 4. Space Efficiency: Trie can store a large number of strings very space-efficiently, especially when these strings share common prefixes.\n * 5. Autocomplete and Prediction: Trie can be used for implementing autocomplete and word prediction features, as it can quickly find all strings with a common prefix.\n * 6. Sorting: Trie can be used to sort a set of strings in alphabetical order.\n * 7. String Retrieval: For example, searching for a specific string in a large set of strings.\n * 8. Autocomplete: Providing recommended words or phrases as a user types.\n * 9. Spell Check: Checking the spelling of words.\n * 10. IP Routing: Used in certain types of IP routing algorithms.\n * 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.\n * @example\n * // Trie isPrefix and isAbsolutePrefix checks\n * const trie = new Trie(['tree', 'trial', 'trick', 'trip', 'trie']);\n *\n * // Check if string is a prefix of any word\n * console.log(trie.hasPrefix('tri')); // true;\n * console.log(trie.hasPrefix('tr')); // true;\n * console.log(trie.hasPrefix('xyz')); // false;\n *\n * // Check if string is an absolute prefix (not a complete word)\n * console.log(trie.hasPurePrefix('tri')); // true;\n * console.log(trie.hasPurePrefix('tree')); // false; // 'tree' is a complete word\n *\n * // Verify size\n * console.log(trie.size); // 5;\n * @example\n * // Trie for autocomplete search index\n * // Trie is perfect for autocomplete: O(m + k) where m is prefix length, k is results\n * const searchIndex = new Trie(['typescript', 'javascript', 'python', 'java', 'rust', 'ruby', 'golang', 'kotlin']);\n *\n * // User types 'j' - get all suggestions\n * const jResults = searchIndex.getWords('j');\n * console.log(jResults); // contains 'javascript';\n * console.log(jResults); // contains 'java';\n * console.log(jResults.length); // 2;\n *\n * // User types 'ja' - get more specific suggestions\n * const jaResults = searchIndex.getWords('ja');\n * console.log(jaResults); // contains 'javascript';\n * console.log(jaResults); // contains 'java';\n * console.log(jaResults.length); // 2;\n *\n * // User types 'jav' - even more specific\n * const javResults = searchIndex.getWords('jav');\n * console.log(javResults); // contains 'javascript';\n * console.log(javResults); // contains 'java';\n * console.log(javResults.length); // 2;\n *\n * // Check for common prefix\n *\n * console.log(searchIndex.hasCommonPrefix('ja')); // false; // Not all words start with 'ja'\n *\n * // Total words in index\n * console.log(searchIndex.size); // 8;\n *\n * // Get height (depth of tree)\n * const height = searchIndex.getHeight();\n * console.log(typeof height); // 'number';\n * @example\n * // Dictionary: Case-insensitive word lookup\n * // Create a case-insensitive dictionary\n * const dictionary = new Trie<string>([], { caseSensitive: false });\n *\n * // Add words with mixed casing\n * dictionary.add('Hello');\n * dictionary.add('WORLD');\n * dictionary.add('JavaScript');\n *\n * // Test lookups with different casings\n * console.log(dictionary.has('hello')); // true;\n * console.log(dictionary.has('HELLO')); // true;\n * console.log(dictionary.has('Hello')); // true;\n * console.log(dictionary.has('javascript')); // true;\n * console.log(dictionary.has('JAVASCRIPT')); // true;\n * @example\n * // File System Path Operations\n * const fileSystem = new Trie<string>([\n * '/home/user/documents/file1.txt',\n * '/home/user/documents/file2.txt',\n * '/home/user/pictures/photo.jpg',\n * '/home/user/pictures/vacation/',\n * '/home/user/downloads'\n * ]);\n *\n * // Find common directory prefix\n * console.log(fileSystem.getLongestCommonPrefix()); // '/home/user/';\n *\n * // List all files in a directory\n * const documentsFiles = fileSystem.getWords('/home/user/documents/');\n * console.log(documentsFiles); // ['/home/user/documents/file1.txt', '/home/user/documents/file2.txt'];\n * @example\n * // IP Address Routing Table\n * // Add IP address prefixes and their corresponding routes\n * const routes = {\n * '192.168.1': 'LAN_SUBNET_1',\n * '192.168.2': 'LAN_SUBNET_2',\n * '10.0.0': 'PRIVATE_NETWORK_1',\n * '10.0.1': 'PRIVATE_NETWORK_2'\n * };\n *\n * const ipRoutingTable = new Trie<string>(Object.keys(routes));\n *\n * // Check IP address prefix matching\n * console.log(ipRoutingTable.hasPrefix('192.168.1')); // true;\n * console.log(ipRoutingTable.hasPrefix('192.168.2')); // true;\n *\n * // Validate IP address belongs to subnet\n * const ip = '192.168.1.100';\n * const subnet = ip.split('.').slice(0, 3).join('.');\n * console.log(ipRoutingTable.hasPrefix(subnet)); // true;\n */\nexport class Trie<R = any> extends IterableElementBase<string, R> {\n /**\n * Create a Trie and optionally bulk-insert words.\n * @remarks Time O(totalChars), Space O(totalChars)\n * @param [words] - Iterable of strings (or raw records if toElementFn is provided).\n * @param [options] - Options such as toElementFn and caseSensitive.\n * @returns New Trie instance.\n */\n\n constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {\n super(options);\n if (options) {\n const { caseSensitive } = options;\n if (caseSensitive !== undefined) this._caseSensitive = caseSensitive;\n }\n if (words) {\n this.addMany(words);\n }\n }\n\n protected _size: number = 0;\n\n /**\n * Get the number of stored words.\n * @remarks Time O(1), Space O(1)\n * @returns Word count.\n */\n\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean = true;\n\n /**\n * Get whether comparisons are case-sensitive.\n * @remarks Time O(1), Space O(1)\n * @returns True if case-sensitive.\n */\n\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode = new TrieNode('');\n\n /**\n * Get the root node.\n * @remarks Time O(1), Space O(1)\n * @returns Root TrieNode.\n */\n\n get root() {\n return this._root;\n }\n\n /**\n * (Protected) Get total count for base class iteration.\n * @remarks Time O(1), Space O(1)\n * @returns Total number of elements.\n */\n\n protected get _total() {\n return this._size;\n }\n\n /**\n * Insert one word into the trie.\n * @remarks Time O(L), Space O(L)\n * @param word - Word to insert.\n * @returns True if the word was newly added.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // basic Trie creation and add words\n * // Create a simple Trie with initial words\n * const trie = new Trie(['apple', 'app', 'apply']);\n *\n * // Verify size\n * console.log(trie.size); // 3;\n *\n * // Check if words exist\n * console.log(trie.has('apple')); // true;\n * console.log(trie.has('app')); // true;\n *\n * // Add a new word\n * trie.add('application');\n * console.log(trie.size); // 4;\n */\n\n add(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n let isNewWord = false;\n for (const c of word) {\n let nodeC = cur.children.get(c);\n if (!nodeC) {\n nodeC = new TrieNode(c);\n cur.children.set(c, nodeC);\n }\n cur = nodeC;\n }\n if (!cur.isEnd) {\n isNewWord = true;\n cur.isEnd = true;\n this._size++;\n }\n return isNewWord;\n }\n\n /**\n * Insert many words from an iterable.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param words - Iterable of strings (or raw records if toElementFn is provided).\n * @returns Array of per-word 'added' flags.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Add multiple words\n * const trie = new Trie();\n * trie.addMany(['cat', 'car', 'card']);\n * console.log(trie.has('cat')); // true;\n * console.log(trie.has('car')); // true;\n * console.log(trie.size); // 3;\n */\n\n addMany(words: Iterable<string> | Iterable<R>): boolean[] {\n const ans: boolean[] = [];\n for (const word of words) {\n if (this.toElementFn) {\n ans.push(this.add(this.toElementFn(word as R)));\n } else {\n ans.push(this.add(word as string));\n }\n }\n return ans;\n }\n\n /**\n * Check whether a word exists.\n * @remarks Time O(L), Space O(1)\n * @param word - Word to search for.\n * @returns True if present.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if a word exists\n * const dict = new Trie(['apple', 'app', 'application']);\n *\n * console.log(dict.has('app')); // true;\n * console.log(dict.has('apple')); // true;\n * console.log(dict.has('ap')); // false;\n */\n\n override has(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n for (const c of word) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return cur.isEnd;\n }\n\n /**\n * Check whether the trie is empty.\n * @remarks Time O(1), Space O(1)\n * @returns True if size is 0.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if empty\n * const trie = new Trie();\n * console.log(trie.isEmpty()); // true;\n * trie.add('word');\n * console.log(trie.isEmpty()); // false;\n */\n\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Remove all words and reset to a fresh root.\n * @remarks Time O(1), Space O(1)\n * @returns void\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Remove all words\n * const trie = new Trie(['a', 'b', 'c']);\n * trie.clear();\n * console.log(trie.isEmpty()); // true;\n */\n\n clear(): void {\n this._size = 0;\n this._root = new TrieNode('');\n }\n\n /**\n * Delete one word if present.\n * @remarks Time O(L), Space O(1)\n * @param word - Word to delete.\n * @returns True if a word was removed.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Trie delete and iteration\n * const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);\n *\n * // Delete a word\n * trie.delete('card');\n * console.log(trie.has('card')); // false;\n *\n * // Word with same prefix still exists\n * console.log(trie.has('care')); // true;\n *\n * // Size decreased\n * console.log(trie.size); // 5;\n *\n * // Iterate through all words\n * const allWords = [...trie];\n * console.log(allWords.length); // 5;\n */\n\n delete(word: string): boolean {\n word = this._caseProcess(word);\n let isDeleted = false;\n const dfs = (cur: TrieNode, i: number): boolean => {\n const char = word[i];\n const child = cur.children.get(char);\n if (child) {\n if (i === word.length - 1) {\n if (child.isEnd) {\n if (child.children.size > 0) {\n child.isEnd = false;\n } else {\n cur.children.delete(char);\n }\n isDeleted = true;\n return true;\n }\n return false;\n }\n const res = dfs(child, i + 1);\n if (res && !cur.isEnd && child.children.size === 0) {\n cur.children.delete(char);\n return true;\n }\n return false;\n }\n return false;\n };\n\n dfs(this.root, 0);\n if (isDeleted) {\n this._size--;\n }\n return isDeleted;\n }\n\n /**\n * Compute the height (max depth) of the trie.\n * @remarks Time O(N), Space O(H)\n * @returns Maximum depth from root to a leaf.\n */\n\n getHeight(): number {\n const startNode = this.root;\n let maxDepth = 0;\n if (startNode) {\n const bfs = (node: TrieNode, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { children } = node;\n if (children) {\n for (const child of children.entries()) {\n bfs(child[1], level + 1);\n }\n }\n };\n bfs(startNode, 0);\n }\n return maxDepth;\n }\n\n /**\n * Check whether input is a proper prefix of at least one word.\n * @remarks Time O(L), Space O(1)\n * @param input - String to test as prefix.\n * @returns True if input is a prefix but not a full word.\n */\n\n hasPurePrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return !cur.isEnd;\n }\n\n /**\n * Check whether any word starts with input.\n * @remarks Time O(L), Space O(1)\n * @param input - String to test as prefix.\n * @returns True if input matches a path from root.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Check if a prefix exists\n * const trie = new Trie(['hello', 'help', 'world']);\n *\n * console.log(trie.hasPrefix('hel')); // true;\n * console.log(trie.hasPrefix('wor')); // true;\n * console.log(trie.hasPrefix('xyz')); // false;\n */\n\n hasPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return true;\n }\n\n /**\n * Check whether the trie’s longest common prefix equals input.\n * @remarks Time O(min(H,L)), Space O(1)\n * @param input - Candidate longest common prefix.\n * @returns True if input equals the common prefix.\n */\n\n hasCommonPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (commonPre === input) return;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre === input;\n }\n\n /**\n * Return the longest common prefix among all words.\n * @remarks Time O(H), Space O(1)\n * @returns The longest common prefix string.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Find shared prefix\n * const trie = new Trie(['flower', 'flow', 'flight']);\n *\n * console.log(trie.getLongestCommonPrefix()); // 'fl';\n */\n\n getLongestCommonPrefix(): string {\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre;\n }\n\n /**\n * Collect words under a prefix up to a maximum count.\n * @remarks Time O(K·L), Space O(K·L)\n * @param [prefix] - Prefix to match; default empty string for root.\n * @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.\n * @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.\n * @returns Array of collected words (at most max).\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Trie getWords and prefix search\n * const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);\n *\n * // Get all words with prefix 'app'\n * const appWords = trie.getWords('app');\n * console.log(appWords); // contains 'app';\n * console.log(appWords); // contains 'apple';\n * console.log(appWords); // contains 'apply';\n * console.log(appWords); // contains 'application';\n * expect(appWords).not.toContain('apricot');\n */\n\n getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {\n prefix = this._caseProcess(prefix);\n const words: string[] = [];\n let found = 0;\n\n const dfs = (node: TrieNode, word: string): void => {\n for (const [char, childNode] of node.children) {\n if (found >= max) return;\n dfs(childNode, word + char);\n }\n if (node.isEnd) {\n if (found >= max) return;\n words.push(word);\n found++;\n }\n };\n\n let startNode = this.root;\n\n if (prefix) {\n for (const c of prefix) {\n const nodeC = startNode.children.get(c);\n if (nodeC) {\n startNode = nodeC;\n } else {\n return [];\n }\n }\n }\n\n if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);\n\n return words;\n }\n\n /**\n * Deep clone this trie by iterating and inserting all words.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @returns A new trie with the same words and options.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Create independent copy\n * const trie = new Trie(['hello', 'world']);\n * const copy = trie.clone();\n * copy.delete('hello');\n * console.log(trie.has('hello')); // true;\n */\n\n clone(): this {\n const next = this._createInstance();\n for (const x of this) next.add(x);\n return next;\n }\n\n /**\n * Filter words into a new trie of the same class.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param predicate - Predicate (word, index, trie) → boolean to keep word.\n * @param [thisArg] - Value for `this` inside the predicate.\n * @returns A new trie containing words that satisfy the predicate.\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Filter words\n * const trie = new Trie(['cat', 'car', 'dog', 'card']);\n * const result = trie.filter(w => w.startsWith('ca'));\n * console.log(result.size); // 3;\n */\n\n filter(predicate: ElementCallback<string, R, boolean>, thisArg?: unknown): this {\n const results = this._createInstance();\n let index = 0;\n for (const word of this) {\n if (predicate.call(thisArg, word, index, this)) {\n results.add(word);\n }\n index++;\n }\n return results;\n }\n\n /**\n * Transform words\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n * @example\n * // Transform words\n * const trie = new Trie(['hello', 'world']);\n * const upper = trie.map(w => w.toUpperCase());\n * console.log(upper.has('HELLO')); // true;\n */\n map<RM>(callback: ElementCallback<string, R, string>, options?: TrieOptions<RM>, thisArg?: unknown): Trie<RM>;\n\n /**\n * Map words into a new trie (possibly different record type).\n * @remarks Time O(ΣL), Space O(ΣL)\n * @template EM\n * @template RM\n * @param callback - Mapping function (word, index, trie) → newWord (string).\n * @param [options] - Options for the output trie (e.g., toElementFn, caseSensitive).\n * @param [thisArg] - Value for `this` inside the callback.\n * @returns A new Trie constructed from mapped words.\n */\n\n map<EM, RM>(\n callback: ElementCallback<string, R, EM>,\n options?: TrieOptions<RM>,\n thisArg?: unknown\n ): IterableElementBase<EM, RM>;\n\n map<EM, RM>(callback: ElementCallback<string, R, EM>, options?: TrieOptions<RM>, thisArg?: unknown): any {\n const newTrie = this._createLike<RM>([], options);\n let i = 0;\n for (const x of this) {\n const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);\n if (typeof v !== 'string') {\n raise(TypeError, ERR.callbackReturnType('string', typeof v, 'Trie.map'));\n }\n newTrie.add(v);\n }\n return newTrie;\n }\n\n /**\n * Map words into a new trie of the same element type.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @param callback - Mapping function (word, index, trie) → string.\n * @param [thisArg] - Value for `this` inside the callback.\n * @returns A new trie with mapped words.\n */\n\n mapSame(callback: ElementCallback<string, R, string>, thisArg?: unknown): this {\n const next = this._createInstance();\n let i = 0;\n for (const key of this) {\n const mapped = thisArg === undefined ? callback(key, i++, this) : callback.call(thisArg, key, i++, this);\n next.add(mapped);\n }\n return next;\n }\n\n /**\n * (Protected) Create an empty instance of the same concrete class.\n * @remarks Time O(1), Space O(1)\n * @param [options] - Options forwarded to the constructor.\n * @returns An empty like-kind trie instance.\n */\n\n protected _createInstance(options?: TrieOptions<R>): this {\n const Ctor = this.constructor as new (\n elements?: Iterable<string> | Iterable<R>,\n options?: TrieOptions<R>\n ) => this;\n return new Ctor([], {\n toElementFn: this.toElementFn,\n caseSensitive: this.caseSensitive,\n ...(options ?? {})\n });\n }\n\n /**\n * (Protected) Create a like-kind trie and seed it from an iterable.\n * @remarks Time O(ΣL), Space O(ΣL)\n * @template RM\n * @param [elements] - Iterable used to seed the new trie.\n * @param [options] - Options forwarded to the constructor.\n * @returns A like-kind Trie instance.\n */\n\n protected _createLike<RM>(elements: Iterable<string> | Iterable<RM> = [], options?: TrieOptions<RM>): Trie<RM> {\n const Ctor = this.constructor as new (\n elements?: Iterable<string> | Iterable<RM>,\n options?: TrieOptions<RM>\n ) => Trie<RM>;\n return new Ctor(elements, options);\n }\n\n /**\n * (Protected) Spawn an empty like-kind trie instance.\n * @remarks Time O(1), Space O(1)\n * @template RM\n * @param [options] - Options forwarded to the constructor.\n * @returns An empty like-kind Trie instance.\n */\n\n protected _spawnLike<RM>(options?: TrieOptions<RM>): Trie<RM> {\n return this._createLike<RM>([], options);\n }\n\n /**\n * (Protected) Iterate all words in lexicographic order of edges.\n * @remarks Time O(ΣL), Space O(H)\n * @returns Iterator of words.\n */\n\n protected *_getIterator(): IterableIterator<string> {\n function* _dfs(node: TrieNode, path: string): IterableIterator<string> {\n if (node.isEnd) {\n yield path;\n }\n for (const [char, childNode] of node.children) {\n yield* _dfs(childNode, path + char);\n }\n }\n\n yield* _dfs(this.root, '');\n }\n\n /**\n * (Protected) Normalize a string according to case sensitivity.\n * @remarks Time O(L), Space O(L)\n * @param str - Input string to normalize.\n * @returns Normalized string based on caseSensitive.\n */\n\n protected _caseProcess(str: string) {\n if (!this._caseSensitive) {\n str = str.toLowerCase();\n }\n return str;\n }\n}\n"],"mappings":"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","names":["DFSOperation"]}