data-structure-typed 2.4.4 → 2.4.5

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 (41) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +24 -1
  3. package/dist/cjs/index.cjs +459 -132
  4. package/dist/cjs-legacy/index.cjs +459 -130
  5. package/dist/esm/index.mjs +459 -133
  6. package/dist/esm-legacy/index.mjs +459 -131
  7. package/dist/types/common/error.d.ts +23 -0
  8. package/dist/types/common/index.d.ts +1 -0
  9. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +10 -0
  10. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
  11. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  12. package/dist/types/data-structures/graph/directed-graph.d.ts +1 -0
  13. package/dist/types/data-structures/graph/undirected-graph.d.ts +14 -0
  14. package/dist/types/data-structures/queue/deque.d.ts +41 -1
  15. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  16. package/dist/umd/data-structure-typed.js +458 -129
  17. package/dist/umd/data-structure-typed.min.js +4 -2
  18. package/package.json +2 -2
  19. package/src/common/error.ts +60 -0
  20. package/src/common/index.ts +2 -0
  21. package/src/data-structures/base/iterable-element-base.ts +3 -2
  22. package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
  23. package/src/data-structures/binary-tree/binary-tree.ts +113 -42
  24. package/src/data-structures/binary-tree/bst.ts +11 -3
  25. package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
  26. package/src/data-structures/binary-tree/tree-map.ts +8 -7
  27. package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
  28. package/src/data-structures/binary-tree/tree-multi-set.ts +5 -4
  29. package/src/data-structures/binary-tree/tree-set.ts +7 -6
  30. package/src/data-structures/graph/abstract-graph.ts +106 -1
  31. package/src/data-structures/graph/directed-graph.ts +4 -0
  32. package/src/data-structures/graph/undirected-graph.ts +95 -0
  33. package/src/data-structures/hash/hash-map.ts +13 -2
  34. package/src/data-structures/heap/heap.ts +4 -3
  35. package/src/data-structures/heap/max-heap.ts +2 -3
  36. package/src/data-structures/matrix/matrix.ts +9 -10
  37. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
  38. package/src/data-structures/queue/deque.ts +71 -3
  39. package/src/data-structures/trie/trie.ts +2 -1
  40. package/src/types/data-structures/queue/deque.ts +7 -0
  41. package/src/utils/utils.ts +4 -2
@@ -191,6 +191,54 @@ var _IterableEntryBase = class _IterableEntryBase {
191
191
  __name(_IterableEntryBase, "IterableEntryBase");
192
192
  var IterableEntryBase = _IterableEntryBase;
193
193
 
194
+ // src/common/error.ts
195
+ var ERR = {
196
+ // Range / index
197
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
198
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
199
+ // Type / argument
200
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
201
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
202
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
203
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
204
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
205
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
206
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
207
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
208
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
209
+ // State / operation
210
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
211
+ // Matrix
212
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
213
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
214
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
215
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
216
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
217
+ };
218
+
219
+ // src/common/index.ts
220
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
221
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
222
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
223
+ return DFSOperation2;
224
+ })(DFSOperation || {});
225
+ var _Range = class _Range {
226
+ constructor(low, high, includeLow = true, includeHigh = true) {
227
+ this.low = low;
228
+ this.high = high;
229
+ this.includeLow = includeLow;
230
+ this.includeHigh = includeHigh;
231
+ }
232
+ // Determine whether a key is within the range
233
+ isInRange(key, comparator) {
234
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
235
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
236
+ return lowCheck && highCheck;
237
+ }
238
+ };
239
+ __name(_Range, "Range");
240
+ var Range = _Range;
241
+
194
242
  // src/data-structures/base/iterable-element-base.ts
195
243
  var _IterableElementBase = class _IterableElementBase {
196
244
  /**
@@ -213,7 +261,7 @@ var _IterableElementBase = class _IterableElementBase {
213
261
  if (options) {
214
262
  const { toElementFn } = options;
215
263
  if (typeof toElementFn === "function") this._toElementFn = toElementFn;
216
- else if (toElementFn) throw new TypeError("toElementFn must be a function type");
264
+ else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
217
265
  }
218
266
  }
219
267
  /**
@@ -369,7 +417,7 @@ var _IterableElementBase = class _IterableElementBase {
369
417
  acc = initialValue;
370
418
  } else {
371
419
  const first = iter.next();
372
- if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
420
+ if (first.done) throw new TypeError(ERR.reduceEmpty());
373
421
  acc = first.value;
374
422
  index = 1;
375
423
  }
@@ -439,8 +487,10 @@ var getMSB = /* @__PURE__ */ __name((value) => {
439
487
  }
440
488
  return 1 << 31 - Math.clz32(value);
441
489
  }, "getMSB");
442
- var rangeCheck = /* @__PURE__ */ __name((index, min, max, message = "Index out of bounds.") => {
443
- if (index < min || index > max) throw new RangeError(message);
490
+ var rangeCheck = /* @__PURE__ */ __name((index, min, max, message) => {
491
+ if (index < min || index > max) {
492
+ throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
493
+ }
444
494
  }, "rangeCheck");
445
495
  var throwRangeError = /* @__PURE__ */ __name((message = "The value is off-limits.") => {
446
496
  throw new RangeError(message);
@@ -812,8 +862,8 @@ var _LinkedHashMap = class _LinkedHashMap extends IterableEntryBase {
812
862
  if (this.isEntry(rawElement)) {
813
863
  return rawElement;
814
864
  }
815
- throw new Error(
816
- "If `entryOrRawElements` does not adhere to [key,value], provide `options.toEntryFn` to transform raw records."
865
+ throw new TypeError(
866
+ ERR.invalidArgument("If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.", "HashMap")
817
867
  );
818
868
  }, "_toEntryFn"));
819
869
  __publicField(this, "_size", 0);
@@ -1098,6 +1148,13 @@ var _LinkedHashMap = class _LinkedHashMap extends IterableEntryBase {
1098
1148
  }
1099
1149
  }
1100
1150
  _deleteNode(node) {
1151
+ const key = node.key;
1152
+ if (isWeakKey(key)) {
1153
+ this._objMap.delete(key);
1154
+ } else {
1155
+ const hash = this._hashFn(key);
1156
+ delete this._noObjMap[hash];
1157
+ }
1101
1158
  const { prev, next } = node;
1102
1159
  prev.next = next;
1103
1160
  next.prev = prev;
@@ -3605,17 +3662,16 @@ var LinkedListQueue = _LinkedListQueue;
3605
3662
 
3606
3663
  // src/data-structures/queue/deque.ts
3607
3664
  var _Deque = class _Deque extends LinearBase {
3608
- /**
3609
- * Create a Deque and optionally bulk-insert elements.
3610
- * @remarks Time O(N), Space O(N)
3611
- * @param [elements] - Iterable (or iterable-like) of elements/records to insert.
3612
- * @param [options] - Options such as bucketSize, toElementFn, and maxLen.
3613
- * @returns New Deque instance.
3614
- */
3615
3665
  constructor(elements = [], options) {
3616
3666
  super(options);
3617
3667
  __publicField(this, "_equals", /* @__PURE__ */ __name((a, b) => Object.is(a, b), "_equals"));
3618
3668
  __publicField(this, "_bucketSize", 1 << 12);
3669
+ __publicField(this, "_autoCompactRatio", 0.5);
3670
+ /**
3671
+ * Counter for shift/pop operations since last compaction check.
3672
+ * Only checks ratio every `_bucketSize` operations to minimize overhead.
3673
+ */
3674
+ __publicField(this, "_compactCounter", 0);
3619
3675
  __publicField(this, "_bucketFirst", 0);
3620
3676
  __publicField(this, "_firstInBucket", 0);
3621
3677
  __publicField(this, "_bucketLast", 0);
@@ -3624,8 +3680,9 @@ var _Deque = class _Deque extends LinearBase {
3624
3680
  __publicField(this, "_buckets", []);
3625
3681
  __publicField(this, "_length", 0);
3626
3682
  if (options) {
3627
- const { bucketSize } = options;
3683
+ const { bucketSize, autoCompactRatio } = options;
3628
3684
  if (typeof bucketSize === "number") this._bucketSize = bucketSize;
3685
+ if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
3629
3686
  }
3630
3687
  let _size;
3631
3688
  if ("length" in elements) {
@@ -3650,6 +3707,24 @@ var _Deque = class _Deque extends LinearBase {
3650
3707
  get bucketSize() {
3651
3708
  return this._bucketSize;
3652
3709
  }
3710
+ /**
3711
+ * Get the auto-compaction ratio.
3712
+ * When `elements / (bucketCount * bucketSize)` drops below this ratio after
3713
+ * enough shift/pop operations, the deque auto-compacts.
3714
+ * @remarks Time O(1), Space O(1)
3715
+ * @returns Current ratio threshold. 0 means auto-compact is disabled.
3716
+ */
3717
+ get autoCompactRatio() {
3718
+ return this._autoCompactRatio;
3719
+ }
3720
+ /**
3721
+ * Set the auto-compaction ratio.
3722
+ * @remarks Time O(1), Space O(1)
3723
+ * @param value - Ratio in [0,1]. 0 disables auto-compact.
3724
+ */
3725
+ set autoCompactRatio(value) {
3726
+ this._autoCompactRatio = value;
3727
+ }
3653
3728
  /**
3654
3729
  * Get the index of the first bucket in use.
3655
3730
  * @remarks Time O(1), Space O(1)
@@ -3781,6 +3856,7 @@ var _Deque = class _Deque extends LinearBase {
3781
3856
  }
3782
3857
  }
3783
3858
  this._length -= 1;
3859
+ this._autoCompact();
3784
3860
  return element;
3785
3861
  }
3786
3862
  /**
@@ -3803,6 +3879,7 @@ var _Deque = class _Deque extends LinearBase {
3803
3879
  }
3804
3880
  }
3805
3881
  this._length -= 1;
3882
+ this._autoCompact();
3806
3883
  return element;
3807
3884
  }
3808
3885
  /**
@@ -4135,11 +4212,40 @@ var _Deque = class _Deque extends LinearBase {
4135
4212
  * @remarks Time O(N), Space O(1)
4136
4213
  * @returns void
4137
4214
  */
4215
+ /**
4216
+ * (Protected) Trigger auto-compaction if space utilization drops below threshold.
4217
+ * Only checks every `_bucketSize` operations to minimize hot-path overhead.
4218
+ * Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
4219
+ */
4220
+ _autoCompact() {
4221
+ if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
4222
+ this._compactCounter++;
4223
+ if (this._compactCounter < this._bucketSize) return;
4224
+ this._compactCounter = 0;
4225
+ const utilization = this._length / (this._bucketCount * this._bucketSize);
4226
+ if (utilization < this._autoCompactRatio) {
4227
+ this.shrinkToFit();
4228
+ }
4229
+ }
4230
+ /**
4231
+ * Compact the deque by removing unused buckets.
4232
+ * @remarks Time O(N), Space O(1)
4233
+ * @returns True if compaction was performed (bucket count reduced).
4234
+ */
4235
+ /**
4236
+ * Compact the deque by removing unused buckets.
4237
+ * @remarks Time O(N), Space O(1)
4238
+ * @returns True if compaction was performed (bucket count reduced).
4239
+ */
4240
+ compact() {
4241
+ const before = this._bucketCount;
4242
+ this.shrinkToFit();
4243
+ return this._bucketCount < before;
4244
+ }
4138
4245
  shrinkToFit() {
4139
4246
  if (this._length === 0) return;
4140
4247
  const newBuckets = [];
4141
- if (this._bucketFirst === this._bucketLast) return;
4142
- else if (this._bucketFirst < this._bucketLast) {
4248
+ if (this._bucketFirst <= this._bucketLast) {
4143
4249
  for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
4144
4250
  newBuckets.push(this._buckets[i]);
4145
4251
  }
@@ -4154,6 +4260,8 @@ var _Deque = class _Deque extends LinearBase {
4154
4260
  this._bucketFirst = 0;
4155
4261
  this._bucketLast = newBuckets.length - 1;
4156
4262
  this._buckets = newBuckets;
4263
+ this._bucketCount = newBuckets.length;
4264
+ this._compactCounter = 0;
4157
4265
  }
4158
4266
  /**
4159
4267
  * Deep clone this deque, preserving options.
@@ -4351,7 +4459,7 @@ var _Heap = class _Heap extends IterableElementBase {
4351
4459
  __publicField(this, "_elements", []);
4352
4460
  __publicField(this, "_DEFAULT_COMPARATOR", /* @__PURE__ */ __name((a, b) => {
4353
4461
  if (typeof a === "object" || typeof b === "object") {
4354
- throw TypeError("When comparing object types, define a custom comparator in options.");
4462
+ throw new TypeError(ERR.comparatorRequired("Heap"));
4355
4463
  }
4356
4464
  if (a > b) return 1;
4357
4465
  if (a < b) return -1;
@@ -4661,7 +4769,7 @@ var _Heap = class _Heap extends IterableElementBase {
4661
4769
  */
4662
4770
  map(callback, options, thisArg) {
4663
4771
  const { comparator, toElementFn, ...rest } = options != null ? options : {};
4664
- if (!comparator) throw new TypeError("Heap.map requires options.comparator for EM");
4772
+ if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
4665
4773
  const out = this._createLike([], { ...rest, comparator, toElementFn });
4666
4774
  let i = 0;
4667
4775
  for (const x of this) {
@@ -4793,7 +4901,7 @@ var _FibonacciHeap = class _FibonacciHeap {
4793
4901
  __publicField(this, "_comparator");
4794
4902
  this.clear();
4795
4903
  this._comparator = comparator || this._defaultComparator;
4796
- if (typeof this.comparator !== "function") throw new Error("FibonacciHeap: comparator must be a function.");
4904
+ if (typeof this.comparator !== "function") throw new TypeError(ERR.notAFunction("comparator", "FibonacciHeap"));
4797
4905
  }
4798
4906
  /**
4799
4907
  * Get the circular root list head.
@@ -5004,9 +5112,7 @@ var _MaxHeap = class _MaxHeap extends Heap {
5004
5112
  super(elements, {
5005
5113
  comparator: /* @__PURE__ */ __name((a, b) => {
5006
5114
  if (typeof a === "object" || typeof b === "object") {
5007
- throw TypeError(
5008
- `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
5009
- );
5115
+ throw new TypeError(ERR.comparatorRequired("MaxHeap"));
5010
5116
  }
5011
5117
  if (a < b) return 1;
5012
5118
  if (a > b) return -1;
@@ -5171,7 +5277,7 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
5171
5277
  const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
5172
5278
  return this._addEdge(newEdge);
5173
5279
  } else {
5174
- throw new Error("dest must be a Vertex or vertex key while srcOrEdge is an Edge");
5280
+ throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
5175
5281
  }
5176
5282
  }
5177
5283
  }
@@ -5855,6 +5961,94 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
5855
5961
  _getVertexKey(vertexOrKey) {
5856
5962
  return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
5857
5963
  }
5964
+ /**
5965
+ * The edge connector string used in visual output.
5966
+ * Override in subclasses (e.g., '--' for undirected, '->' for directed).
5967
+ */
5968
+ get _edgeConnector() {
5969
+ return "--";
5970
+ }
5971
+ /**
5972
+ * Generate a text-based visual representation of the graph.
5973
+ *
5974
+ * **Adjacency list format:**
5975
+ * ```
5976
+ * Graph (5 vertices, 6 edges):
5977
+ * A -> B (1), C (2)
5978
+ * B -> D (3)
5979
+ * C -> (no outgoing edges)
5980
+ * D -> A (1)
5981
+ * E (isolated)
5982
+ * ```
5983
+ *
5984
+ * @param options - Optional display settings.
5985
+ * @param options.showWeight - Whether to show edge weights (default: true).
5986
+ * @returns The visual string.
5987
+ */
5988
+ toVisual(options) {
5989
+ var _a;
5990
+ const showWeight = (_a = options == null ? void 0 : options.showWeight) != null ? _a : true;
5991
+ const vertices = [...this._vertexMap.values()];
5992
+ const vertexCount = vertices.length;
5993
+ const edgeCount = this.edgeSet().length;
5994
+ const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
5995
+ for (const vertex of vertices) {
5996
+ const neighbors = this.getNeighbors(vertex);
5997
+ if (neighbors.length === 0) {
5998
+ lines.push(` ${vertex.key} (isolated)`);
5999
+ } else {
6000
+ const edgeStrs = neighbors.map((neighbor) => {
6001
+ const edge = this.getEdge(vertex, neighbor);
6002
+ if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
6003
+ return `${neighbor.key} (${edge.weight})`;
6004
+ }
6005
+ return `${neighbor.key}`;
6006
+ });
6007
+ lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
6008
+ }
6009
+ }
6010
+ return lines.join("\n");
6011
+ }
6012
+ /**
6013
+ * Generate DOT language representation for Graphviz.
6014
+ *
6015
+ * @param options - Optional display settings.
6016
+ * @param options.name - Graph name (default: 'G').
6017
+ * @param options.showWeight - Whether to label edges with weight (default: true).
6018
+ * @returns DOT format string.
6019
+ */
6020
+ toDot(options) {
6021
+ var _a, _b;
6022
+ const name = (_a = options == null ? void 0 : options.name) != null ? _a : "G";
6023
+ const showWeight = (_b = options == null ? void 0 : options.showWeight) != null ? _b : true;
6024
+ const isDirected = this._edgeConnector === "->";
6025
+ const graphType = isDirected ? "digraph" : "graph";
6026
+ const edgeOp = isDirected ? "->" : "--";
6027
+ const lines = [`${graphType} ${name} {`];
6028
+ for (const vertex of this._vertexMap.values()) {
6029
+ lines.push(` "${vertex.key}";`);
6030
+ }
6031
+ const visited = /* @__PURE__ */ new Set();
6032
+ for (const vertex of this._vertexMap.values()) {
6033
+ for (const neighbor of this.getNeighbors(vertex)) {
6034
+ const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
6035
+ if (visited.has(edgeId)) continue;
6036
+ visited.add(edgeId);
6037
+ const edge = this.getEdge(vertex, neighbor);
6038
+ const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
6039
+ lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
6040
+ }
6041
+ }
6042
+ lines.push("}");
6043
+ return lines.join("\n");
6044
+ }
6045
+ /**
6046
+ * Print the graph to console.
6047
+ * @param options - Display settings passed to `toVisual`.
6048
+ */
6049
+ print(options) {
6050
+ console.log(this.toVisual(options));
6051
+ }
5858
6052
  };
5859
6053
  __name(_AbstractGraph, "AbstractGraph");
5860
6054
  var AbstractGraph = _AbstractGraph;
@@ -5889,6 +6083,9 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
5889
6083
  __publicField(this, "_outEdgeMap", /* @__PURE__ */ new Map());
5890
6084
  __publicField(this, "_inEdgeMap", /* @__PURE__ */ new Map());
5891
6085
  }
6086
+ get _edgeConnector() {
6087
+ return "->";
6088
+ }
5892
6089
  get outEdgeMap() {
5893
6090
  return this._outEdgeMap;
5894
6091
  }
@@ -6669,6 +6866,84 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
6669
6866
  cutVertices
6670
6867
  };
6671
6868
  }
6869
+ /**
6870
+ * Find biconnected components using edge-stack Tarjan variant.
6871
+ * A biconnected component is a maximal biconnected subgraph.
6872
+ * @returns Array of edge arrays, each representing a biconnected component.
6873
+ * @remarks Time O(V + E), Space O(V + E)
6874
+ */
6875
+ getBiconnectedComponents() {
6876
+ const dfn = /* @__PURE__ */ new Map();
6877
+ const low = /* @__PURE__ */ new Map();
6878
+ const edgeStack = [];
6879
+ const components = [];
6880
+ let time = 0;
6881
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
6882
+ dfn.set(vertex, time);
6883
+ low.set(vertex, time);
6884
+ time++;
6885
+ const neighbors = this.getNeighbors(vertex);
6886
+ let childCount = 0;
6887
+ for (const neighbor of neighbors) {
6888
+ const edge = this.getEdge(vertex, neighbor);
6889
+ if (!edge) continue;
6890
+ if (!dfn.has(neighbor)) {
6891
+ childCount++;
6892
+ edgeStack.push(edge);
6893
+ dfs(neighbor, vertex);
6894
+ low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
6895
+ if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
6896
+ const component = [];
6897
+ let e;
6898
+ do {
6899
+ e = edgeStack.pop();
6900
+ if (e) component.push(e);
6901
+ } while (e && e !== edge);
6902
+ if (component.length > 0) components.push(component);
6903
+ }
6904
+ } else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
6905
+ edgeStack.push(edge);
6906
+ low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
6907
+ }
6908
+ }
6909
+ }, "dfs");
6910
+ for (const vertex of this.vertexMap.values()) {
6911
+ if (!dfn.has(vertex)) {
6912
+ dfs(vertex, void 0);
6913
+ if (edgeStack.length > 0) {
6914
+ components.push([...edgeStack]);
6915
+ edgeStack.length = 0;
6916
+ }
6917
+ }
6918
+ }
6919
+ return components;
6920
+ }
6921
+ /**
6922
+ * Detect whether the graph contains a cycle.
6923
+ * Uses DFS with parent tracking.
6924
+ * @returns `true` if a cycle exists, `false` otherwise.
6925
+ * @remarks Time O(V + E), Space O(V)
6926
+ */
6927
+ hasCycle() {
6928
+ const visited = /* @__PURE__ */ new Set();
6929
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
6930
+ visited.add(vertex);
6931
+ for (const neighbor of this.getNeighbors(vertex)) {
6932
+ if (!visited.has(neighbor)) {
6933
+ if (dfs(neighbor, vertex)) return true;
6934
+ } else if (neighbor !== parent) {
6935
+ return true;
6936
+ }
6937
+ }
6938
+ return false;
6939
+ }, "dfs");
6940
+ for (const vertex of this.vertexMap.values()) {
6941
+ if (!visited.has(vertex)) {
6942
+ if (dfs(vertex, void 0)) return true;
6943
+ }
6944
+ }
6945
+ return false;
6946
+ }
6672
6947
  /**
6673
6948
  * Get bridges discovered by `tarjan()`.
6674
6949
  * @returns Array of edges that are bridges.
@@ -6821,29 +7096,6 @@ var _MapGraph = class _MapGraph extends DirectedGraph {
6821
7096
  __name(_MapGraph, "MapGraph");
6822
7097
  var MapGraph = _MapGraph;
6823
7098
 
6824
- // src/common/index.ts
6825
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
6826
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
6827
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
6828
- return DFSOperation2;
6829
- })(DFSOperation || {});
6830
- var _Range = class _Range {
6831
- constructor(low, high, includeLow = true, includeHigh = true) {
6832
- this.low = low;
6833
- this.high = high;
6834
- this.includeLow = includeLow;
6835
- this.includeHigh = includeHigh;
6836
- }
6837
- // Determine whether a key is within the range
6838
- isInRange(key, comparator) {
6839
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
6840
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
6841
- return lowCheck && highCheck;
6842
- }
6843
- };
6844
- __name(_Range, "Range");
6845
- var Range = _Range;
6846
-
6847
7099
  // src/data-structures/binary-tree/binary-tree.ts
6848
7100
  var _BinaryTreeNode = class _BinaryTreeNode {
6849
7101
  /**
@@ -7016,7 +7268,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
7016
7268
  if (isMapMode !== void 0) this._isMapMode = isMapMode;
7017
7269
  if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
7018
7270
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
7019
- else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
7271
+ else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
7020
7272
  }
7021
7273
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
7022
7274
  }
@@ -7244,7 +7496,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
7244
7496
  if (!this._root) {
7245
7497
  this._setRoot(newNode);
7246
7498
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
7247
- this._size = 1;
7499
+ if (newNode !== null) this._size = 1;
7248
7500
  return true;
7249
7501
  }
7250
7502
  const queue = new Queue([this._root]);
@@ -7276,7 +7528,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
7276
7528
  potentialParent.right = newNode;
7277
7529
  }
7278
7530
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
7279
- this._size++;
7531
+ if (newNode !== null) this._size++;
7280
7532
  return true;
7281
7533
  }
7282
7534
  return false;
@@ -7845,7 +8097,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
7845
8097
  }
7846
8098
  /**
7847
8099
  * Finds all leaf nodes in the tree.
7848
- * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
8100
+ * @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
7849
8101
  *
7850
8102
  * @template C - The type of the callback function.
7851
8103
  * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
@@ -7868,15 +8120,15 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
7868
8120
  }, "dfs");
7869
8121
  dfs(startNode);
7870
8122
  } else {
7871
- const queue = new Queue([startNode]);
7872
- while (queue.length > 0) {
7873
- const cur = queue.shift();
8123
+ const stack = [startNode];
8124
+ while (stack.length > 0) {
8125
+ const cur = stack.pop();
7874
8126
  if (this.isRealNode(cur)) {
7875
8127
  if (this.isLeaf(cur)) {
7876
8128
  leaves.push(callback(cur));
7877
8129
  }
7878
- if (this.isRealNode(cur.left)) queue.push(cur.left);
7879
- if (this.isRealNode(cur.right)) queue.push(cur.right);
8130
+ if (this.isRealNode(cur.right)) stack.push(cur.right);
8131
+ if (this.isRealNode(cur.left)) stack.push(cur.left);
7880
8132
  }
7881
8133
  }
7882
8134
  }
@@ -8332,42 +8584,98 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
8332
8584
  _displayAux(node, options) {
8333
8585
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
8334
8586
  const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
8335
- if (node === null && !isShowNull) {
8336
- return emptyDisplayLayout;
8337
- } else if (node === void 0 && !isShowUndefined) {
8338
- return emptyDisplayLayout;
8339
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
8340
- return emptyDisplayLayout;
8341
- } else if (node !== null && node !== void 0) {
8342
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
8343
- return _buildNodeDisplay(
8344
- line,
8345
- width,
8346
- this._displayAux(node.left, options),
8347
- this._displayAux(node.right, options)
8348
- );
8349
- } else {
8350
- const line = node === void 0 ? "U" : "N", width = line.length;
8351
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
8352
- }
8353
- function _buildNodeDisplay(line, width, left, right) {
8354
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
8355
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
8356
- const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
8357
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
8358
- const mergedLines = [firstLine, secondLine];
8359
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
8360
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
8361
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
8362
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
8587
+ const newFrame = /* @__PURE__ */ __name((n) => ({
8588
+ node: n,
8589
+ stage: 0,
8590
+ leftLayout: emptyDisplayLayout,
8591
+ rightLayout: emptyDisplayLayout
8592
+ }), "newFrame");
8593
+ const stack = [newFrame(node)];
8594
+ let result = emptyDisplayLayout;
8595
+ const setChildResult = /* @__PURE__ */ __name((layout) => {
8596
+ if (stack.length === 0) {
8597
+ result = layout;
8598
+ return;
8599
+ }
8600
+ const parent = stack[stack.length - 1];
8601
+ if (parent.stage === 1) parent.leftLayout = layout;
8602
+ else parent.rightLayout = layout;
8603
+ }, "setChildResult");
8604
+ while (stack.length > 0) {
8605
+ const frame = stack[stack.length - 1];
8606
+ const cur = frame.node;
8607
+ if (frame.stage === 0) {
8608
+ if (this._isDisplayLeaf(cur, options)) {
8609
+ stack.pop();
8610
+ const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
8611
+ setChildResult(layout);
8612
+ continue;
8613
+ }
8614
+ frame.stage = 1;
8615
+ stack.push(newFrame(cur.left));
8616
+ } else if (frame.stage === 1) {
8617
+ frame.stage = 2;
8618
+ stack.push(newFrame(cur.right));
8619
+ } else {
8620
+ stack.pop();
8621
+ const line = this.isNIL(cur) ? "S" : String(cur.key);
8622
+ const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
8623
+ setChildResult(layout);
8363
8624
  }
8364
- return [
8365
- mergedLines,
8366
- leftWidth + width + rightWidth,
8367
- Math.max(leftHeight, rightHeight) + 2,
8368
- leftWidth + Math.floor(width / 2)
8369
- ];
8370
8625
  }
8626
+ return result;
8627
+ }
8628
+ static _buildNodeDisplay(line, width, left, right) {
8629
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
8630
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
8631
+ const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
8632
+ const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
8633
+ const mergedLines = [firstLine, secondLine];
8634
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
8635
+ const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
8636
+ const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
8637
+ mergedLines.push(leftLine + " ".repeat(width) + rightLine);
8638
+ }
8639
+ return [
8640
+ mergedLines,
8641
+ leftWidth + width + rightWidth,
8642
+ Math.max(leftHeight, rightHeight) + 2,
8643
+ leftWidth + Math.floor(width / 2)
8644
+ ];
8645
+ }
8646
+ /**
8647
+ * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
8648
+ */
8649
+ _isDisplayLeaf(node, options) {
8650
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
8651
+ if (node === null && !isShowNull) return true;
8652
+ if (node === void 0 && !isShowUndefined) return true;
8653
+ if (this.isNIL(node) && !isShowRedBlackNIL) return true;
8654
+ if (node === null || node === void 0) return true;
8655
+ const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
8656
+ const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
8657
+ return !hasDisplayableLeft && !hasDisplayableRight;
8658
+ }
8659
+ _hasDisplayableChild(child, options) {
8660
+ if (child === null) return !!options.isShowNull;
8661
+ if (child === void 0) return !!options.isShowUndefined;
8662
+ if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
8663
+ return true;
8664
+ }
8665
+ /**
8666
+ * Resolve a display leaf node to its layout.
8667
+ */
8668
+ _resolveDisplayLeaf(node, options, emptyDisplayLayout) {
8669
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
8670
+ if (node === null && !isShowNull) return emptyDisplayLayout;
8671
+ if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
8672
+ if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
8673
+ if (node !== null && node !== void 0) {
8674
+ const line2 = this.isNIL(node) ? "S" : String(node.key);
8675
+ return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
8676
+ }
8677
+ const line = node === void 0 ? "U" : "N";
8678
+ return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
8371
8679
  }
8372
8680
  /**
8373
8681
  * (Protected) Swaps the key/value properties of two nodes.
@@ -9373,9 +9681,15 @@ var _BST = class _BST extends BinaryTree {
9373
9681
  if (a < b) return -1;
9374
9682
  return 0;
9375
9683
  }
9684
+ if (a instanceof Date && b instanceof Date) {
9685
+ const ta = a.getTime();
9686
+ const tb = b.getTime();
9687
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
9688
+ return ta > tb ? 1 : ta < tb ? -1 : 0;
9689
+ }
9376
9690
  if (typeof a === "object" || typeof b === "object") {
9377
- throw TypeError(
9378
- `When comparing object type keys, a custom comparator must be provided in the constructor's options!`
9691
+ throw new TypeError(
9692
+ ERR.comparatorRequired("BST")
9379
9693
  );
9380
9694
  }
9381
9695
  return 0;
@@ -9889,7 +10203,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
9889
10203
  */
9890
10204
  read(count) {
9891
10205
  if (!Number.isInteger(count)) {
9892
- throw new Error("Invalid count");
10206
+ throw new Error(ERR.invalidArgument("count must be an integer", "BinaryIndexedTree"));
9893
10207
  }
9894
10208
  return this._read(Math.max(Math.min(count, this.max), 0));
9895
10209
  }
@@ -9901,7 +10215,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
9901
10215
  */
9902
10216
  lowerBound(sum) {
9903
10217
  if (this.negativeCount > 0) {
9904
- throw new Error("Sequence is not non-descending");
10218
+ throw new Error(ERR.invalidOperation("Sequence is not non-descending.", "BinaryIndexedTree"));
9905
10219
  }
9906
10220
  return this._binarySearch(sum, (x, y) => x < y);
9907
10221
  }
@@ -9914,7 +10228,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
9914
10228
  */
9915
10229
  upperBound(sum) {
9916
10230
  if (this.negativeCount > 0) {
9917
- throw new Error("Must not be descending");
10231
+ throw new Error(ERR.invalidOperation("Sequence must not be descending.", "BinaryIndexedTree"));
9918
10232
  }
9919
10233
  return this._binarySearch(sum, (x, y) => x <= y);
9920
10234
  }
@@ -9965,10 +10279,10 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
9965
10279
  */
9966
10280
  _checkIndex(index) {
9967
10281
  if (!Number.isInteger(index)) {
9968
- throw new Error("Invalid index: Index must be an integer.");
10282
+ throw new TypeError(ERR.invalidIndex("BinaryIndexedTree"));
9969
10283
  }
9970
10284
  if (index < 0 || index >= this.max) {
9971
- throw new Error("Index out of range: Index must be within the range [0, this.max).");
10285
+ throw new RangeError(ERR.indexOutOfRange(index, 0, this.max - 1, "BinaryIndexedTree"));
9972
10286
  }
9973
10287
  }
9974
10288
  /**
@@ -11557,6 +11871,24 @@ var _RedBlackTree = class _RedBlackTree extends BST {
11557
11871
  * @param [thisArg] - See parameter type for details.
11558
11872
  * @returns A new RedBlackTree with mapped entries.
11559
11873
  */
11874
+ /**
11875
+ * Red-Black trees are self-balancing — `perfectlyBalance` rebuilds via
11876
+ * sorted bulk insert, which naturally produces a balanced RBT.
11877
+ * @remarks Time O(N), Space O(N)
11878
+ */
11879
+ perfectlyBalance(iterationType) {
11880
+ const entries = [];
11881
+ for (const [key, value] of this) entries.push([key, value]);
11882
+ if (entries.length <= 1) return true;
11883
+ this.clear();
11884
+ this.setMany(
11885
+ entries.map(([k]) => k),
11886
+ entries.map(([, v]) => v),
11887
+ true
11888
+ // isBalanceAdd
11889
+ );
11890
+ return true;
11891
+ }
11560
11892
  map(callback, options, thisArg) {
11561
11893
  const out = this._createLike([], options);
11562
11894
  let index = 0;
@@ -11881,7 +12213,7 @@ var _TreeSet = class _TreeSet {
11881
12213
  static createDefaultComparator() {
11882
12214
  return (a, b) => {
11883
12215
  if (typeof a === "number" && typeof b === "number") {
11884
- if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeSet: NaN is not a valid key");
12216
+ if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeSet"));
11885
12217
  const aa = Object.is(a, -0) ? 0 : a;
11886
12218
  const bb = Object.is(b, -0) ? 0 : b;
11887
12219
  return aa > bb ? 1 : aa < bb ? -1 : 0;
@@ -11892,10 +12224,10 @@ var _TreeSet = class _TreeSet {
11892
12224
  if (a instanceof Date && b instanceof Date) {
11893
12225
  const ta = a.getTime();
11894
12226
  const tb = b.getTime();
11895
- if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeSet: invalid Date key");
12227
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeSet"));
11896
12228
  return ta > tb ? 1 : ta < tb ? -1 : 0;
11897
12229
  }
11898
- throw new TypeError("TreeSet: comparator is required for non-number/non-string/non-Date keys");
12230
+ throw new TypeError(ERR.comparatorRequired("TreeSet"));
11899
12231
  };
11900
12232
  }
11901
12233
  /**
@@ -11913,15 +12245,15 @@ var _TreeSet = class _TreeSet {
11913
12245
  _validateKey(key) {
11914
12246
  if (!__privateGet(this, _isDefaultComparator)) return;
11915
12247
  if (typeof key === "number") {
11916
- if (Number.isNaN(key)) throw new TypeError("TreeSet: NaN is not a valid key");
12248
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeSet"));
11917
12249
  return;
11918
12250
  }
11919
12251
  if (typeof key === "string") return;
11920
12252
  if (key instanceof Date) {
11921
- if (Number.isNaN(key.getTime())) throw new TypeError("TreeSet: invalid Date key");
12253
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeSet"));
11922
12254
  return;
11923
12255
  }
11924
- throw new TypeError("TreeSet: comparator is required for non-number/non-string/non-Date keys");
12256
+ throw new TypeError(ERR.comparatorRequired("TreeSet"));
11925
12257
  }
11926
12258
  /**
11927
12259
  * Add a key to the set (no-op if already present).
@@ -12244,15 +12576,15 @@ var _TreeMultiMap = class _TreeMultiMap {
12244
12576
  _validateKey(key) {
12245
12577
  if (!__privateGet(this, _isDefaultComparator2)) return;
12246
12578
  if (typeof key === "number") {
12247
- if (Number.isNaN(key)) throw new TypeError("TreeMultiMap: NaN is not a valid key");
12579
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiMap"));
12248
12580
  return;
12249
12581
  }
12250
12582
  if (typeof key === "string") return;
12251
12583
  if (key instanceof Date) {
12252
- if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiMap: invalid Date key");
12584
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiMap"));
12253
12585
  return;
12254
12586
  }
12255
- throw new TypeError("TreeMultiMap: comparator is required for non-number/non-string/non-Date keys");
12587
+ throw new TypeError(ERR.comparatorRequired("TreeMultiMap"));
12256
12588
  }
12257
12589
  /**
12258
12590
  * Number of distinct keys.
@@ -12677,7 +13009,7 @@ var _TreeMap = class _TreeMap {
12677
13009
  [k, v] = toEntryFn(item);
12678
13010
  } else {
12679
13011
  if (!Array.isArray(item) || item.length < 2) {
12680
- throw new TypeError("TreeMap: each entry must be a [key, value] tuple");
13012
+ throw new TypeError(ERR.invalidEntry("TreeMap"));
12681
13013
  }
12682
13014
  k = item[0];
12683
13015
  v = item[1];
@@ -12698,7 +13030,7 @@ var _TreeMap = class _TreeMap {
12698
13030
  static createDefaultComparator() {
12699
13031
  return (a, b) => {
12700
13032
  if (typeof a === "number" && typeof b === "number") {
12701
- if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeMap: NaN is not a valid key");
13033
+ if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeMap"));
12702
13034
  const aa = Object.is(a, -0) ? 0 : a;
12703
13035
  const bb = Object.is(b, -0) ? 0 : b;
12704
13036
  return aa > bb ? 1 : aa < bb ? -1 : 0;
@@ -12709,24 +13041,24 @@ var _TreeMap = class _TreeMap {
12709
13041
  if (a instanceof Date && b instanceof Date) {
12710
13042
  const ta = a.getTime();
12711
13043
  const tb = b.getTime();
12712
- if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeMap: invalid Date key");
13044
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeMap"));
12713
13045
  return ta > tb ? 1 : ta < tb ? -1 : 0;
12714
13046
  }
12715
- throw new TypeError("TreeMap: comparator is required for non-number/non-string/non-Date keys");
13047
+ throw new TypeError(ERR.comparatorRequired("TreeMap"));
12716
13048
  };
12717
13049
  }
12718
13050
  _validateKey(key) {
12719
13051
  if (!__privateGet(this, _isDefaultComparator3)) return;
12720
13052
  if (typeof key === "number") {
12721
- if (Number.isNaN(key)) throw new TypeError("TreeMap: NaN is not a valid key");
13053
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMap"));
12722
13054
  return;
12723
13055
  }
12724
13056
  if (typeof key === "string") return;
12725
13057
  if (key instanceof Date) {
12726
- if (Number.isNaN(key.getTime())) throw new TypeError("TreeMap: invalid Date key");
13058
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMap"));
12727
13059
  return;
12728
13060
  }
12729
- throw new TypeError("TreeMap: comparator is required for non-number/non-string/non-Date keys");
13061
+ throw new TypeError(ERR.comparatorRequired("TreeMap"));
12730
13062
  }
12731
13063
  /**
12732
13064
  * Number of entries in the map.
@@ -13055,22 +13387,22 @@ var _TreeMultiSet = class _TreeMultiSet {
13055
13387
  _validateKey(key) {
13056
13388
  if (!__privateGet(this, _isDefaultComparator4)) return;
13057
13389
  if (typeof key === "number") {
13058
- if (Number.isNaN(key)) throw new TypeError("TreeMultiSet: NaN is not a valid key");
13390
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiSet"));
13059
13391
  return;
13060
13392
  }
13061
13393
  if (typeof key === "string") return;
13062
13394
  if (key instanceof Date) {
13063
- if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiSet: invalid Date key");
13395
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiSet"));
13064
13396
  return;
13065
13397
  }
13066
- throw new TypeError("TreeMultiSet: comparator is required for non-number/non-string/non-Date keys");
13398
+ throw new TypeError(ERR.comparatorRequired("TreeMultiSet"));
13067
13399
  }
13068
13400
  /**
13069
13401
  * Validates that count is a non-negative safe integer.
13070
13402
  * @remarks Time O(1), Space O(1)
13071
13403
  */
13072
13404
  _validateCount(n) {
13073
- if (!Number.isSafeInteger(n) || n < 0) throw new RangeError("TreeMultiSet: count must be a safe integer >= 0");
13405
+ if (!Number.isSafeInteger(n) || n < 0) throw new RangeError(ERR.invalidArgument("count must be a safe integer >= 0.", "TreeMultiSet"));
13074
13406
  }
13075
13407
  /**
13076
13408
  * Total occurrences (sumCounts).
@@ -13498,9 +13830,7 @@ var _MaxPriorityQueue = class _MaxPriorityQueue extends PriorityQueue {
13498
13830
  super(elements, {
13499
13831
  comparator: /* @__PURE__ */ __name((a, b) => {
13500
13832
  if (typeof a === "object" || typeof b === "object") {
13501
- throw TypeError(
13502
- `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
13503
- );
13833
+ throw new TypeError(ERR.comparatorRequired("MaxPriorityQueue"));
13504
13834
  }
13505
13835
  if (a < b) return 1;
13506
13836
  if (a > b) return -1;
@@ -13641,7 +13971,7 @@ var _Matrix = class _Matrix {
13641
13971
  */
13642
13972
  add(matrix) {
13643
13973
  if (!this.isMatchForCalculate(matrix)) {
13644
- throw new Error("Matrix dimensions must match for addition.");
13974
+ throw new Error(ERR.matrixDimensionMismatch("addition"));
13645
13975
  }
13646
13976
  const resultData = [];
13647
13977
  for (let i = 0; i < this.rows; i++) {
@@ -13673,7 +14003,7 @@ var _Matrix = class _Matrix {
13673
14003
  */
13674
14004
  subtract(matrix) {
13675
14005
  if (!this.isMatchForCalculate(matrix)) {
13676
- throw new Error("Matrix dimensions must match for subtraction.");
14006
+ throw new Error(ERR.matrixDimensionMismatch("subtraction"));
13677
14007
  }
13678
14008
  const resultData = [];
13679
14009
  for (let i = 0; i < this.rows; i++) {
@@ -13704,7 +14034,7 @@ var _Matrix = class _Matrix {
13704
14034
  */
13705
14035
  multiply(matrix) {
13706
14036
  if (this.cols !== matrix.rows) {
13707
- throw new Error("Matrix dimensions must be compatible for multiplication (A.cols = B.rows).");
14037
+ throw new Error(ERR.matrixDimensionMismatch("multiplication (A.cols must equal B.rows)"));
13708
14038
  }
13709
14039
  const resultData = [];
13710
14040
  for (let i = 0; i < this.rows; i++) {
@@ -13738,7 +14068,7 @@ var _Matrix = class _Matrix {
13738
14068
  */
13739
14069
  transpose() {
13740
14070
  if (this.data.some((row) => row.length !== this.rows)) {
13741
- throw new Error("Matrix must be rectangular for transposition.");
14071
+ throw new Error(ERR.matrixNotRectangular());
13742
14072
  }
13743
14073
  const resultData = [];
13744
14074
  for (let j = 0; j < this.cols; j++) {
@@ -13763,7 +14093,7 @@ var _Matrix = class _Matrix {
13763
14093
  inverse() {
13764
14094
  var _a;
13765
14095
  if (this.rows !== this.cols) {
13766
- throw new Error("Matrix must be square for inversion.");
14096
+ throw new Error(ERR.matrixNotSquare());
13767
14097
  }
13768
14098
  const augmentedMatrixData = [];
13769
14099
  for (let i = 0; i < this.rows; i++) {
@@ -13785,12 +14115,12 @@ var _Matrix = class _Matrix {
13785
14115
  pivotRow++;
13786
14116
  }
13787
14117
  if (pivotRow === this.rows) {
13788
- throw new Error("Matrix is singular, and its inverse does not exist.");
14118
+ throw new Error(ERR.matrixSingular());
13789
14119
  }
13790
14120
  augmentedMatrix._swapRows(i, pivotRow);
13791
14121
  const pivotElement = (_a = augmentedMatrix.get(i, i)) != null ? _a : 1;
13792
14122
  if (pivotElement === 0) {
13793
- throw new Error("Matrix is singular, and its inverse does not exist (division by zero).");
14123
+ throw new Error(ERR.matrixSingular());
13794
14124
  }
13795
14125
  augmentedMatrix._scaleRow(i, 1 / pivotElement);
13796
14126
  for (let j = 0; j < this.rows; j++) {
@@ -13820,9 +14150,7 @@ var _Matrix = class _Matrix {
13820
14150
  */
13821
14151
  dot(matrix) {
13822
14152
  if (this.cols !== matrix.rows) {
13823
- throw new Error(
13824
- "Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product."
13825
- );
14153
+ throw new Error(ERR.matrixDimensionMismatch("dot product (A.cols must equal B.rows)"));
13826
14154
  }
13827
14155
  const resultData = [];
13828
14156
  for (let i = 0; i < this.rows; i++) {
@@ -14444,7 +14772,7 @@ var _Trie = class _Trie extends IterableElementBase {
14444
14772
  for (const x of this) {
14445
14773
  const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
14446
14774
  if (typeof v !== "string") {
14447
- throw new TypeError(`Trie.map callback must return string; got ${typeof v}`);
14775
+ throw new TypeError(ERR.callbackReturnType("string", typeof v, "Trie.map"));
14448
14776
  }
14449
14777
  newTrie.add(v);
14450
14778
  }
@@ -14677,6 +15005,6 @@ var TreeNode = _TreeNode;
14677
15005
  * @license MIT License
14678
15006
  */
14679
15007
 
14680
- export { AVLTree, AVLTreeNode, AbstractEdge, AbstractGraph, AbstractVertex, BST, BSTNode, BinaryIndexedTree, BinaryTree, BinaryTreeNode, Character, DFSOperation, Deque, DirectedEdge, DirectedGraph, DirectedVertex, DoublyLinkedList, DoublyLinkedListNode, FibonacciHeap, FibonacciHeapNode, HashMap, Heap, IterableElementBase, IterableEntryBase, LinkedHashMap, LinkedListQueue, MapEdge, MapGraph, MapVertex, Matrix, MaxHeap, MaxPriorityQueue, MinHeap, MinPriorityQueue, Navigator, PriorityQueue, Queue, Range, RedBlackTree, RedBlackTreeNode, SegmentTree, SegmentTreeNode, SinglyLinkedList, SinglyLinkedListNode, SkipList, SkipListNode, Stack, TreeMap, TreeMultiMap, TreeMultiMapNode, TreeMultiSet, TreeNode, TreeSet, Trie, TrieNode, UndirectedEdge, UndirectedGraph, UndirectedVertex, arrayRemove, asyncTrampoline, calcMinUnitsRequired, getMSB, isComparable, isTrampolineThunk, isWeakKey, makeAsyncTrampoline, makeTrampoline, makeTrampolineThunk, rangeCheck, roundFixed, throwRangeError, toBinaryString, trampoline, uuidV4 };
15008
+ export { AVLTree, AVLTreeNode, AbstractEdge, AbstractGraph, AbstractVertex, BST, BSTNode, BinaryIndexedTree, BinaryTree, BinaryTreeNode, Character, DFSOperation, Deque, DirectedEdge, DirectedGraph, DirectedVertex, DoublyLinkedList, DoublyLinkedListNode, ERR, FibonacciHeap, FibonacciHeapNode, HashMap, Heap, IterableElementBase, IterableEntryBase, LinkedHashMap, LinkedListQueue, MapEdge, MapGraph, MapVertex, Matrix, MaxHeap, MaxPriorityQueue, MinHeap, MinPriorityQueue, Navigator, PriorityQueue, Queue, Range, RedBlackTree, RedBlackTreeNode, SegmentTree, SegmentTreeNode, SinglyLinkedList, SinglyLinkedListNode, SkipList, SkipListNode, Stack, TreeMap, TreeMultiMap, TreeMultiMapNode, TreeMultiSet, TreeNode, TreeSet, Trie, TrieNode, UndirectedEdge, UndirectedGraph, UndirectedVertex, arrayRemove, asyncTrampoline, calcMinUnitsRequired, getMSB, isComparable, isTrampolineThunk, isWeakKey, makeAsyncTrampoline, makeTrampoline, makeTrampolineThunk, rangeCheck, roundFixed, throwRangeError, toBinaryString, trampoline, uuidV4 };
14681
15009
  //# sourceMappingURL=index.mjs.map
14682
15010
  //# sourceMappingURL=index.mjs.map