@graphty/graphty-element 2.5.1 → 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 (135) hide show
  1. package/dist/ai.js +3 -3
  2. package/dist/catalog.d.ts +16 -0
  3. package/dist/catalog.js +34 -32
  4. package/dist/chunks/{AiManager-CrbvKdEK.js → AiManager-4iQpsJW1.js} +4 -4
  5. package/dist/chunks/{DataSource-qU-nLhXN.js → DataSource-BL2UzPff.js} +2 -2
  6. package/dist/chunks/GraphSession-BhuHSXIo.js +12819 -0
  7. package/dist/chunks/{GraphtyLogger-DOTwCiMR.js → GraphtyLogger-B_O67a6c.js} +1 -1
  8. package/dist/chunks/{VoiceInputAdapter-D4NrRL_1.js → VoiceInputAdapter-Cc6mHXTI.js} +1 -1
  9. package/dist/chunks/{XRPivotCameraController-Uqa47vmo.js → XRPivotCameraController-BLa89LXn.js} +2 -2
  10. package/dist/chunks/{algorithms-D-ab-Auu.js → algorithms-BJ6DQMOe.js} +931 -781
  11. package/dist/chunks/{capability-check-Vw3IcqiE.js → capability-check-Am2zliFj.js} +1 -1
  12. package/dist/chunks/{detect-B4Qrw976.js → detect-fyuVnlCT.js} +1 -1
  13. package/dist/chunks/{format-detection-r2IfNFXO.js → format-detection-BHwrAVzW.js} +1 -1
  14. package/dist/chunks/{index-J9MgLio9.js → index-BkBLbvui.js} +2691 -2434
  15. package/dist/chunks/optionsFromZod-CKMYSwTz.js +3636 -0
  16. package/dist/chunks/{paletteRegistry-Kt-6CeoN.js → paletteRegistry-BCFSwJGK.js} +224 -189
  17. package/dist/chunks/parse-BMTqt4SS.js +3658 -0
  18. package/dist/chunks/{types-C_c53VgR.js → types-DFchv4Ny.js} +4 -1
  19. package/dist/custom-elements.json +1 -1
  20. package/dist/extend.d.ts +10 -8
  21. package/dist/extend.js +6 -6
  22. package/dist/graphty-catalog.json +75 -38
  23. package/dist/graphty.bundle.js +55368 -48970
  24. package/dist/graphty.js +19 -19
  25. package/dist/index.d.ts +1 -1
  26. package/dist/logging.js +2 -2
  27. package/dist/schema.d.ts +15 -1
  28. package/dist/schema.js +1 -1
  29. package/dist/session.d.ts +30 -7
  30. package/dist/session.js +40 -37
  31. package/dist/src/Graph.d.ts +35 -7
  32. package/dist/src/acceleration/types.d.ts +79 -43
  33. package/dist/src/algorithms/Algorithm.d.ts +52 -4
  34. package/dist/src/algorithms/BFSAlgorithm.d.ts +3 -0
  35. package/dist/src/algorithms/BellmanFordAlgorithm.d.ts +3 -0
  36. package/dist/src/algorithms/BetweennessCentralityAlgorithm.d.ts +3 -0
  37. package/dist/src/algorithms/BipartiteMatchingAlgorithm.d.ts +3 -0
  38. package/dist/src/algorithms/ClosenessCentralityAlgorithm.d.ts +3 -0
  39. package/dist/src/algorithms/ConnectedComponentsAlgorithm.d.ts +4 -1
  40. package/dist/src/algorithms/DFSAlgorithm.d.ts +3 -0
  41. package/dist/src/algorithms/DegreeAlgorithm.d.ts +3 -0
  42. package/dist/src/algorithms/DijkstraAlgorithm.d.ts +6 -0
  43. package/dist/src/algorithms/EigenvectorCentralityAlgorithm.d.ts +2 -0
  44. package/dist/src/algorithms/FloydWarshallAlgorithm.d.ts +3 -0
  45. package/dist/src/algorithms/GirvanNewmanAlgorithm.d.ts +3 -0
  46. package/dist/src/algorithms/HITSAlgorithm.d.ts +3 -0
  47. package/dist/src/algorithms/KCoreAlgorithm.d.ts +3 -0
  48. package/dist/src/algorithms/KatzCentralityAlgorithm.d.ts +3 -0
  49. package/dist/src/algorithms/KruskalAlgorithm.d.ts +4 -1
  50. package/dist/src/algorithms/LabelPropagationAlgorithm.d.ts +3 -0
  51. package/dist/src/algorithms/LeidenAlgorithm.d.ts +3 -0
  52. package/dist/src/algorithms/LinkPredictionAlgorithm.d.ts +4 -1
  53. package/dist/src/algorithms/LouvainAlgorithm.d.ts +3 -0
  54. package/dist/src/algorithms/MaxFlowAlgorithm.d.ts +3 -0
  55. package/dist/src/algorithms/MinCutAlgorithm.d.ts +3 -0
  56. package/dist/src/algorithms/PageRankAlgorithm.d.ts +3 -0
  57. package/dist/src/algorithms/PrimAlgorithm.d.ts +3 -0
  58. package/dist/src/algorithms/StronglyConnectedComponentsAlgorithm.d.ts +3 -0
  59. package/dist/src/algorithms/input/ScopedInput.d.ts +185 -0
  60. package/dist/src/algorithms/input/derivedInputs.d.ts +199 -0
  61. package/dist/src/algorithms/input/maskBack.d.ts +37 -0
  62. package/dist/src/algorithms/metrics/MetricAlgorithm.d.ts +3 -3
  63. package/dist/src/algorithms/results/DeclaredAlgorithm.d.ts +4 -3
  64. package/dist/src/algorithms/results/types.d.ts +28 -6
  65. package/dist/src/algorithms/utils/communityUtils.d.ts +0 -48
  66. package/dist/src/algorithms/utils/graphUtils.d.ts +2 -68
  67. package/dist/src/algorithms/utils/snapshotGraph.d.ts +3 -1
  68. package/dist/src/catalog/algorithms.d.ts +3 -0
  69. package/dist/src/catalog/layouts.d.ts +2 -0
  70. package/dist/src/catalog/sets/canonical.d.ts +68 -0
  71. package/dist/src/catalog/sets/hash.d.ts +126 -0
  72. package/dist/src/catalog/sets/parse.d.ts +115 -0
  73. package/dist/src/catalog/types.d.ts +329 -8
  74. package/dist/src/data/GraphStore.d.ts +73 -1
  75. package/dist/src/data/edgeIdentity.d.ts +202 -1
  76. package/dist/src/data/ingest.d.ts +3 -1
  77. package/dist/src/data/report.d.ts +20 -0
  78. package/dist/src/graphty-element.d.ts +42 -6
  79. package/dist/src/layout/D3GraphLayoutEngine.d.ts +11 -0
  80. package/dist/src/layout/LayoutEngine.d.ts +56 -0
  81. package/dist/src/layout/NGraphLayoutEngine.d.ts +10 -0
  82. package/dist/src/layout/SimulationLayoutEngine.d.ts +11 -0
  83. package/dist/src/managers/AlgorithmManager.d.ts +8 -0
  84. package/dist/src/managers/DataManager.d.ts +11 -0
  85. package/dist/src/managers/LayoutManager.d.ts +126 -2
  86. package/dist/src/managers/StatsManager.d.ts +1 -0
  87. package/dist/src/session/GraphSession.d.ts +48 -0
  88. package/dist/src/session/attributes.d.ts +121 -1
  89. package/dist/src/session/cost/estimate.d.ts +20 -0
  90. package/dist/src/session/cost/index.d.ts +1 -1
  91. package/dist/src/session/planning.d.ts +32 -2
  92. package/dist/src/session/query.d.ts +7 -0
  93. package/dist/src/session/results/ResultsApi.d.ts +14 -1
  94. package/dist/src/session/runs/Run.d.ts +65 -4
  95. package/dist/src/session/runs/RunsApi.d.ts +58 -2
  96. package/dist/src/session/runs/runId.d.ts +55 -6
  97. package/dist/src/session/runs/types.d.ts +36 -8
  98. package/dist/src/session/scope/ElementMask.d.ts +14 -1
  99. package/dist/src/session/scope/ScopeApi.d.ts +160 -31
  100. package/dist/src/session/scope/index.d.ts +1 -1
  101. package/dist/src/session/selection/SelectionApi.d.ts +15 -10
  102. package/dist/src/session/selection/index.d.ts +1 -1
  103. package/dist/src/session/selection/targets.d.ts +6 -7
  104. package/dist/src/session/sets/SetsApi.d.ts +110 -0
  105. package/dist/src/session/sets/algebra.d.ts +124 -0
  106. package/dist/src/session/sets/cache.d.ts +197 -0
  107. package/dist/src/session/sets/captures.d.ts +83 -0
  108. package/dist/src/session/sets/dependencies.d.ts +167 -0
  109. package/dist/src/session/sets/layers.d.ts +101 -0
  110. package/dist/src/session/sets/notify.d.ts +122 -0
  111. package/dist/src/session/sets/offers.d.ts +103 -0
  112. package/dist/src/session/sets/path.d.ts +37 -0
  113. package/dist/src/session/sets/prepare.d.ts +209 -0
  114. package/dist/src/session/sets/resolve.d.ts +311 -0
  115. package/dist/src/session/sets/signature.d.ts +77 -0
  116. package/dist/src/session/sets/status.d.ts +98 -0
  117. package/dist/src/session/sets/store.d.ts +196 -0
  118. package/dist/src/session/sets/types.d.ts +386 -0
  119. package/dist/src/session/styles/Layer.d.ts +9 -2
  120. package/dist/src/session/styles/StylesApi.d.ts +5 -2
  121. package/dist/src/session/styles/explain.d.ts +5 -2
  122. package/dist/src/session/styles/predicate.d.ts +41 -2
  123. package/dist/src/session/styles/repaint.d.ts +19 -0
  124. package/dist/src/session/styles/selector.d.ts +16 -5
  125. package/dist/src/session/types.d.ts +18 -0
  126. package/dist/src/session/visibility/VisibilityApi.d.ts +47 -3
  127. package/dist/src/session/visibility/filter.d.ts +86 -51
  128. package/dist/src/session/visibility/index.d.ts +1 -1
  129. package/dist/src/testing/fakeAccelerator.d.ts +5 -0
  130. package/dist/src/utils/queue-migration.d.ts +17 -0
  131. package/package.json +15 -9
  132. package/dist/chunks/GraphSession-DuAhRgCd.js +0 -8622
  133. package/dist/chunks/optionsFromZod-B9RncoTX.js +0 -2578
  134. package/dist/chunks/scales-CJCRwi2J.js +0 -3220
  135. package/dist/src/algorithms/utils/index.d.ts +0 -6
@@ -1,32 +1,32 @@
1
- import { c as b, G as g, S as T } from "./pluginRegistry-Bs8bEkz9.js";
2
- import { a as F, b as D, d as k } from "./types-C_c53VgR.js";
3
- import { remapArray as S, INVALID_INDEX as N } from "@graphty/graph-format";
1
+ import { c as E, G as g, S as _ } from "./pluginRegistry-Bs8bEkz9.js";
2
+ import { a as F, b as D, d as k } from "./types-DFchv4Ny.js";
3
+ import { remapArray as S, INVALID_INDEX as w, maskTest as v } from "@graphty/graph-format";
4
4
  import { z as O } from "zod/v4";
5
- import { G as v } from "./GraphtyLogger-DOTwCiMR.js";
5
+ import { G as $ } from "./GraphtyLogger-B_O67a6c.js";
6
6
  import { c as L } from "./common-DWNKjpH_.js";
7
- const f = b({
7
+ const f = E({
8
8
  kind: "format",
9
- idOf: (i) => i.descriptor.id,
10
- descriptorOf: (i) => i.descriptor,
11
- implementationOf: (i) => i.descriptor,
9
+ idOf: (s) => s.descriptor.id,
10
+ descriptorOf: (s) => s.descriptor,
11
+ implementationOf: (s) => s.descriptor,
12
12
  builtInIds: () => F
13
13
  });
14
- function st(i, t) {
15
- f.register(i, t);
14
+ function rt(s, t) {
15
+ f.register(s, t);
16
16
  }
17
- function rt() {
17
+ function nt() {
18
18
  return f.entries();
19
19
  }
20
- function $() {
20
+ function R() {
21
21
  return f.descriptors();
22
22
  }
23
- function j(i) {
24
- return f.byId(i);
23
+ function M(s) {
24
+ return f.byId(s);
25
25
  }
26
- function nt() {
26
+ function ot() {
27
27
  f.clearForTesting();
28
28
  }
29
- const M = {
29
+ const j = {
30
30
  "edge-list": "Edge List",
31
31
  "node-list": "Node List",
32
32
  "adjacency-list": "Adjacency List",
@@ -34,7 +34,7 @@ const M = {
34
34
  gephi: "Gephi Export",
35
35
  cytoscape: "Cytoscape Export",
36
36
  generic: "Generic"
37
- }, R = [
37
+ }, z = [
38
38
  {
39
39
  name: "delimiter",
40
40
  plainName: "Column Separator",
@@ -47,7 +47,7 @@ const M = {
47
47
  plainName: "File Shape",
48
48
  technicalName: "variant",
49
49
  type: "enum",
50
- values: Object.entries(M).map(([i, t]) => ({ value: i, label: t })),
50
+ values: Object.entries(j).map(([s, t]) => ({ value: s, label: t })),
51
51
  description: "Which CSV shape to read. Worked out from the header row when it is not set."
52
52
  },
53
53
  {
@@ -72,7 +72,7 @@ const M = {
72
72
  type: "string",
73
73
  description: "Where to find the node an edge ends at. Left unset, the element looks for target, then dst, then to."
74
74
  }
75
- ], z = [
75
+ ], B = [
76
76
  {
77
77
  name: "nodeIdPath",
78
78
  plainName: "Node Id Field",
@@ -80,7 +80,7 @@ const M = {
80
80
  type: "string",
81
81
  description: "An expression selecting each node's identity out of the node record."
82
82
  }
83
- ], _ = [
83
+ ], T = [
84
84
  {
85
85
  id: "json",
86
86
  plainName: "JSON",
@@ -88,7 +88,7 @@ const M = {
88
88
  mimeTypes: ["application/json"],
89
89
  canImport: !0,
90
90
  canExport: !1,
91
- options: [...z, ...h]
91
+ options: [...B, ...h]
92
92
  },
93
93
  {
94
94
  id: "csv",
@@ -97,7 +97,7 @@ const M = {
97
97
  mimeTypes: ["text/csv", "text/tab-separated-values", "text/plain"],
98
98
  canImport: !0,
99
99
  canExport: !1,
100
- options: [...R, ...h]
100
+ options: [...z, ...h]
101
101
  },
102
102
  {
103
103
  id: "graphml",
@@ -149,7 +149,7 @@ const M = {
149
149
  canExport: !1,
150
150
  options: h
151
151
  }
152
- ], ot = [
152
+ ], at = [
153
153
  {
154
154
  id: "sif",
155
155
  reason: "No data source reads the Cytoscape simple interaction format. The name is deprecated and is removed at the next major release unless a reader lands."
@@ -159,59 +159,59 @@ const M = {
159
159
  reason: "No data source reads the Cytoscape Exchange format. The name is deprecated and is removed at the next major release unless a reader lands."
160
160
  }
161
161
  ];
162
- function at(i) {
163
- return _.find((t) => t.id === i) ?? j(i)?.descriptor;
162
+ function lt(s) {
163
+ return T.find((t) => t.id === s) ?? M(s)?.descriptor;
164
164
  }
165
- function lt(i) {
166
- const t = i.toLowerCase();
167
- return [..._, ...$()].filter(
165
+ function ct(s) {
166
+ const t = s.toLowerCase();
167
+ return [...T, ...R()].filter(
168
168
  (e) => e.extensions.includes(t)
169
169
  );
170
170
  }
171
- const m = b({
171
+ const y = E({
172
172
  kind: "layout",
173
- idOf: (i) => i.descriptor.id,
174
- descriptorOf: (i) => i.descriptor,
175
- implementationOf: (i) => i.descriptor,
173
+ idOf: (s) => s.descriptor.id,
174
+ descriptorOf: (s) => s.descriptor,
175
+ implementationOf: (s) => s.descriptor,
176
176
  builtInIds: () => D
177
177
  });
178
- function B(i, t) {
179
- m.register(i, t);
178
+ function C(s, t) {
179
+ y.register(s, t);
180
180
  }
181
- function ct() {
182
- return m.descriptors();
181
+ function ht() {
182
+ return y.descriptors();
183
183
  }
184
- function ht(i) {
185
- return m.byId(i);
184
+ function dt(s) {
185
+ return y.byId(s);
186
186
  }
187
- function dt() {
188
- m.clearForTesting();
187
+ function ut() {
188
+ y.clearForTesting();
189
189
  }
190
- const o = 3, C = 1024;
191
- function p(i, t) {
192
- if (!Number.isInteger(i) || i < 0)
193
- throw new RangeError(`ElementPositions: ${t} must be a non-negative integer, found ${String(i)}`);
194
- return i;
190
+ const a = 3, W = 1024;
191
+ function p(s, t) {
192
+ if (!Number.isInteger(s) || s < 0)
193
+ throw new RangeError(`ElementPositions: ${t} must be a non-negative integer, found ${String(s)}`);
194
+ return s;
195
195
  }
196
- function d(i) {
197
- return Number.isFinite(Math.fround(i));
196
+ function d(s) {
197
+ return Number.isFinite(Math.fround(s));
198
198
  }
199
199
  class x {
200
200
  /**
201
201
  * Allocate the backing array, every row unplaced and unpinned.
202
202
  * @param capacity - rows to reserve before the first growth; a non-negative integer
203
203
  */
204
- constructor(t = C) {
205
- this.components = o, this.rows = 0, p(t, "capacity");
204
+ constructor(t = W) {
205
+ this.components = a, this.rows = 0, p(t, "capacity");
206
206
  const e = Math.max(1, t);
207
- this.array = new Float32Array(o * e), this.array.fill(Number.NaN), this.pins = new Uint8Array(e);
207
+ this.array = new Float32Array(a * e), this.array.fill(Number.NaN), this.pins = new Uint8Array(e);
208
208
  }
209
209
  /**
210
210
  * Rows the backing array can hold without reallocating.
211
211
  * @returns the current capacity in rows
212
212
  */
213
213
  get capacity() {
214
- return this.array.length / o;
214
+ return this.array.length / a;
215
215
  }
216
216
  /**
217
217
  * Rows currently in use. Equals the last snapshot's nodeCount.
@@ -242,7 +242,7 @@ class x {
242
242
  */
243
243
  get placedCount() {
244
244
  let t = 0;
245
- for (let e = 0; e < o * this.rows; e += o)
245
+ for (let e = 0; e < a * this.rows; e += a)
246
246
  this.hasStorableX(e) && t++;
247
247
  return t;
248
248
  }
@@ -264,7 +264,7 @@ class x {
264
264
  throw new RangeError(
265
265
  `ElementPositions: view(${t}) needs ${t} live rows but only ${this.rows} exist; call grow(${t}) first`
266
266
  );
267
- return this.array.subarray(0, o * t);
267
+ return this.array.subarray(0, a * t);
268
268
  }
269
269
  /**
270
270
  * Prefix-stable growth: existing rows keep their coordinates, EVERY row at or above the new
@@ -278,11 +278,11 @@ class x {
278
278
  */
279
279
  grow(t) {
280
280
  if (p(t, "nodeCount"), t > this.capacity) {
281
- const e = Math.max(this.capacity * 2, t), s = new Float32Array(o * e);
282
- s.set(this.array), s.fill(Number.NaN, o * this.rows), this.array = s;
281
+ const e = Math.max(this.capacity * 2, t), i = new Float32Array(a * e);
282
+ i.set(this.array), i.fill(Number.NaN, a * this.rows), this.array = i;
283
283
  const r = new Uint8Array(e);
284
284
  r.set(this.pins), r.fill(0, this.rows), this.pins = r;
285
- } else t > this.rows ? (this.array.fill(Number.NaN, o * this.rows, o * t), this.pins.fill(0, this.rows, t)) : t < this.rows && (this.array.fill(Number.NaN, o * t, o * this.rows), this.pins.fill(0, t, this.rows));
285
+ } else t > this.rows ? (this.array.fill(Number.NaN, a * this.rows, a * t), this.pins.fill(0, this.rows, t)) : t < this.rows && (this.array.fill(Number.NaN, a * t, a * this.rows), this.pins.fill(0, t, this.rows));
286
286
  this.rows = t;
287
287
  }
288
288
  /**
@@ -298,7 +298,7 @@ class x {
298
298
  * @throws RangeError when `nodeCount` is not a non-negative integer
299
299
  */
300
300
  remap(t, e) {
301
- p(e, "nodeCount"), this.array = S(this.array, t, e, Number.NaN, o), this.pins = S(this.pins, t, e, 0, 1), this.rows = e;
301
+ p(e, "nodeCount"), this.array = S(this.array, t, e, Number.NaN, a), this.pins = S(this.pins, t, e, 0, 1), this.rows = e;
302
302
  }
303
303
  /**
304
304
  * Whether the reader has fixed this row's node in place.
@@ -330,7 +330,7 @@ class x {
330
330
  * @returns true when the lane was written, false when the index names no row
331
331
  */
332
332
  setPinned(t, e) {
333
- return t === N || !Number.isInteger(t) || t < 0 ? !1 : (t >= this.rows && this.grow(t + 1), this.pins[t] = e ? 1 : 0, !0);
333
+ return t === w || !Number.isInteger(t) || t < 0 ? !1 : (t >= this.rows && this.grow(t + 1), this.pins[t] = e ? 1 : 0, !0);
334
334
  }
335
335
  /**
336
336
  * How many live rows are pinned.
@@ -369,7 +369,7 @@ class x {
369
369
  * @returns true when the row is inside the live count AND carries a storable x
370
370
  */
371
371
  isPlaced(t) {
372
- return !Number.isInteger(t) || t < 0 || t >= this.rows ? !1 : this.hasStorableX(o * t);
372
+ return !Number.isInteger(t) || t < 0 || t >= this.rows ? !1 : this.hasStorableX(a * t);
373
373
  }
374
374
  /**
375
375
  * Read one row into a caller-supplied object (14.4 rule 7: never return a shared vector).
@@ -381,8 +381,8 @@ class x {
381
381
  * @throws RangeError when `index` is not an integer in `[0, count)`
382
382
  */
383
383
  read(t, e) {
384
- const s = this.rowBase(t);
385
- e.x = this.array[s] ?? Number.NaN, e.y = this.array[s + 1] ?? Number.NaN, e.z = this.array[s + 2] ?? Number.NaN;
384
+ const i = this.rowBase(t);
385
+ e.x = this.array[i] ?? Number.NaN, e.y = this.array[i + 1] ?? Number.NaN, e.z = this.array[i + 2] ?? Number.NaN;
386
386
  }
387
387
  /**
388
388
  * Write one row.
@@ -402,13 +402,13 @@ class x {
402
402
  * last freeze has no row yet: freeze first (which grows this array), then write
403
403
  * @throws RangeError when any component is NaN, an infinity, or a double that overflows f32
404
404
  */
405
- write(t, e, s, r) {
405
+ write(t, e, i, r) {
406
406
  const n = this.rowBase(t);
407
- if (!d(e) || !d(s) || !d(r))
407
+ if (!d(e) || !d(i) || !d(r))
408
408
  throw new RangeError(
409
- `ElementPositions: row ${String(t)} was written the unstorable coordinate (${String(e)}, ${String(s)}, ${String(r)}); NaN is this class's UNPLACED marker, and an infinity -- including one an f32 overflow produces -- poisons the scene bounds`
409
+ `ElementPositions: row ${String(t)} was written the unstorable coordinate (${String(e)}, ${String(i)}, ${String(r)}); NaN is this class's UNPLACED marker, and an infinity -- including one an f32 overflow produces -- poisons the scene bounds`
410
410
  );
411
- this.array[n] = e, this.array[n + 1] = s, this.array[n + 2] = r;
411
+ this.array[n] = e, this.array[n + 1] = i, this.array[n + 2] = r;
412
412
  }
413
413
  /**
414
414
  * Write a row ONLY when it is unplaced. This is how importer-seeded coordinates reach a new
@@ -426,9 +426,9 @@ class x {
426
426
  * @throws RangeError when any component is NaN, an infinity, or a double that overflows f32,
427
427
  * through `write()`
428
428
  */
429
- fillUnplaced(t, e, s, r) {
429
+ fillUnplaced(t, e, i, r) {
430
430
  const n = this.rowBase(t);
431
- return this.hasStorableX(n) ? !1 : (this.write(t, e, s, r), !0);
431
+ return this.hasStorableX(n) ? !1 : (this.write(t, e, i, r), !0);
432
432
  }
433
433
  /**
434
434
  * Whether the row at this offset carries a storable x, which is the one test "placed" means.
@@ -446,12 +446,12 @@ class x {
446
446
  rowBase(t) {
447
447
  if (!Number.isInteger(t) || t < 0 || t >= this.rows)
448
448
  throw new RangeError(
449
- t === N ? "ElementPositions: INVALID_INDEX is the graph-format 'no node' sentinel, not a row" : `ElementPositions: row ${String(t)} is outside the live range [0, ${this.rows})`
449
+ t === w ? "ElementPositions: INVALID_INDEX is the graph-format 'no node' sentinel, not a row" : `ElementPositions: row ${String(t)} is outside the live range [0, ${this.rows})`
450
450
  );
451
- return o * t;
451
+ return a * t;
452
452
  }
453
453
  }
454
- const l = new T("layout"), W = Object.freeze([
454
+ const c = new _("layout"), G = Object.freeze([
455
455
  "arf",
456
456
  "bfs",
457
457
  "bipartite",
@@ -471,22 +471,22 @@ const l = new T("layout"), W = Object.freeze([
471
471
  "spiral",
472
472
  "spring",
473
473
  "spring-electrical"
474
- ]), G = v.getLogger(["graphty", "layout"]), P = 1e-6;
475
- function U(i, t) {
476
- return JSON.stringify([i, t]);
474
+ ]), U = $.getLogger(["graphty", "layout"]), P = 1e-6;
475
+ function V(s, t) {
476
+ return JSON.stringify([s, t]);
477
477
  }
478
- const V = 10;
479
- function A(i) {
478
+ const X = 10;
479
+ function A(s) {
480
480
  return new g({
481
481
  code: "E_DUPLICATE_PLUGIN",
482
- message: `"${i}" is a layout engine the element ships, and a built-in name may not be taken: a saved document that named it yesterday has to mean the same thing today`,
482
+ message: `"${s}" is a layout engine the element ships, and a built-in name may not be taken: a saved document that named it yesterday has to mean the same thing today`,
483
483
  source: "registry",
484
- details: { kind: "layout", name: i, builtIn: !0 }
484
+ details: { kind: "layout", name: s, builtIn: !0 }
485
485
  });
486
486
  }
487
- const E = class E {
487
+ const m = class m {
488
488
  constructor() {
489
- this.positionArrayAttached = !1;
489
+ this.positionArrayAttached = !1, this.hold = null, this.holdRows = 0;
490
490
  }
491
491
  /**
492
492
  * Add multiple nodes to the layout engine
@@ -534,7 +534,7 @@ const E = class E {
534
534
  * @param _nodes - the nodes that have just arrived
535
535
  */
536
536
  updatePositions(t) {
537
- for (let e = 0; e < V; e++) {
537
+ for (let e = 0; e < X; e++) {
538
538
  if (this.isSettled)
539
539
  return;
540
540
  this.step();
@@ -570,6 +570,37 @@ const E = class E {
570
570
  attachPositions(t) {
571
571
  this.positionArray = t, this.positionArrayAttached = !0;
572
572
  }
573
+ /**
574
+ * Hold the nodes a scoped layout may not move, or release them all with null.
575
+ *
576
+ * The element calls this on an engine whose class declares `static scoped = true`, after
577
+ * `init()` and after every renumbering of the graph. A set bit is a held row. A row at or past
578
+ * `rows` belongs to a node that arrived after the scope was captured, and is held too: the
579
+ * members of a scoped layout are the ones it started with. An engine that overrides this calls
580
+ * `super.setHoldMask` first and then fixes held nodes in its own state (see
581
+ * {@link LayoutEngineStatics.scoped}).
582
+ * @param mask - One bit per row, set for a row to hold; null holds nothing.
583
+ * @param rows - How many rows the mask covers.
584
+ */
585
+ setHoldMask(t, e) {
586
+ this.hold = t, this.holdRows = t === null ? 0 : e;
587
+ }
588
+ /**
589
+ * The hold mask the element last handed this engine, or null when nothing is held.
590
+ * @returns The mask, which the caller must not change.
591
+ */
592
+ get holdMask() {
593
+ return this.hold;
594
+ }
595
+ /**
596
+ * Whether the element is holding this row still for a scoped layout.
597
+ * @param index - The node's row, or `INVALID_INDEX`.
598
+ * @returns True while a hold is set and the row is held or newer than the hold.
599
+ */
600
+ isHeld(t) {
601
+ const { hold: e } = this;
602
+ return e === null ? !1 : t >= this.holdRows || !Number.isInteger(t) || t < 0 || v(e, t);
603
+ }
573
604
  /**
574
605
  * Copy every node's current coordinates out of the engine and into the position array.
575
606
  *
@@ -600,8 +631,8 @@ const E = class E {
600
631
  * @returns true when the node has a placed row
601
632
  */
602
633
  readNodePosition(t, e) {
603
- const s = this.positionsFor(t);
604
- return s.isPlaced(t.index) ? (s.read(t.index, e), !0) : !1;
634
+ const i = this.positionsFor(t);
635
+ return i.isPlaced(t.index) ? (i.read(t.index, e), !0) : !1;
605
636
  }
606
637
  /**
607
638
  * Publish one node's coordinates, growing the array to reach its row.
@@ -641,12 +672,12 @@ const E = class E {
641
672
  * @param intent - `"layout"` for a simulation step, `"placement"` for a drag or a replay
642
673
  * @returns true when the row was written
643
674
  */
644
- writeNodePosition(t, e, s, r, n = "layout") {
645
- const { index: a } = t;
646
- if (a === N || !Number.isInteger(a) || a < 0 || !d(e) || !d(s) || !d(r))
675
+ writeNodePosition(t, e, i, r, n = "layout") {
676
+ const { index: o } = t;
677
+ if (o === w || !Number.isInteger(o) || o < 0 || !d(e) || !d(i) || !d(r))
647
678
  return !1;
648
- const c = this.positionsFor(t);
649
- return n === "layout" && c.isPinned(a) ? !1 : (a >= c.count && c.grow(a + 1), c.write(a, e, s, r), !0);
679
+ const l = this.positionsFor(t);
680
+ return n === "layout" && (l.isPinned(o) || this.isHeld(o) && l.isPlaced(o)) ? !1 : (o >= l.count && l.grow(o + 1), l.write(o, e, i, r), !0);
650
681
  }
651
682
  /**
652
683
  * The weight of every ordered endpoint pair this batch of edges covers, or null when the
@@ -682,16 +713,16 @@ const E = class E {
682
713
  pairWeights(t) {
683
714
  if (t.length === 0)
684
715
  return null;
685
- const s = t[0].parentGraph?.getDataManager?.()?.getSnapshot?.()?.edgeList().weights ?? null;
686
- if (s === null)
716
+ const i = t[0].parentGraph?.getDataManager?.()?.getSnapshot?.()?.edgeList().weights ?? null;
717
+ if (i === null)
687
718
  return null;
688
719
  const r = /* @__PURE__ */ new Map();
689
720
  let n = !1;
690
- for (const a of t) {
691
- const c = a.index >= 0 && a.index < s.length ? s[a.index] : 1;
692
- c !== 1 && (n = !0);
693
- const I = U(a.srcId, a.dstId);
694
- r.set(I, (r.get(I) ?? 0) + c);
721
+ for (const o of t) {
722
+ const l = o.index >= 0 && o.index < i.length ? i[o.index] : 1;
723
+ l !== 1 && (n = !0);
724
+ const I = V(o.srcId, o.dstId);
725
+ r.set(I, (r.get(I) ?? 0) + l);
695
726
  }
696
727
  return n ? r : null;
697
728
  }
@@ -708,12 +739,12 @@ const E = class E {
708
739
  * @param weights - the pair weights about to be handed to the layout function
709
740
  */
710
741
  reportClampedWeights(t, e) {
711
- let s = 0;
742
+ let i = 0;
712
743
  for (const r of e.values())
713
- r < P && s++;
714
- s > 0 && G.warn("Edge weights at or below zero were clamped before the layout read them", {
744
+ r < P && i++;
745
+ i > 0 && U.warn("Edge weights at or below zero were clamped before the layout read them", {
715
746
  layout: t,
716
- clamped: s,
747
+ clamped: i,
717
748
  epsilon: P
718
749
  });
719
750
  }
@@ -762,42 +793,46 @@ const E = class E {
762
793
  * `E_DUPLICATE_PLUGIN` when the name or the descriptor id is one the element itself ships.
763
794
  */
764
795
  static register(t) {
765
- const e = t, { type: s, descriptor: r } = e;
766
- if (typeof s != "string" || s === "")
796
+ const e = t, { type: i, descriptor: r } = e;
797
+ if (typeof i != "string" || i === "")
767
798
  throw new g({
768
799
  code: "E_BAD_COMMAND",
769
800
  message: "a layout engine is filed under its `static type`, and this class declares none",
770
801
  source: "registry",
771
802
  details: { kind: "layout", field: "type" }
772
803
  });
773
- if (l.get(s) === t)
804
+ if (c.get(i) === t)
774
805
  return t;
775
- const n = W.includes(s);
806
+ const n = G.includes(i);
776
807
  if (r === void 0) {
777
808
  if (!n)
778
809
  throw new g({
779
810
  code: "E_BAD_COMMAND",
780
- message: `the layout "${s}" declares no \`static descriptor\`, so nothing could offer it: a picker reads the catalogue, and an engine the catalogue does not carry is reachable only by a consumer who already knows its name`,
811
+ message: `the layout "${i}" declares no \`static descriptor\`, so nothing could offer it: a picker reads the catalogue, and an engine the catalogue does not carry is reachable only by a consumer who already knows its name`,
781
812
  source: "registry",
782
- details: { kind: "layout", name: s, field: "descriptor" }
813
+ details: { kind: "layout", name: i, field: "descriptor" }
783
814
  });
784
- if (l.hasOwn(s))
785
- throw A(s);
786
- return l.set(s, t), t;
815
+ if (c.hasOwn(i))
816
+ throw A(i);
817
+ return c.set(i, t), t;
787
818
  }
788
819
  if (n)
789
- throw A(s);
790
- if (r.id !== s)
820
+ throw A(i);
821
+ if (r.id !== i)
791
822
  throw new g({
792
823
  code: "E_BAD_COMMAND",
793
- message: `the layout "${s}" describes itself as "${r.id}". A layout has ONE key: the name \`setLayout\` takes and the name the catalogue publishes are the same string, so nothing has to be named twice and a saved document means one thing`,
824
+ message: `the layout "${i}" describes itself as "${r.id}". A layout has ONE key: the name \`setLayout\` takes and the name the catalogue publishes are the same string, so nothing has to be named twice and a saved document means one thing`,
794
825
  source: "registry",
795
- details: { kind: "layout", name: s, field: "descriptor.id", id: r.id }
826
+ details: { kind: "layout", name: i, field: "descriptor.id", id: r.id }
796
827
  });
797
- return B({
798
- descriptor: { ...r, honoursWeights: e.honoursWeights ?? !1 },
799
- type: s
800
- }), l.set(s, t), t;
828
+ return C({
829
+ descriptor: {
830
+ ...r,
831
+ honoursWeights: e.honoursWeights ?? !1,
832
+ scoped: e.scoped ?? !1
833
+ },
834
+ type: i
835
+ }), c.set(i, t), t;
801
836
  }
802
837
  /**
803
838
  * Get a layout engine instance by type
@@ -806,8 +841,8 @@ const E = class E {
806
841
  * @returns A new layout engine instance or null if type not found
807
842
  */
808
843
  static get(t, e = {}) {
809
- const s = l.get(t);
810
- return s ? new s(e) : null;
844
+ const i = c.get(t);
845
+ return i ? new i(e) : null;
811
846
  }
812
847
  /**
813
848
  * Get dimension-specific options for this layout
@@ -824,8 +859,8 @@ const E = class E {
824
859
  * @returns Options object for the dimension or null if type not found or unsupported
825
860
  */
826
861
  static getOptionsForDimensionByType(t, e) {
827
- const s = l.get(t);
828
- return s ? s.getOptionsForDimension(e) : null;
862
+ const i = c.get(t);
863
+ return i ? i.getOptionsForDimension(e) : null;
829
864
  }
830
865
  /**
831
866
  * Get the Zod-based options schema for this layout
@@ -846,7 +881,7 @@ const E = class E {
846
881
  * @returns Array of registered layout type identifiers
847
882
  */
848
883
  static getRegisteredTypes() {
849
- return Array.from(l.keys());
884
+ return Array.from(c.keys());
850
885
  }
851
886
  /**
852
887
  * Get a layout class by type
@@ -854,22 +889,22 @@ const E = class E {
854
889
  * @returns The layout engine class or null if not found
855
890
  */
856
891
  static getClass(t) {
857
- return l.get(t) ?? null;
892
+ return c.get(t) ?? null;
858
893
  }
859
894
  };
860
- E.honoursWeights = !1;
861
- let w = E;
862
- const X = O.looseObject({
895
+ m.honoursWeights = !1, m.scoped = !1;
896
+ let b = m;
897
+ const H = O.looseObject({
863
898
  scalingFactor: O.number().default(100)
864
899
  });
865
- class ut extends w {
900
+ class pt extends b {
866
901
  /**
867
902
  * Create a simple layout engine
868
903
  * @param opts - Configuration options including scalingFactor
869
904
  */
870
905
  constructor(t = {}) {
871
906
  super(), this._nodes = [], this._edges = [], this.stale = !0, this.positions = {}, this.scalingFactor = 100, this.isSettled = !0;
872
- const e = X.parse(t);
907
+ const e = H.parse(t);
873
908
  this.scalingFactor = e.scalingFactor;
874
909
  }
875
910
  /**
@@ -929,8 +964,8 @@ class ut extends w {
929
964
  * @param p - where it moved to
930
965
  */
931
966
  setNodePosition(t, e) {
932
- const s = e.z ?? 0;
933
- this.writeNodePosition(t, e.x, e.y, s, "placement"), this.positions[t.id] = [e.x / this.scalingFactor, e.y / this.scalingFactor, s / this.scalingFactor];
967
+ const i = e.z ?? 0;
968
+ this.writeNodePosition(t, e.x, e.y, i, "placement"), this.positions[t.id] = [e.x / this.scalingFactor, e.y / this.scalingFactor, i / this.scalingFactor];
934
969
  }
935
970
  /**
936
971
  * Get the position of an edge based on its endpoints
@@ -1057,105 +1092,105 @@ class ut extends w {
1057
1092
  * @returns a fresh coordinate triple
1058
1093
  */
1059
1094
  publishedOr(t, e) {
1060
- const s = { x: 0, y: 0, z: 0 };
1061
- return t !== void 0 && this.readNodePosition(t, s) ? s : K(this.positions[e], this.scalingFactor);
1095
+ const i = { x: 0, y: 0, z: 0 };
1096
+ return t !== void 0 && this.readNodePosition(t, i) ? i : K(this.positions[e], this.scalingFactor);
1062
1097
  }
1063
1098
  }
1064
- function K(i, t) {
1065
- if (!i || i.length === 0)
1099
+ function K(s, t) {
1100
+ if (!s || s.length === 0)
1066
1101
  return { x: 0, y: 0, z: 0 };
1067
- const e = i[0] * t, s = i[1] * t, r = (i[2] ?? 0) * t;
1068
- return { x: e, y: s, z: r };
1102
+ const e = s[0] * t, i = s[1] * t, r = (s[2] ?? 0) * t;
1103
+ return { x: e, y: i, z: r };
1069
1104
  }
1070
- const H = /^#[0-9a-f]{6}$/i;
1071
- function q(i) {
1072
- if (typeof i != "string" || i.trim() === "")
1105
+ const q = /^#[0-9a-f]{6}$/i;
1106
+ function J(s) {
1107
+ if (typeof s != "string" || s.trim() === "")
1073
1108
  return null;
1074
1109
  try {
1075
- const t = L(i.trim());
1110
+ const t = L(s.trim());
1076
1111
  if (t === void 0)
1077
1112
  return null;
1078
1113
  const e = t.length === 9 ? t.slice(0, 7) : t;
1079
- return H.test(e) ? e.toUpperCase() : null;
1114
+ return q.test(e) ? e.toUpperCase() : null;
1080
1115
  } catch {
1081
1116
  return null;
1082
1117
  }
1083
1118
  }
1084
- function J(i) {
1085
- return JSON.stringify([i.id, i.kind, i.colors, i.capacity, i.colorblindSafe]);
1119
+ function Y(s) {
1120
+ return JSON.stringify([s.id, s.kind, s.colors, s.capacity, s.colorblindSafe]);
1086
1121
  }
1087
- const y = b({
1122
+ const N = E({
1088
1123
  kind: "palette",
1089
- idOf: (i) => i.id,
1090
- descriptorOf: (i) => i,
1091
- implementationOf: J,
1124
+ idOf: (s) => s.id,
1125
+ descriptorOf: (s) => s,
1126
+ implementationOf: Y,
1092
1127
  builtInIds: () => k
1093
1128
  });
1094
- function u(i, t, e) {
1129
+ function u(s, t, e) {
1095
1130
  throw new g({
1096
1131
  code: "E_BAD_COMMAND",
1097
1132
  message: e,
1098
1133
  source: "registry",
1099
- details: { kind: "palette", name: typeof i == "string" ? i : "", field: t }
1134
+ details: { kind: "palette", name: typeof s == "string" ? s : "", field: t }
1100
1135
  });
1101
1136
  }
1102
- function pt(i, t) {
1103
- typeof i != "object" && u("", "descriptor", "registerPalette takes a palette descriptor"), (i.plainName === void 0 || i.plainName === "") && u(i.id, "plainName", `the palette "${String(i.id)}" was registered without a plain name`), i.kind !== "sequential" && i.kind !== "diverging" && i.kind !== "categorical" && u(
1104
- i.id,
1137
+ function gt(s, t) {
1138
+ typeof s != "object" && u("", "descriptor", "registerPalette takes a palette descriptor"), (s.plainName === void 0 || s.plainName === "") && u(s.id, "plainName", `the palette "${String(s.id)}" was registered without a plain name`), s.kind !== "sequential" && s.kind !== "diverging" && s.kind !== "categorical" && u(
1139
+ s.id,
1105
1140
  "kind",
1106
- `the palette "${String(i.id)}" must be sequential, diverging or categorical`
1107
- ), (!Array.isArray(i.colors) || i.colors.length === 0) && u(i.id, "colors", `the palette "${String(i.id)}" was registered with no colours`);
1141
+ `the palette "${String(s.id)}" must be sequential, diverging or categorical`
1142
+ ), (!Array.isArray(s.colors) || s.colors.length === 0) && u(s.id, "colors", `the palette "${String(s.id)}" was registered with no colours`);
1108
1143
  const e = [];
1109
- for (const r of i.colors) {
1110
- const n = q(r);
1111
- n === null && u(i.id, "colors", `"${String(r)}" in the palette "${String(i.id)}" is not a colour`), e.push(n);
1144
+ for (const r of s.colors) {
1145
+ const n = J(r);
1146
+ n === null && u(s.id, "colors", `"${String(r)}" in the palette "${String(s.id)}" is not a colour`), e.push(n);
1112
1147
  }
1113
- const s = i.kind === "categorical" ? e.length : null;
1114
- i.capacity !== void 0 && i.capacity !== s && u(
1115
- i.id,
1148
+ const i = s.kind === "categorical" ? e.length : null;
1149
+ s.capacity !== void 0 && s.capacity !== i && u(
1150
+ s.id,
1116
1151
  "capacity",
1117
- `the palette "${String(i.id)}" is ${i.kind}, so its capacity is ${s === null ? "null" : String(s)} rather than ${String(i.capacity)}`
1118
- ), y.register(
1152
+ `the palette "${String(s.id)}" is ${s.kind}, so its capacity is ${i === null ? "null" : String(i)} rather than ${String(s.capacity)}`
1153
+ ), N.register(
1119
1154
  Object.freeze({
1120
- ...i,
1155
+ ...s,
1121
1156
  colors: Object.freeze(e),
1122
- capacity: s,
1123
- colorblindSafe: Object.freeze(i.colorblindSafe ?? [])
1157
+ capacity: i,
1158
+ colorblindSafe: Object.freeze(s.colorblindSafe ?? [])
1124
1159
  }),
1125
1160
  t
1126
1161
  );
1127
1162
  }
1128
- function gt() {
1129
- return y.descriptors();
1163
+ function ft() {
1164
+ return N.descriptors();
1130
1165
  }
1131
- function ft(i) {
1132
- return y.byId(i);
1166
+ function mt(s) {
1167
+ return N.byId(s);
1133
1168
  }
1134
- function mt() {
1135
- y.clearForTesting();
1169
+ function yt() {
1170
+ N.clearForTesting();
1136
1171
  }
1137
1172
  export {
1138
1173
  x as E,
1139
- _ as F,
1140
- w as L,
1141
- o as P,
1142
- X as S,
1143
- ot as U,
1174
+ T as F,
1175
+ b as L,
1176
+ a as P,
1177
+ H as S,
1178
+ at as U,
1144
1179
  P as W,
1145
- ut as a,
1146
- dt as b,
1147
- nt as c,
1148
- mt as d,
1149
- $ as e,
1150
- ct as f,
1151
- gt as g,
1152
- rt as h,
1153
- at as i,
1154
- lt as j,
1155
- U as k,
1156
- ht as l,
1157
- ft as m,
1180
+ pt as a,
1181
+ ut as b,
1182
+ ot as c,
1183
+ yt as d,
1184
+ R as e,
1185
+ ht as f,
1186
+ ft as g,
1187
+ nt as h,
1188
+ lt as i,
1189
+ ct as j,
1190
+ V as k,
1191
+ dt as l,
1192
+ mt as m,
1158
1193
  d as n,
1159
- st as p,
1160
- pt as r
1194
+ rt as p,
1195
+ gt as r
1161
1196
  };