@opendata-ai/openchart-vanilla 8.2.0 → 8.2.2

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.
package/dist/index.js CHANGED
@@ -6,13 +6,14 @@ import {
6
6
  } from "./chunk-DCODCLWI.js";
7
7
  import {
8
8
  renderTileMapSVG
9
- } from "./chunk-BGJT3GTB.js";
9
+ } from "./chunk-ZKASH7AX.js";
10
10
  import {
11
11
  AnimationScheduler,
12
12
  CANVAS_DEFAULT_UPDATE_MAX_MARKS,
13
13
  DEFAULT_UPDATE_MAX_MARKS,
14
14
  SpatialIndex,
15
15
  VECTOR_EXPORT_MAX_POINTS,
16
+ applySrOnlyStyles,
16
17
  cancelAnimations,
17
18
  createChart,
18
19
  createGeoMap,
@@ -24,15 +25,13 @@ import {
24
25
  materializeCanvasModeSVG,
25
26
  observeResize,
26
27
  prefersReducedMotion,
27
- quadtree,
28
28
  resolveDarkMode,
29
29
  resolveEase,
30
30
  resolveFontFamily,
31
31
  scheduleFontReload,
32
32
  setupAnimationCleanup,
33
- setupTableAnimationCleanup,
34
- zoom_default
35
- } from "./chunk-RC5PGDQX.js";
33
+ setupTableAnimationCleanup
34
+ } from "./chunk-BKN4R3J6.js";
36
35
  import {
37
36
  embedFonts,
38
37
  ensureSVGDimensions,
@@ -50,7 +49,7 @@ import {
50
49
  registerMarkRenderer,
51
50
  renderChartSVG,
52
51
  stampAnimationVars
53
- } from "./chunk-XOZ6AM7C.js";
52
+ } from "./chunk-2CEKMIJH.js";
54
53
  import {
55
54
  injectThemeStyleBlock
56
55
  } from "./chunk-RM5XS6NR.js";
@@ -102,12 +101,12 @@ function renderWatermark(parent, layout) {
102
101
  const rightEdge = width - padding;
103
102
  const bottomEdge = height - padding;
104
103
  const fill = theme.colors.axis;
105
- const a2 = createSVGElement("a");
106
- a2.setAttribute("href", BRAND_URL);
107
- a2.setAttributeNS(XLINK_NS, "xlink:href", BRAND_URL);
108
- a2.setAttribute("target", "_blank");
109
- a2.setAttribute("rel", "noopener");
110
- a2.setAttribute("class", "oc-chrome-ref");
104
+ const a = createSVGElement("a");
105
+ a.setAttribute("href", BRAND_URL);
106
+ a.setAttributeNS(XLINK_NS, "xlink:href", BRAND_URL);
107
+ a.setAttribute("target", "_blank");
108
+ a.setAttribute("rel", "noopener");
109
+ a.setAttribute("class", "oc-chrome-ref");
111
110
  const text = createSVGElement("text");
112
111
  setAttrs(text, {
113
112
  x: rightEdge,
@@ -131,8 +130,8 @@ function renderWatermark(parent, layout) {
131
130
  text.appendChild(trySpan);
132
131
  text.appendChild(openDataSpan);
133
132
  text.appendChild(aiSpan);
134
- a2.appendChild(text);
135
- parent.appendChild(a2);
133
+ a.appendChild(text);
134
+ parent.appendChild(a);
136
135
  }
137
136
  function renderRows(parent, rows, animation) {
138
137
  const g = createSVGElement("g");
@@ -309,9 +308,9 @@ function createBarList(container, spec, options) {
309
308
  const mouseEvent = e;
310
309
  if (content && tooltipManager && options?.tooltip !== false) {
311
310
  const svgRect = svg.getBoundingClientRect();
312
- const x3 = mouseEvent.clientX - svgRect.left;
313
- const y3 = mouseEvent.clientY - svgRect.top;
314
- tooltipManager.show(content, x3, y3);
311
+ const x = mouseEvent.clientX - svgRect.left;
312
+ const y = mouseEvent.clientY - svgRect.top;
313
+ tooltipManager.show(content, x, y);
315
314
  }
316
315
  if (row) {
317
316
  options?.onRowHover?.({
@@ -325,9 +324,9 @@ function createBarList(container, spec, options) {
325
324
  if (content && tooltipManager && options?.tooltip !== false) {
326
325
  const mouseEvent = e;
327
326
  const svgRect = svg.getBoundingClientRect();
328
- const x3 = mouseEvent.clientX - svgRect.left;
329
- const y3 = mouseEvent.clientY - svgRect.top;
330
- tooltipManager.show(content, x3, y3);
327
+ const x = mouseEvent.clientX - svgRect.left;
328
+ const y = mouseEvent.clientY - svgRect.top;
329
+ tooltipManager.show(content, x, y);
331
330
  }
332
331
  };
333
332
  const handleMouseLeave = () => {
@@ -596,8 +595,8 @@ async function exportSpecSequence(specs, options) {
596
595
  const globalPalette = paletteFromCanvas(frames[frames.length - 1].canvas, quantize);
597
596
  const gif = GIFEncoder();
598
597
  frames.forEach(({ canvas, delayMs }, i) => {
599
- const index2 = applyPalette(readCanvasSRGB(canvas), globalPalette);
600
- gif.writeFrame(index2, canvas.width, canvas.height, {
598
+ const index = applyPalette(readCanvasSRGB(canvas), globalPalette);
599
+ gif.writeFrame(index, canvas.width, canvas.height, {
601
600
  palette: globalPalette,
602
601
  delay: delayMs,
603
602
  // `repeat` writes the loop extension; only meaningful on the first frame.
@@ -620,11 +619,14 @@ function createSimulationWorker() {
620
619
  // src/graph-mount.ts
621
620
  import { buildEdgeTooltip, compileGraph } from "@opendata-ai/openchart-engine";
622
621
 
622
+ // src/graph/camera.ts
623
+ import { interpolateZoom } from "d3-interpolate";
624
+
623
625
  // src/graph/zoom.ts
624
626
  var ZoomTransform = class _ZoomTransform {
625
- constructor(x3, y3, k) {
626
- this.x = x3;
627
- this.y = y3;
627
+ constructor(x, y, k) {
628
+ this.x = x;
629
+ this.y = y;
628
630
  this.k = k;
629
631
  }
630
632
  /** Convert screen coordinates to graph coordinates. */
@@ -734,9 +736,9 @@ function transformToView(t, viewport) {
734
736
  function viewToTransform(view, viewport) {
735
737
  const [cx, cy, width] = view;
736
738
  const k = clampK(viewport.width / width);
737
- const x3 = viewport.width / 2 - cx * k;
738
- const y3 = viewport.height / 2 - cy * k;
739
- return new ZoomTransform(x3, y3, k);
739
+ const x = viewport.width / 2 - cx * k;
740
+ const y = viewport.height / 2 - cy * k;
741
+ return new ZoomTransform(x, y, k);
740
742
  }
741
743
  function clampK(k) {
742
744
  if (!Number.isFinite(k) || k <= 0) return K_MIN;
@@ -751,12 +753,12 @@ function createCameraFlight(inputs) {
751
753
  const to = isProvider ? inputs.to() : inputs.to;
752
754
  return transformToView(to, viewport);
753
755
  }
754
- let interp = zoom_default(fromView, targetView());
756
+ let interp = interpolateZoom(fromView, targetView());
755
757
  const resolvedDuration = resolveDuration(opts?.duration, interp.duration);
756
758
  let startTime = null;
757
759
  let finished = false;
758
760
  function applyAt(t) {
759
- if (isProvider) interp = zoom_default(fromView, targetView());
761
+ if (isProvider) interp = interpolateZoom(fromView, targetView());
760
762
  const view = interp(t);
761
763
  if (view.some((v) => !Number.isFinite(v))) {
762
764
  apply(viewToTransform(targetView(), viewport));
@@ -765,10 +767,10 @@ function createCameraFlight(inputs) {
765
767
  apply(viewToTransform(view, viewport));
766
768
  }
767
769
  return {
768
- tick(now2) {
770
+ tick(now) {
769
771
  if (finished) return false;
770
- if (startTime === null) startTime = now2;
771
- const raw = resolvedDuration <= 0 ? 1 : Math.min(1, (now2 - startTime) / resolvedDuration);
772
+ if (startTime === null) startTime = now;
773
+ const raw = resolvedDuration <= 0 ? 1 : Math.min(1, (now - startTime) / resolvedDuration);
772
774
  applyAt(ease(raw));
773
775
  if (raw >= 1) {
774
776
  finished = true;
@@ -818,9 +820,9 @@ function resolveDuration(duration, interpDuration) {
818
820
  import { BRAND_FONT_SIZE, BRAND_MIN_WIDTH } from "@opendata-ai/openchart-core";
819
821
 
820
822
  // src/graph/entrance.ts
821
- function nodeEnterProgress(globalT, index2, total, buckets = 8) {
823
+ function nodeEnterProgress(globalT, index, total, buckets = 8) {
822
824
  const g = globalT <= 0 ? 0 : globalT >= 1 ? 1 : globalT;
823
- const start = total > 0 ? index2 / total * 0.4 : 0;
825
+ const start = total > 0 ? index / total * 0.4 : 0;
824
826
  const local = (g - start) / 0.6;
825
827
  const clamped = local <= 0 ? 0 : local >= 1 ? 1 : local;
826
828
  const b = Math.max(1, Math.floor(buckets));
@@ -850,10 +852,10 @@ function hashId(id) {
850
852
  function entranceOrder(nodes) {
851
853
  const rank = /* @__PURE__ */ new Map();
852
854
  if (nodes.length === 0) return rank;
853
- const sorted = [...nodes].sort((a2, b) => {
854
- const ha = hashId(a2.id);
855
+ const sorted = [...nodes].sort((a, b) => {
856
+ const ha = hashId(a.id);
855
857
  const hb = hashId(b.id);
856
- return ha - hb || (a2.id < b.id ? -1 : a2.id > b.id ? 1 : 0);
858
+ return ha - hb || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
857
859
  });
858
860
  for (let i = 0; i < sorted.length; i++) rank.set(sorted[i].id, i);
859
861
  return rank;
@@ -883,8 +885,8 @@ function popScale(t) {
883
885
  return 1 + c3 * u * u * u + c1 * u * u;
884
886
  }
885
887
  function popAlpha(t) {
886
- const a2 = t / 0.6;
887
- return a2 >= 1 ? 1 : a2 <= 0 ? 0 : a2;
888
+ const a = t / 0.6;
889
+ return a >= 1 ? 1 : a <= 0 ? 0 : a;
888
890
  }
889
891
  function driftFactor(t) {
890
892
  const u = 1 - (t <= 0 ? 0 : t >= 1 ? 1 : t);
@@ -926,8 +928,8 @@ function nodeTierAlpha(tier, dimOpacity) {
926
928
  return 1;
927
929
  }
928
930
  }
929
- function lerp(a2, b, t) {
930
- return a2 + (b - a2) * t;
931
+ function lerp(a, b, t) {
932
+ return a + (b - a) * t;
931
933
  }
932
934
  var ZERO_SHIFT = { x: 0, y: 0 };
933
935
  function makeEntranceReveal(entrance, total) {
@@ -977,12 +979,12 @@ function labelThreshold(zoom) {
977
979
  return 1 - t;
978
980
  }
979
981
  function visibleRect(canvasWidth, canvasHeight, transform, margin = CULL_MARGIN) {
980
- const { x: x3, y: y3, k } = transform;
982
+ const { x, y, k } = transform;
981
983
  return {
982
- minX: (-x3 - margin) / k,
983
- minY: (-y3 - margin) / k,
984
- maxX: (canvasWidth - x3 + margin) / k,
985
- maxY: (canvasHeight - y3 + margin) / k
984
+ minX: (-x - margin) / k,
985
+ minY: (-y - margin) / k,
986
+ maxX: (canvasWidth - x + margin) / k,
987
+ maxY: (canvasHeight - y + margin) / k
986
988
  };
987
989
  }
988
990
  function nodeInView(node, rect) {
@@ -1127,14 +1129,14 @@ var GraphCanvasRenderer = class {
1127
1129
  ctx.save();
1128
1130
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
1129
1131
  const padding = theme.spacing.padding;
1130
- const x3 = w - padding;
1131
- const y3 = h - padding;
1132
+ const x = w - padding;
1133
+ const y = h - padding;
1132
1134
  ctx.font = `600 ${BRAND_FONT_SIZE}px ${theme.fonts.family}`;
1133
1135
  ctx.fillStyle = theme.colors.axis;
1134
1136
  ctx.globalAlpha = 0.55;
1135
1137
  ctx.textAlign = "right";
1136
1138
  ctx.textBaseline = "alphabetic";
1137
- ctx.fillText("tryOpenData.ai", x3, y3);
1139
+ ctx.fillText("tryOpenData.ai", x, y);
1138
1140
  ctx.restore();
1139
1141
  }
1140
1142
  // -------------------------------------------------------------------------
@@ -1207,7 +1209,7 @@ var GraphCanvasRenderer = class {
1207
1209
  const [prevTier, nextTier] = key.split("|");
1208
1210
  const alpha = lerp(edgeTierAlpha(prevTier, dimOpacity), edgeTierAlpha(nextTier, dimOpacity), t) * ea;
1209
1211
  return { alpha, bucket };
1210
- }).sort((a2, b) => a2.alpha - b.alpha);
1212
+ }).sort((a, b) => a.alpha - b.alpha);
1211
1213
  for (const { alpha, bucket } of ordered) {
1212
1214
  this.drawEdgeGroupBatched(ctx, bucket, alpha, searchMatches, enterAlphaFor);
1213
1215
  }
@@ -1532,7 +1534,7 @@ function brighten(color) {
1532
1534
  return `rgb(${r},${g},${b})`;
1533
1535
  }
1534
1536
  const hex = color.replace("#", "");
1535
- const full = hex.length === 3 ? hex.split("").map((c2) => c2 + c2).join("") : hex;
1537
+ const full = hex.length === 3 ? hex.split("").map((c) => c + c).join("") : hex;
1536
1538
  if (full.length === 6) {
1537
1539
  const r = Math.min(255, parseInt(full.slice(0, 2), 16) + 40);
1538
1540
  const g = Math.min(255, parseInt(full.slice(2, 4), 16) + 40);
@@ -1543,17 +1545,17 @@ function brighten(color) {
1543
1545
  }
1544
1546
 
1545
1547
  // src/graph/focus-transition.ts
1546
- function focusSnapshotsEqual(a2, b) {
1547
- return a2.hasActive === b.hasActive && setsEqual(a2.connected, b.connected) && nullableSetsEqual(a2.searchMatches, b.searchMatches) && setsEqual(a2.selected, b.selected);
1548
+ function focusSnapshotsEqual(a, b) {
1549
+ return a.hasActive === b.hasActive && setsEqual(a.connected, b.connected) && nullableSetsEqual(a.searchMatches, b.searchMatches) && setsEqual(a.selected, b.selected);
1548
1550
  }
1549
- function setsEqual(a2, b) {
1550
- if (a2.size !== b.size) return false;
1551
- for (const v of a2) if (!b.has(v)) return false;
1551
+ function setsEqual(a, b) {
1552
+ if (a.size !== b.size) return false;
1553
+ for (const v of a) if (!b.has(v)) return false;
1552
1554
  return true;
1553
1555
  }
1554
- function nullableSetsEqual(a2, b) {
1555
- if (a2 === null || b === null) return a2 === b;
1556
- return setsEqual(a2, b);
1556
+ function nullableSetsEqual(a, b) {
1557
+ if (a === null || b === null) return a === b;
1558
+ return setsEqual(a, b);
1557
1559
  }
1558
1560
  var FocusTransition = class {
1559
1561
  prev;
@@ -1561,10 +1563,10 @@ var FocusTransition = class {
1561
1563
  startTime;
1562
1564
  duration;
1563
1565
  ease;
1564
- constructor(initial, duration, ease, now2) {
1566
+ constructor(initial, duration, ease, now) {
1565
1567
  this.prev = initial;
1566
1568
  this.next = initial;
1567
- this.startTime = now2;
1569
+ this.startTime = now;
1568
1570
  this.duration = Math.max(0, duration);
1569
1571
  this.ease = ease;
1570
1572
  }
@@ -1573,25 +1575,25 @@ var FocusTransition = class {
1573
1575
  * current display as the new `prev` (the `p < 0.5` rule). A no-op when
1574
1576
  * `target` already equals `next`.
1575
1577
  */
1576
- retarget(target, now2) {
1578
+ retarget(target, now) {
1577
1579
  if (focusSnapshotsEqual(target, this.next)) return;
1578
- const p = this.rawProgress(now2);
1580
+ const p = this.rawProgress(now);
1579
1581
  this.prev = p < 0.5 ? this.prev : this.next;
1580
1582
  this.next = target;
1581
- this.startTime = now2;
1583
+ this.startTime = now;
1582
1584
  }
1583
1585
  /** Raw (un-eased) 0..1 progress. */
1584
- rawProgress(now2) {
1586
+ rawProgress(now) {
1585
1587
  if (this.duration <= 0) return 1;
1586
- return Math.min(1, Math.max(0, (now2 - this.startTime) / this.duration));
1588
+ return Math.min(1, Math.max(0, (now - this.startTime) / this.duration));
1587
1589
  }
1588
1590
  /** Eased 0..1 progress toward `next`. */
1589
- progress(now2) {
1590
- return this.ease(this.rawProgress(now2));
1591
+ progress(now) {
1592
+ return this.ease(this.rawProgress(now));
1591
1593
  }
1592
1594
  /** True once the transition has fully settled onto `next`. */
1593
- isSettled(now2) {
1594
- return this.rawProgress(now2) >= 1;
1595
+ isSettled(now) {
1596
+ return this.rawProgress(now) >= 1;
1595
1597
  }
1596
1598
  };
1597
1599
  function composeStandingFocus(highlight, searchMatches, selected, adjacency) {
@@ -1631,8 +1633,8 @@ function layerHoverFocus(standing, hoveredId, hoverConnected) {
1631
1633
  selected: standing.selected
1632
1634
  };
1633
1635
  }
1634
- function intersect(a2, b) {
1635
- const [small, large] = a2.size <= b.size ? [a2, b] : [b, a2];
1636
+ function intersect(a, b) {
1637
+ const [small, large] = a.size <= b.size ? [a, b] : [b, a];
1636
1638
  const out = /* @__PURE__ */ new Set();
1637
1639
  for (const v of small) if (large.has(v)) out.add(v);
1638
1640
  return out;
@@ -1732,31 +1734,31 @@ var GraphInteractionManager = class {
1732
1734
  }
1733
1735
  onWheel(e) {
1734
1736
  e.preventDefault();
1735
- const { x: x3, y: y3 } = this.canvasXY(e);
1737
+ const { x, y } = this.canvasXY(e);
1736
1738
  const factor = e.deltaY * ZOOM_STEP;
1737
1739
  const newK = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, this.transform.k * (1 + factor)));
1738
- this.transform = this.transform.zoomAt(newK, x3, y3);
1740
+ this.transform = this.transform.zoomAt(newK, x, y);
1739
1741
  this.callbacks.onTransformChange(this.transform);
1740
1742
  }
1741
1743
  onMouseDown(e) {
1742
- const { x: x3, y: y3 } = this.canvasXY(e);
1743
- const hitId = this.hitTest(x3, y3);
1744
+ const { x, y } = this.canvasXY(e);
1745
+ const hitId = this.hitTest(x, y);
1744
1746
  if (hitId) {
1745
1747
  this.dragState = { nodeId: hitId, started: false };
1746
1748
  this.mousedownNodeId = hitId;
1747
1749
  } else {
1748
- this.panState = { startX: x3, startY: y3 };
1750
+ this.panState = { startX: x, startY: y };
1749
1751
  this.mousedownNodeId = null;
1750
1752
  }
1751
1753
  }
1752
1754
  onMouseMove(e) {
1753
- const { x: x3, y: y3 } = this.canvasXY(e);
1755
+ const { x, y } = this.canvasXY(e);
1754
1756
  if (this.callbacks.onPointerMove) {
1755
- const gp = this.transform.screenToGraph(x3, y3);
1757
+ const gp = this.transform.screenToGraph(x, y);
1756
1758
  this.callbacks.onPointerMove(gp.x, gp.y);
1757
1759
  }
1758
1760
  if (this.dragState) {
1759
- const graph = this.transform.screenToGraph(x3, y3);
1761
+ const graph = this.transform.screenToGraph(x, y);
1760
1762
  if (!this.dragState.started) {
1761
1763
  this.dragState.started = true;
1762
1764
  this.callbacks.onNodeDragStart(this.dragState.nodeId);
@@ -1765,23 +1767,23 @@ var GraphInteractionManager = class {
1765
1767
  return;
1766
1768
  }
1767
1769
  if (this.panState) {
1768
- const dx = x3 - this.panState.startX;
1769
- const dy = y3 - this.panState.startY;
1770
+ const dx = x - this.panState.startX;
1771
+ const dy = y - this.panState.startY;
1770
1772
  this.transform = this.transform.pan(dx, dy);
1771
- this.panState = { startX: x3, startY: y3 };
1773
+ this.panState = { startX: x, startY: y };
1772
1774
  this.callbacks.onTransformChange(this.transform);
1773
1775
  return;
1774
1776
  }
1775
- const hitId = this.hitTest(x3, y3);
1777
+ const hitId = this.hitTest(x, y);
1776
1778
  this.callbacks.onHoverChange(hitId);
1777
1779
  if (!hitId) {
1778
- const graph = this.transform.screenToGraph(x3, y3);
1779
- this.callbacks.onBackgroundHover?.(graph.x, graph.y, x3, y3);
1780
+ const graph = this.transform.screenToGraph(x, y);
1781
+ this.callbacks.onBackgroundHover?.(graph.x, graph.y, x, y);
1780
1782
  }
1781
1783
  this.canvas.style.cursor = hitId ? "pointer" : "default";
1782
1784
  }
1783
1785
  onMouseUp(e) {
1784
- const { x: x3, y: y3 } = this.canvasXY(e);
1786
+ const { x, y } = this.canvasXY(e);
1785
1787
  if (this.dragState) {
1786
1788
  if (this.dragState.started) {
1787
1789
  this.callbacks.onNodeDragEnd(this.dragState.nodeId);
@@ -1794,7 +1796,7 @@ var GraphInteractionManager = class {
1794
1796
  if (this.panState) {
1795
1797
  this.panState = null;
1796
1798
  if (!this.mousedownNodeId) {
1797
- const hitId = this.hitTest(x3, y3);
1799
+ const hitId = this.hitTest(x, y);
1798
1800
  if (!hitId) {
1799
1801
  this.selectedIds.clear();
1800
1802
  this.callbacks.onSelectionChange([]);
@@ -1804,8 +1806,8 @@ var GraphInteractionManager = class {
1804
1806
  }
1805
1807
  }
1806
1808
  onDblClick(e) {
1807
- const { x: x3, y: y3 } = this.canvasXY(e);
1808
- const hitId = this.hitTest(x3, y3);
1809
+ const { x, y } = this.canvasXY(e);
1810
+ const hitId = this.hitTest(x, y);
1809
1811
  if (hitId) {
1810
1812
  this.callbacks.onDoubleClick(hitId);
1811
1813
  }
@@ -1846,13 +1848,13 @@ var GraphInteractionManager = class {
1846
1848
  } else if (e.touches.length === 1) {
1847
1849
  const touch = e.touches[0];
1848
1850
  const rect = this.canvas.getBoundingClientRect();
1849
- const x3 = touch.clientX - rect.left;
1850
- const y3 = touch.clientY - rect.top;
1851
- const hitId = this.hitTest(x3, y3);
1851
+ const x = touch.clientX - rect.left;
1852
+ const y = touch.clientY - rect.top;
1853
+ const hitId = this.hitTest(x, y);
1852
1854
  if (hitId) {
1853
1855
  this.mousedownNodeId = hitId;
1854
1856
  } else {
1855
- this.panState = { startX: x3, startY: y3 };
1857
+ this.panState = { startX: x, startY: y };
1856
1858
  this.mousedownNodeId = null;
1857
1859
  }
1858
1860
  }
@@ -1882,12 +1884,12 @@ var GraphInteractionManager = class {
1882
1884
  } else if (e.touches.length === 1 && this.panState) {
1883
1885
  const touch = e.touches[0];
1884
1886
  const rect = this.canvas.getBoundingClientRect();
1885
- const x3 = touch.clientX - rect.left;
1886
- const y3 = touch.clientY - rect.top;
1887
- const dx = x3 - this.panState.startX;
1888
- const dy = y3 - this.panState.startY;
1887
+ const x = touch.clientX - rect.left;
1888
+ const y = touch.clientY - rect.top;
1889
+ const dx = x - this.panState.startX;
1890
+ const dy = y - this.panState.startY;
1889
1891
  this.transform = this.transform.pan(dx, dy);
1890
- this.panState = { startX: x3, startY: y3 };
1892
+ this.panState = { startX: x, startY: y };
1891
1893
  this.callbacks.onTransformChange(this.transform);
1892
1894
  }
1893
1895
  }
@@ -1933,9 +1935,9 @@ function attachGraphKeyboardNav(options) {
1933
1935
  if (candidates.length === 0) return null;
1934
1936
  let best = null;
1935
1937
  let bestScore = -Infinity;
1936
- for (const c2 of candidates) {
1937
- const dx = c2.x - fromNode.x;
1938
- const dy = c2.y - fromNode.y;
1938
+ for (const c of candidates) {
1939
+ const dx = c.x - fromNode.x;
1940
+ const dy = c.y - fromNode.y;
1939
1941
  let score;
1940
1942
  switch (direction) {
1941
1943
  case "right":
@@ -1953,7 +1955,7 @@ function attachGraphKeyboardNav(options) {
1953
1955
  }
1954
1956
  if (score > bestScore) {
1955
1957
  bestScore = score;
1956
- best = c2;
1958
+ best = c;
1957
1959
  }
1958
1960
  }
1959
1961
  return best?.id ?? null;
@@ -2192,634 +2194,16 @@ function seedNodePositions(nodes, seed) {
2192
2194
  }
2193
2195
  }
2194
2196
 
2195
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/center.js
2196
- function center_default(x3, y3) {
2197
- var nodes, strength = 1;
2198
- if (x3 == null) x3 = 0;
2199
- if (y3 == null) y3 = 0;
2200
- function force() {
2201
- var i, n = nodes.length, node, sx = 0, sy = 0;
2202
- for (i = 0; i < n; ++i) {
2203
- node = nodes[i], sx += node.x, sy += node.y;
2204
- }
2205
- for (sx = (sx / n - x3) * strength, sy = (sy / n - y3) * strength, i = 0; i < n; ++i) {
2206
- node = nodes[i], node.x -= sx, node.y -= sy;
2207
- }
2208
- }
2209
- force.initialize = function(_) {
2210
- nodes = _;
2211
- };
2212
- force.x = function(_) {
2213
- return arguments.length ? (x3 = +_, force) : x3;
2214
- };
2215
- force.y = function(_) {
2216
- return arguments.length ? (y3 = +_, force) : y3;
2217
- };
2218
- force.strength = function(_) {
2219
- return arguments.length ? (strength = +_, force) : strength;
2220
- };
2221
- return force;
2222
- }
2223
-
2224
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/constant.js
2225
- function constant_default(x3) {
2226
- return function() {
2227
- return x3;
2228
- };
2229
- }
2230
-
2231
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/jiggle.js
2232
- function jiggle_default(random) {
2233
- return (random() - 0.5) * 1e-6;
2234
- }
2235
-
2236
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/collide.js
2237
- function x(d) {
2238
- return d.x + d.vx;
2239
- }
2240
- function y(d) {
2241
- return d.y + d.vy;
2242
- }
2243
- function collide_default(radius) {
2244
- var nodes, radii, random, strength = 1, iterations = 1;
2245
- if (typeof radius !== "function") radius = constant_default(radius == null ? 1 : +radius);
2246
- function force() {
2247
- var i, n = nodes.length, tree, node, xi, yi, ri, ri2;
2248
- for (var k = 0; k < iterations; ++k) {
2249
- tree = quadtree(nodes, x, y).visitAfter(prepare);
2250
- for (i = 0; i < n; ++i) {
2251
- node = nodes[i];
2252
- ri = radii[node.index], ri2 = ri * ri;
2253
- xi = node.x + node.vx;
2254
- yi = node.y + node.vy;
2255
- tree.visit(apply);
2256
- }
2257
- }
2258
- function apply(quad, x0, y0, x1, y1) {
2259
- var data = quad.data, rj = quad.r, r = ri + rj;
2260
- if (data) {
2261
- if (data.index > node.index) {
2262
- var x3 = xi - data.x - data.vx, y3 = yi - data.y - data.vy, l = x3 * x3 + y3 * y3;
2263
- if (l < r * r) {
2264
- if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
2265
- if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
2266
- l = (r - (l = Math.sqrt(l))) / l * strength;
2267
- node.vx += (x3 *= l) * (r = (rj *= rj) / (ri2 + rj));
2268
- node.vy += (y3 *= l) * r;
2269
- data.vx -= x3 * (r = 1 - r);
2270
- data.vy -= y3 * r;
2271
- }
2272
- }
2273
- return;
2274
- }
2275
- return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
2276
- }
2277
- }
2278
- function prepare(quad) {
2279
- if (quad.data) return quad.r = radii[quad.data.index];
2280
- for (var i = quad.r = 0; i < 4; ++i) {
2281
- if (quad[i] && quad[i].r > quad.r) {
2282
- quad.r = quad[i].r;
2283
- }
2284
- }
2285
- }
2286
- function initialize() {
2287
- if (!nodes) return;
2288
- var i, n = nodes.length, node;
2289
- radii = new Array(n);
2290
- for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
2291
- }
2292
- force.initialize = function(_nodes, _random) {
2293
- nodes = _nodes;
2294
- random = _random;
2295
- initialize();
2296
- };
2297
- force.iterations = function(_) {
2298
- return arguments.length ? (iterations = +_, force) : iterations;
2299
- };
2300
- force.strength = function(_) {
2301
- return arguments.length ? (strength = +_, force) : strength;
2302
- };
2303
- force.radius = function(_) {
2304
- return arguments.length ? (radius = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : radius;
2305
- };
2306
- return force;
2307
- }
2308
-
2309
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/link.js
2310
- function index(d) {
2311
- return d.index;
2312
- }
2313
- function find(nodeById, nodeId) {
2314
- var node = nodeById.get(nodeId);
2315
- if (!node) throw new Error("node not found: " + nodeId);
2316
- return node;
2317
- }
2318
- function link_default(links) {
2319
- var id = index, strength = defaultStrength, strengths, distance = constant_default(30), distances, nodes, count, bias, random, iterations = 1;
2320
- if (links == null) links = [];
2321
- function defaultStrength(link) {
2322
- return 1 / Math.min(count[link.source.index], count[link.target.index]);
2323
- }
2324
- function force(alpha) {
2325
- for (var k = 0, n = links.length; k < iterations; ++k) {
2326
- for (var i = 0, link, source, target, x3, y3, l, b; i < n; ++i) {
2327
- link = links[i], source = link.source, target = link.target;
2328
- x3 = target.x + target.vx - source.x - source.vx || jiggle_default(random);
2329
- y3 = target.y + target.vy - source.y - source.vy || jiggle_default(random);
2330
- l = Math.sqrt(x3 * x3 + y3 * y3);
2331
- l = (l - distances[i]) / l * alpha * strengths[i];
2332
- x3 *= l, y3 *= l;
2333
- target.vx -= x3 * (b = bias[i]);
2334
- target.vy -= y3 * b;
2335
- source.vx += x3 * (b = 1 - b);
2336
- source.vy += y3 * b;
2337
- }
2338
- }
2339
- }
2340
- function initialize() {
2341
- if (!nodes) return;
2342
- var i, n = nodes.length, m2 = links.length, nodeById = new Map(nodes.map((d, i2) => [id(d, i2, nodes), d])), link;
2343
- for (i = 0, count = new Array(n); i < m2; ++i) {
2344
- link = links[i], link.index = i;
2345
- if (typeof link.source !== "object") link.source = find(nodeById, link.source);
2346
- if (typeof link.target !== "object") link.target = find(nodeById, link.target);
2347
- count[link.source.index] = (count[link.source.index] || 0) + 1;
2348
- count[link.target.index] = (count[link.target.index] || 0) + 1;
2349
- }
2350
- for (i = 0, bias = new Array(m2); i < m2; ++i) {
2351
- link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
2352
- }
2353
- strengths = new Array(m2), initializeStrength();
2354
- distances = new Array(m2), initializeDistance();
2355
- }
2356
- function initializeStrength() {
2357
- if (!nodes) return;
2358
- for (var i = 0, n = links.length; i < n; ++i) {
2359
- strengths[i] = +strength(links[i], i, links);
2360
- }
2361
- }
2362
- function initializeDistance() {
2363
- if (!nodes) return;
2364
- for (var i = 0, n = links.length; i < n; ++i) {
2365
- distances[i] = +distance(links[i], i, links);
2366
- }
2367
- }
2368
- force.initialize = function(_nodes, _random) {
2369
- nodes = _nodes;
2370
- random = _random;
2371
- initialize();
2372
- };
2373
- force.links = function(_) {
2374
- return arguments.length ? (links = _, initialize(), force) : links;
2375
- };
2376
- force.id = function(_) {
2377
- return arguments.length ? (id = _, force) : id;
2378
- };
2379
- force.iterations = function(_) {
2380
- return arguments.length ? (iterations = +_, force) : iterations;
2381
- };
2382
- force.strength = function(_) {
2383
- return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initializeStrength(), force) : strength;
2384
- };
2385
- force.distance = function(_) {
2386
- return arguments.length ? (distance = typeof _ === "function" ? _ : constant_default(+_), initializeDistance(), force) : distance;
2387
- };
2388
- return force;
2389
- }
2390
-
2391
- // ../../node_modules/.bun/d3-dispatch@3.0.1/node_modules/d3-dispatch/src/dispatch.js
2392
- var noop = { value: () => {
2393
- } };
2394
- function dispatch() {
2395
- for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
2396
- if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t)) throw new Error("illegal type: " + t);
2397
- _[t] = [];
2398
- }
2399
- return new Dispatch(_);
2400
- }
2401
- function Dispatch(_) {
2402
- this._ = _;
2403
- }
2404
- function parseTypenames(typenames, types) {
2405
- return typenames.trim().split(/^|\s+/).map(function(t) {
2406
- var name = "", i = t.indexOf(".");
2407
- if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
2408
- if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
2409
- return { type: t, name };
2410
- });
2411
- }
2412
- Dispatch.prototype = dispatch.prototype = {
2413
- constructor: Dispatch,
2414
- on: function(typename, callback) {
2415
- var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length;
2416
- if (arguments.length < 2) {
2417
- while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
2418
- return;
2419
- }
2420
- if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
2421
- while (++i < n) {
2422
- if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
2423
- else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
2424
- }
2425
- return this;
2426
- },
2427
- copy: function() {
2428
- var copy = {}, _ = this._;
2429
- for (var t in _) copy[t] = _[t].slice();
2430
- return new Dispatch(copy);
2431
- },
2432
- call: function(type, that) {
2433
- if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
2434
- if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
2435
- for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
2436
- },
2437
- apply: function(type, that, args) {
2438
- if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
2439
- for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
2440
- }
2441
- };
2442
- function get(type, name) {
2443
- for (var i = 0, n = type.length, c2; i < n; ++i) {
2444
- if ((c2 = type[i]).name === name) {
2445
- return c2.value;
2446
- }
2447
- }
2448
- }
2449
- function set(type, name, callback) {
2450
- for (var i = 0, n = type.length; i < n; ++i) {
2451
- if (type[i].name === name) {
2452
- type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
2453
- break;
2454
- }
2455
- }
2456
- if (callback != null) type.push({ name, value: callback });
2457
- return type;
2458
- }
2459
- var dispatch_default = dispatch;
2460
-
2461
- // ../../node_modules/.bun/d3-timer@3.0.1/node_modules/d3-timer/src/timer.js
2462
- var frame = 0;
2463
- var timeout = 0;
2464
- var interval = 0;
2465
- var pokeDelay = 1e3;
2466
- var taskHead;
2467
- var taskTail;
2468
- var clockLast = 0;
2469
- var clockNow = 0;
2470
- var clockSkew = 0;
2471
- var clock = typeof performance === "object" && performance.now ? performance : Date;
2472
- var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) {
2473
- setTimeout(f, 17);
2474
- };
2475
- function now() {
2476
- return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
2477
- }
2478
- function clearNow() {
2479
- clockNow = 0;
2480
- }
2481
- function Timer() {
2482
- this._call = this._time = this._next = null;
2483
- }
2484
- Timer.prototype = timer.prototype = {
2485
- constructor: Timer,
2486
- restart: function(callback, delay, time) {
2487
- if (typeof callback !== "function") throw new TypeError("callback is not a function");
2488
- time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
2489
- if (!this._next && taskTail !== this) {
2490
- if (taskTail) taskTail._next = this;
2491
- else taskHead = this;
2492
- taskTail = this;
2493
- }
2494
- this._call = callback;
2495
- this._time = time;
2496
- sleep();
2497
- },
2498
- stop: function() {
2499
- if (this._call) {
2500
- this._call = null;
2501
- this._time = Infinity;
2502
- sleep();
2503
- }
2504
- }
2505
- };
2506
- function timer(callback, delay, time) {
2507
- var t = new Timer();
2508
- t.restart(callback, delay, time);
2509
- return t;
2510
- }
2511
- function timerFlush() {
2512
- now();
2513
- ++frame;
2514
- var t = taskHead, e;
2515
- while (t) {
2516
- if ((e = clockNow - t._time) >= 0) t._call.call(void 0, e);
2517
- t = t._next;
2518
- }
2519
- --frame;
2520
- }
2521
- function wake() {
2522
- clockNow = (clockLast = clock.now()) + clockSkew;
2523
- frame = timeout = 0;
2524
- try {
2525
- timerFlush();
2526
- } finally {
2527
- frame = 0;
2528
- nap();
2529
- clockNow = 0;
2530
- }
2531
- }
2532
- function poke() {
2533
- var now2 = clock.now(), delay = now2 - clockLast;
2534
- if (delay > pokeDelay) clockSkew -= delay, clockLast = now2;
2535
- }
2536
- function nap() {
2537
- var t0, t1 = taskHead, t2, time = Infinity;
2538
- while (t1) {
2539
- if (t1._call) {
2540
- if (time > t1._time) time = t1._time;
2541
- t0 = t1, t1 = t1._next;
2542
- } else {
2543
- t2 = t1._next, t1._next = null;
2544
- t1 = t0 ? t0._next = t2 : taskHead = t2;
2545
- }
2546
- }
2547
- taskTail = t0;
2548
- sleep(time);
2549
- }
2550
- function sleep(time) {
2551
- if (frame) return;
2552
- if (timeout) timeout = clearTimeout(timeout);
2553
- var delay = time - clockNow;
2554
- if (delay > 24) {
2555
- if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
2556
- if (interval) interval = clearInterval(interval);
2557
- } else {
2558
- if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
2559
- frame = 1, setFrame(wake);
2560
- }
2561
- }
2562
-
2563
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/lcg.js
2564
- var a = 1664525;
2565
- var c = 1013904223;
2566
- var m = 4294967296;
2567
- function lcg_default() {
2568
- let s = 1;
2569
- return () => (s = (a * s + c) % m) / m;
2570
- }
2571
-
2572
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/simulation.js
2573
- function x2(d) {
2574
- return d.x;
2575
- }
2576
- function y2(d) {
2577
- return d.y;
2578
- }
2579
- var initialRadius = 10;
2580
- var initialAngle = Math.PI * (3 - Math.sqrt(5));
2581
- function simulation_default(nodes) {
2582
- var simulation, alpha = 1, alphaMin = 1e-3, alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), alphaTarget = 0, velocityDecay = 0.6, forces = /* @__PURE__ */ new Map(), stepper = timer(step), event = dispatch_default("tick", "end"), random = lcg_default();
2583
- if (nodes == null) nodes = [];
2584
- function step() {
2585
- tick();
2586
- event.call("tick", simulation);
2587
- if (alpha < alphaMin) {
2588
- stepper.stop();
2589
- event.call("end", simulation);
2590
- }
2591
- }
2592
- function tick(iterations) {
2593
- var i, n = nodes.length, node;
2594
- if (iterations === void 0) iterations = 1;
2595
- for (var k = 0; k < iterations; ++k) {
2596
- alpha += (alphaTarget - alpha) * alphaDecay;
2597
- forces.forEach(function(force) {
2598
- force(alpha);
2599
- });
2600
- for (i = 0; i < n; ++i) {
2601
- node = nodes[i];
2602
- if (node.fx == null) node.x += node.vx *= velocityDecay;
2603
- else node.x = node.fx, node.vx = 0;
2604
- if (node.fy == null) node.y += node.vy *= velocityDecay;
2605
- else node.y = node.fy, node.vy = 0;
2606
- }
2607
- }
2608
- return simulation;
2609
- }
2610
- function initializeNodes() {
2611
- for (var i = 0, n = nodes.length, node; i < n; ++i) {
2612
- node = nodes[i], node.index = i;
2613
- if (node.fx != null) node.x = node.fx;
2614
- if (node.fy != null) node.y = node.fy;
2615
- if (isNaN(node.x) || isNaN(node.y)) {
2616
- var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle;
2617
- node.x = radius * Math.cos(angle);
2618
- node.y = radius * Math.sin(angle);
2619
- }
2620
- if (isNaN(node.vx) || isNaN(node.vy)) {
2621
- node.vx = node.vy = 0;
2622
- }
2623
- }
2624
- }
2625
- function initializeForce(force) {
2626
- if (force.initialize) force.initialize(nodes, random);
2627
- return force;
2628
- }
2629
- initializeNodes();
2630
- return simulation = {
2631
- tick,
2632
- restart: function() {
2633
- return stepper.restart(step), simulation;
2634
- },
2635
- stop: function() {
2636
- return stepper.stop(), simulation;
2637
- },
2638
- nodes: function(_) {
2639
- return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes;
2640
- },
2641
- alpha: function(_) {
2642
- return arguments.length ? (alpha = +_, simulation) : alpha;
2643
- },
2644
- alphaMin: function(_) {
2645
- return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
2646
- },
2647
- alphaDecay: function(_) {
2648
- return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
2649
- },
2650
- alphaTarget: function(_) {
2651
- return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
2652
- },
2653
- velocityDecay: function(_) {
2654
- return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
2655
- },
2656
- randomSource: function(_) {
2657
- return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random;
2658
- },
2659
- force: function(name, _) {
2660
- return arguments.length > 1 ? (_ == null ? forces.delete(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
2661
- },
2662
- find: function(x3, y3, radius) {
2663
- var i = 0, n = nodes.length, dx, dy, d2, node, closest;
2664
- if (radius == null) radius = Infinity;
2665
- else radius *= radius;
2666
- for (i = 0; i < n; ++i) {
2667
- node = nodes[i];
2668
- dx = x3 - node.x;
2669
- dy = y3 - node.y;
2670
- d2 = dx * dx + dy * dy;
2671
- if (d2 < radius) closest = node, radius = d2;
2672
- }
2673
- return closest;
2674
- },
2675
- on: function(name, _) {
2676
- return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
2677
- }
2678
- };
2679
- }
2680
-
2681
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/manyBody.js
2682
- function manyBody_default() {
2683
- var nodes, node, random, alpha, strength = constant_default(-30), strengths, distanceMin2 = 1, distanceMax2 = Infinity, theta2 = 0.81;
2684
- function force(_) {
2685
- var i, n = nodes.length, tree = quadtree(nodes, x2, y2).visitAfter(accumulate);
2686
- for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
2687
- }
2688
- function initialize() {
2689
- if (!nodes) return;
2690
- var i, n = nodes.length, node2;
2691
- strengths = new Array(n);
2692
- for (i = 0; i < n; ++i) node2 = nodes[i], strengths[node2.index] = +strength(node2, i, nodes);
2693
- }
2694
- function accumulate(quad) {
2695
- var strength2 = 0, q, c2, weight = 0, x3, y3, i;
2696
- if (quad.length) {
2697
- for (x3 = y3 = i = 0; i < 4; ++i) {
2698
- if ((q = quad[i]) && (c2 = Math.abs(q.value))) {
2699
- strength2 += q.value, weight += c2, x3 += c2 * q.x, y3 += c2 * q.y;
2700
- }
2701
- }
2702
- quad.x = x3 / weight;
2703
- quad.y = y3 / weight;
2704
- } else {
2705
- q = quad;
2706
- q.x = q.data.x;
2707
- q.y = q.data.y;
2708
- do
2709
- strength2 += strengths[q.data.index];
2710
- while (q = q.next);
2711
- }
2712
- quad.value = strength2;
2713
- }
2714
- function apply(quad, x1, _, x22) {
2715
- if (!quad.value) return true;
2716
- var x3 = quad.x - node.x, y3 = quad.y - node.y, w = x22 - x1, l = x3 * x3 + y3 * y3;
2717
- if (w * w / theta2 < l) {
2718
- if (l < distanceMax2) {
2719
- if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
2720
- if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
2721
- if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
2722
- node.vx += x3 * quad.value * alpha / l;
2723
- node.vy += y3 * quad.value * alpha / l;
2724
- }
2725
- return true;
2726
- } else if (quad.length || l >= distanceMax2) return;
2727
- if (quad.data !== node || quad.next) {
2728
- if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3;
2729
- if (y3 === 0) y3 = jiggle_default(random), l += y3 * y3;
2730
- if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
2731
- }
2732
- do
2733
- if (quad.data !== node) {
2734
- w = strengths[quad.data.index] * alpha / l;
2735
- node.vx += x3 * w;
2736
- node.vy += y3 * w;
2737
- }
2738
- while (quad = quad.next);
2739
- }
2740
- force.initialize = function(_nodes, _random) {
2741
- nodes = _nodes;
2742
- random = _random;
2743
- initialize();
2744
- };
2745
- force.strength = function(_) {
2746
- return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
2747
- };
2748
- force.distanceMin = function(_) {
2749
- return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
2750
- };
2751
- force.distanceMax = function(_) {
2752
- return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
2753
- };
2754
- force.theta = function(_) {
2755
- return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
2756
- };
2757
- return force;
2758
- }
2759
-
2760
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/x.js
2761
- function x_default(x3) {
2762
- var strength = constant_default(0.1), nodes, strengths, xz;
2763
- if (typeof x3 !== "function") x3 = constant_default(x3 == null ? 0 : +x3);
2764
- function force(alpha) {
2765
- for (var i = 0, n = nodes.length, node; i < n; ++i) {
2766
- node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
2767
- }
2768
- }
2769
- function initialize() {
2770
- if (!nodes) return;
2771
- var i, n = nodes.length;
2772
- strengths = new Array(n);
2773
- xz = new Array(n);
2774
- for (i = 0; i < n; ++i) {
2775
- strengths[i] = isNaN(xz[i] = +x3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
2776
- }
2777
- }
2778
- force.initialize = function(_) {
2779
- nodes = _;
2780
- initialize();
2781
- };
2782
- force.strength = function(_) {
2783
- return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
2784
- };
2785
- force.x = function(_) {
2786
- return arguments.length ? (x3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : x3;
2787
- };
2788
- return force;
2789
- }
2790
-
2791
- // ../../node_modules/.bun/d3-force@3.0.0/node_modules/d3-force/src/y.js
2792
- function y_default(y3) {
2793
- var strength = constant_default(0.1), nodes, strengths, yz;
2794
- if (typeof y3 !== "function") y3 = constant_default(y3 == null ? 0 : +y3);
2795
- function force(alpha) {
2796
- for (var i = 0, n = nodes.length, node; i < n; ++i) {
2797
- node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
2798
- }
2799
- }
2800
- function initialize() {
2801
- if (!nodes) return;
2802
- var i, n = nodes.length;
2803
- strengths = new Array(n);
2804
- yz = new Array(n);
2805
- for (i = 0; i < n; ++i) {
2806
- strengths[i] = isNaN(yz[i] = +y3(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
2807
- }
2808
- }
2809
- force.initialize = function(_) {
2810
- nodes = _;
2811
- initialize();
2812
- };
2813
- force.strength = function(_) {
2814
- return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength;
2815
- };
2816
- force.y = function(_) {
2817
- return arguments.length ? (y3 = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : y3;
2818
- };
2819
- return force;
2820
- }
2821
-
2822
2197
  // src/graph/simulation.ts
2198
+ import {
2199
+ forceCenter,
2200
+ forceCollide,
2201
+ forceLink,
2202
+ forceManyBody,
2203
+ forceSimulation,
2204
+ forceX,
2205
+ forceY
2206
+ } from "d3-force";
2823
2207
  var SYNC_TICKS_PER_BATCH = 15;
2824
2208
  var SYNC_MAX_TICKS_CEIL = 800;
2825
2209
  var DEFAULT_ALPHA_MIN = 1e-3;
@@ -2836,14 +2220,14 @@ function forceCluster(nodes, strength) {
2836
2220
  const count = /* @__PURE__ */ new Map();
2837
2221
  for (const node of nodes) {
2838
2222
  if (!node.community) continue;
2839
- const c2 = node.community;
2840
- cx.set(c2, (cx.get(c2) ?? 0) + (node.x ?? 0));
2841
- cy.set(c2, (cy.get(c2) ?? 0) + (node.y ?? 0));
2842
- count.set(c2, (count.get(c2) ?? 0) + 1);
2223
+ const c = node.community;
2224
+ cx.set(c, (cx.get(c) ?? 0) + (node.x ?? 0));
2225
+ cy.set(c, (cy.get(c) ?? 0) + (node.y ?? 0));
2226
+ count.set(c, (count.get(c) ?? 0) + 1);
2843
2227
  }
2844
- for (const [c2, n] of count) {
2845
- cx.set(c2, cx.get(c2) / n);
2846
- cy.set(c2, cy.get(c2) / n);
2228
+ for (const [c, n] of count) {
2229
+ cx.set(c, cx.get(c) / n);
2230
+ cy.set(c, cy.get(c) / n);
2847
2231
  }
2848
2232
  const k = strength * alpha;
2849
2233
  for (const node of nodes) {
@@ -2945,17 +2329,17 @@ var SimulationManager = class _SimulationManager {
2945
2329
  * pinned node's neighbors follow springily. Omitting it posts a byte-identical
2946
2330
  * legacy message and leaves alpha untouched.
2947
2331
  */
2948
- pinNode(id, x3, y3, alphaTarget) {
2332
+ pinNode(id, x, y, alphaTarget) {
2949
2333
  if (this.destroyed) return;
2950
2334
  if (this.worker) {
2951
2335
  this.worker.postMessage(
2952
- alphaTarget != null ? { type: "pin", nodeId: id, x: x3, y: y3, alphaTarget } : { type: "pin", nodeId: id, x: x3, y: y3 }
2336
+ alphaTarget != null ? { type: "pin", nodeId: id, x, y, alphaTarget } : { type: "pin", nodeId: id, x, y }
2953
2337
  );
2954
2338
  } else {
2955
2339
  const node = this.syncNodeMap.get(id);
2956
2340
  if (node) {
2957
- node.fx = x3;
2958
- node.fy = y3;
2341
+ node.fx = x;
2342
+ node.fy = y;
2959
2343
  }
2960
2344
  if (alphaTarget != null && this.syncSim) {
2961
2345
  this.dragAlphaTarget = alphaTarget;
@@ -2998,14 +2382,14 @@ var SimulationManager = class _SimulationManager {
2998
2382
  * Feed the cursor-repulsion force a pointer position. `active: false` clears
2999
2383
  * the force. No-op when the graph has no cursor force configured (radius 0).
3000
2384
  */
3001
- setPointer(x3, y3, active) {
2385
+ setPointer(x, y, active) {
3002
2386
  if (this.destroyed) return;
3003
2387
  if (this.worker) {
3004
- this.worker.postMessage({ type: "pointer", x: x3, y: y3, active });
2388
+ this.worker.postMessage({ type: "pointer", x, y, active });
3005
2389
  } else {
3006
2390
  if (this.pointer.radius <= 0) return;
3007
- this.pointer.x = x3;
3008
- this.pointer.y = y3;
2391
+ this.pointer.x = x;
2392
+ this.pointer.y = y;
3009
2393
  this.pointer.active = active;
3010
2394
  this.cursorAlphaTarget = active ? 0.03 : 0;
3011
2395
  if (this.syncSim) {
@@ -3023,15 +2407,15 @@ var SimulationManager = class _SimulationManager {
3023
2407
  this.syncSim.alphaTarget(Math.max(this.dragAlphaTarget, this.cursorAlphaTarget));
3024
2408
  }
3025
2409
  /** Drag a node (pins it and reheats slightly). */
3026
- dragNode(id, x3, y3) {
2410
+ dragNode(id, x, y) {
3027
2411
  if (this.destroyed) return;
3028
2412
  if (this.worker) {
3029
- this.worker.postMessage({ type: "drag", nodeId: id, x: x3, y: y3 });
2413
+ this.worker.postMessage({ type: "drag", nodeId: id, x, y });
3030
2414
  } else {
3031
2415
  const node = this.syncNodeMap.get(id);
3032
2416
  if (node) {
3033
- node.fx = x3;
3034
- node.fy = y3;
2417
+ node.fx = x;
2418
+ node.fy = y;
3035
2419
  }
3036
2420
  if (this.syncSim && this.syncSim.alpha() < 0.1) {
3037
2421
  this.syncSim.alpha(0.1).restart();
@@ -3127,17 +2511,17 @@ var SimulationManager = class _SimulationManager {
3127
2511
  community: n.community
3128
2512
  }));
3129
2513
  this.syncNodeMap = new Map(this.syncNodes.map((n) => [n.id, n]));
3130
- const linkForce = link_default(edges.map((e) => ({ ...e }))).id((d) => d.id).distance(config.linkDistance);
2514
+ const linkForce = forceLink(edges.map((e) => ({ ...e }))).id((d) => d.id).distance(config.linkDistance);
3131
2515
  if (config.linkStrength != null) {
3132
2516
  linkForce.strength(config.linkStrength);
3133
2517
  }
3134
2518
  const padding = config.collisionPadding ?? 2;
3135
- this.syncSim = simulation_default(this.syncNodes).force("link", linkForce).force("charge", manyBody_default().strength(config.chargeStrength)).force(
2519
+ this.syncSim = forceSimulation(this.syncNodes).force("link", linkForce).force("charge", forceManyBody().strength(config.chargeStrength)).force(
3136
2520
  "collide",
3137
- collide_default().radius((d) => d.radius + padding)
3138
- ).force("gravityX", x_default(0).strength(0.05)).force("gravityY", y_default(0).strength(0.05)).alphaDecay(config.alphaDecay).velocityDecay(config.velocityDecay).stop();
2521
+ forceCollide().radius((d) => d.radius + padding)
2522
+ ).force("gravityX", forceX(0).strength(0.05)).force("gravityY", forceY(0).strength(0.05)).alphaDecay(config.alphaDecay).velocityDecay(config.velocityDecay).stop();
3139
2523
  if (config.centerForce !== false) {
3140
- this.syncSim.force("center", center_default(0, 0));
2524
+ this.syncSim.force("center", forceCenter(0, 0));
3141
2525
  }
3142
2526
  if (config.clustering) {
3143
2527
  const clusterFn = forceCluster(this.syncNodes, config.clustering.strength);
@@ -3238,24 +2622,24 @@ var SpatialIndex2 = class extends SpatialIndex {
3238
2622
  };
3239
2623
 
3240
2624
  // src/graph/update-diff-config.ts
3241
- function stableKey(c2) {
2625
+ function stableKey(c) {
3242
2626
  return JSON.stringify([
3243
- c2.chargeStrength,
3244
- c2.linkDistance,
3245
- c2.clustering ? [c2.clustering.field, c2.clustering.strength] : null,
3246
- c2.alphaDecay,
3247
- c2.velocityDecay,
3248
- c2.collisionRadius,
3249
- c2.collisionPadding ?? null,
3250
- c2.linkStrength ?? null,
3251
- c2.centerForce ?? null,
3252
- c2.seed ?? null,
3253
- c2.warmupTicks ?? null,
3254
- c2.warmupBudgetMs ?? null
2627
+ c.chargeStrength,
2628
+ c.linkDistance,
2629
+ c.clustering ? [c.clustering.field, c.clustering.strength] : null,
2630
+ c.alphaDecay,
2631
+ c.velocityDecay,
2632
+ c.collisionRadius,
2633
+ c.collisionPadding ?? null,
2634
+ c.linkStrength ?? null,
2635
+ c.centerForce ?? null,
2636
+ c.seed ?? null,
2637
+ c.warmupTicks ?? null,
2638
+ c.warmupBudgetMs ?? null
3255
2639
  ]);
3256
2640
  }
3257
- function simulationConfigEqual(a2, b) {
3258
- return stableKey(a2) === stableKey(b);
2641
+ function simulationConfigEqual(a, b) {
2642
+ return stableKey(a) === stableKey(b);
3259
2643
  }
3260
2644
 
3261
2645
  // src/graph/update-diff.ts
@@ -3296,9 +2680,9 @@ function diffGraphUpdate(prevNodes, prevEdges, next, prevConfig, seed) {
3296
2680
  const remainingPrev = new Map(prevEdgeCounts);
3297
2681
  for (const e of next.edges) {
3298
2682
  const k = `${e.source} ${e.target}`;
3299
- const c2 = remainingPrev.get(k);
3300
- if (c2 && c2 > 0) {
3301
- remainingPrev.set(k, c2 - 1);
2683
+ const c = remainingPrev.get(k);
2684
+ if (c && c > 0) {
2685
+ remainingPrev.set(k, c - 1);
3302
2686
  } else {
3303
2687
  enteringEdgeCount++;
3304
2688
  }
@@ -3338,10 +2722,10 @@ function diffGraphUpdate(prevNodes, prevEdges, next, prevConfig, seed) {
3338
2722
  }
3339
2723
  function buildAdjacency(edges) {
3340
2724
  const map = /* @__PURE__ */ new Map();
3341
- const push = (a2, b) => {
3342
- const list = map.get(a2);
2725
+ const push = (a, b) => {
2726
+ const list = map.get(a);
3343
2727
  if (list) list.push(b);
3344
- else map.set(a2, [b]);
2728
+ else map.set(a, [b]);
3345
2729
  };
3346
2730
  for (const e of edges) {
3347
2731
  push(e.source, e.target);
@@ -3369,9 +2753,9 @@ function edgeSetsEqual(prev, next) {
3369
2753
  }
3370
2754
  for (const e of next) {
3371
2755
  const k = key(e);
3372
- const c2 = counts.get(k);
3373
- if (!c2) return false;
3374
- counts.set(k, c2 - 1);
2756
+ const c = counts.get(k);
2757
+ if (!c) return false;
2758
+ counts.set(k, c - 1);
3375
2759
  }
3376
2760
  return true;
3377
2761
  }
@@ -3695,9 +3079,9 @@ function createGraph(container, spec, options) {
3695
3079
  for (const p of positions) {
3696
3080
  posMap.set(p.id, { x: p.x, y: p.y });
3697
3081
  }
3698
- positionedNodes = compilation.nodes.map((node, index2) => {
3082
+ positionedNodes = compilation.nodes.map((node, index) => {
3699
3083
  const pos = posMap.get(node.id) ?? { x: 0, y: 0 };
3700
- return { ...node, x: pos.x, y: pos.y, index: index2 };
3084
+ return { ...node, x: pos.x, y: pos.y, index };
3701
3085
  });
3702
3086
  positionedEdges = compilation.edges.map((edge) => {
3703
3087
  const src = posMap.get(edge.source) ?? { x: 0, y: 0 };
@@ -3800,16 +3184,16 @@ function createGraph(container, spec, options) {
3800
3184
  if (nodeId === null) return null;
3801
3185
  if (compilation.interaction.hoverMode === "category") {
3802
3186
  const cat = nodeCategory.get(nodeId);
3803
- const set3 = /* @__PURE__ */ new Set([nodeId]);
3187
+ const set2 = /* @__PURE__ */ new Set([nodeId]);
3804
3188
  if (cat !== void 0) {
3805
- for (const [id, c2] of nodeCategory) if (c2 === cat) set3.add(id);
3189
+ for (const [id, c] of nodeCategory) if (c === cat) set2.add(id);
3806
3190
  }
3807
- return set3;
3191
+ return set2;
3808
3192
  }
3809
- const set2 = /* @__PURE__ */ new Set([nodeId]);
3193
+ const set = /* @__PURE__ */ new Set([nodeId]);
3810
3194
  const neighbors = adjacencyMap.get(nodeId);
3811
- if (neighbors) for (const nid of neighbors) set2.add(nid);
3812
- return set2;
3195
+ if (neighbors) for (const nid of neighbors) set.add(nid);
3196
+ return set;
3813
3197
  }
3814
3198
  function standingSnapshot() {
3815
3199
  return composeStandingFocus(
@@ -3822,16 +3206,16 @@ function createGraph(container, spec, options) {
3822
3206
  function targetSnapshot() {
3823
3207
  return layerHoverFocus(standingSnapshot(), hoveredNodeId, hoverConnectedSet(hoveredNodeId));
3824
3208
  }
3825
- function armFocus(now2) {
3209
+ function armFocus(now) {
3826
3210
  const target = targetSnapshot();
3827
3211
  const hoverCfg = compilation.animation?.hover ?? null;
3828
3212
  const duration = hoverCfg && !prefersReducedMotion() ? hoverCfg.duration : 0;
3829
3213
  const ease = resolveEase(hoverCfg?.ease ?? "smooth");
3830
3214
  if (!focusTransition) {
3831
- focusTransition = new FocusTransition(target, duration, ease, now2);
3215
+ focusTransition = new FocusTransition(target, duration, ease, now);
3832
3216
  return;
3833
3217
  }
3834
- focusTransition.retarget(target, now2);
3218
+ focusTransition.retarget(target, now);
3835
3219
  if (focusAnim) scheduler.remove(focusAnim);
3836
3220
  focusAnim = {
3837
3221
  tick: (t) => {
@@ -3856,28 +3240,28 @@ function createGraph(container, spec, options) {
3856
3240
  function resolveHighlightTarget(target) {
3857
3241
  if ("nodeIds" in target) return new Set(target.nodeIds);
3858
3242
  if ("neighborsOf" in target) {
3859
- const set3 = /* @__PURE__ */ new Set();
3860
- if (target.includeSelf !== false) set3.add(target.neighborsOf);
3243
+ const set2 = /* @__PURE__ */ new Set();
3244
+ if (target.includeSelf !== false) set2.add(target.neighborsOf);
3861
3245
  const neighbors = adjacencyMap.get(target.neighborsOf);
3862
- if (neighbors) for (const nid of neighbors) set3.add(nid);
3863
- return set3;
3246
+ if (neighbors) for (const nid of neighbors) set2.add(nid);
3247
+ return set2;
3864
3248
  }
3865
3249
  const values = new Set(
3866
3250
  Array.isArray(target.category.value) ? target.category.value : [target.category.value]
3867
3251
  );
3868
3252
  const field = target.category.field;
3869
- const set2 = /* @__PURE__ */ new Set();
3253
+ const set = /* @__PURE__ */ new Set();
3870
3254
  for (const n of compilation.nodes) {
3871
3255
  const v = n.data?.[field];
3872
- if (v != null && values.has(String(v))) set2.add(n.id);
3256
+ if (v != null && values.has(String(v))) set.add(n.id);
3873
3257
  }
3874
- return set2;
3258
+ return set;
3875
3259
  }
3876
3260
  function categoryHighlightSet() {
3877
3261
  if (activeCategories.size === 0) return null;
3878
- const set2 = /* @__PURE__ */ new Set();
3879
- for (const [id, cat] of nodeCategory) if (activeCategories.has(cat)) set2.add(id);
3880
- return set2;
3262
+ const set = /* @__PURE__ */ new Set();
3263
+ for (const [id, cat] of nodeCategory) if (activeCategories.has(cat)) set.add(id);
3264
+ return set;
3881
3265
  }
3882
3266
  function recomputeHighlight() {
3883
3267
  const filter = categoryHighlightSet();
@@ -3966,23 +3350,23 @@ function createGraph(container, spec, options) {
3966
3350
  const t = options?.tooltip;
3967
3351
  return t && typeof t === "object" ? t.formatter ?? null : null;
3968
3352
  }
3969
- function applyFormatterResult(result, x3, y3) {
3353
+ function applyFormatterResult(result, x, y) {
3970
3354
  if (!tooltipManager) return;
3971
3355
  if (result === null) {
3972
3356
  tooltipManager.hide();
3973
3357
  } else if (typeof result === "string") {
3974
- tooltipManager.show({ text: result }, x3, y3);
3358
+ tooltipManager.show({ text: result }, x, y);
3975
3359
  } else if (result instanceof HTMLElement) {
3976
- tooltipManager.show({ element: result }, x3, y3);
3360
+ tooltipManager.show({ element: result }, x, y);
3977
3361
  } else {
3978
- tooltipManager.show(result, x3, y3);
3362
+ tooltipManager.show(result, x, y);
3979
3363
  }
3980
3364
  }
3981
- function buildRenderState(now2) {
3365
+ function buildRenderState(now) {
3982
3366
  const transform = interactionManager.getTransform();
3983
- if (!focusTransition) armFocus(now2);
3367
+ if (!focusTransition) armFocus(now);
3984
3368
  const ft = focusTransition;
3985
- const t = ft.progress(now2);
3369
+ const t = ft.progress(now);
3986
3370
  const focus = t < 1 ? { t, prev: ft.prev, next: ft.next } : void 0;
3987
3371
  const settledNext = ft.next;
3988
3372
  const hoverRadiusScale = hoverRadiusTween ? /* @__PURE__ */ new Map([[hoverRadiusTween.nodeId, hoverRadiusTween.scale]]) : void 0;
@@ -4012,13 +3396,13 @@ function createGraph(container, spec, options) {
4012
3396
  exiting: exitingGhosts ?? void 0
4013
3397
  };
4014
3398
  }
4015
- function renderFrame(now2) {
3399
+ function renderFrame(now) {
4016
3400
  animFrameId = null;
4017
3401
  if (destroyed || !renderer || !interactionManager) return;
4018
- if (scheduler.tick(now2)) needsRender = true;
3402
+ if (scheduler.tick(now)) needsRender = true;
4019
3403
  if (needsRender) {
4020
3404
  needsRender = false;
4021
- renderer.render(buildRenderState(now2));
3405
+ renderer.render(buildRenderState(now));
4022
3406
  }
4023
3407
  if (scheduler.active) scheduleRender();
4024
3408
  if (cameraChangePending) {
@@ -4126,8 +3510,8 @@ function createGraph(container, spec, options) {
4126
3510
  },
4127
3511
  onBackgroundHover(graphX, graphY, screenX, screenY) {
4128
3512
  if (hoveredNodeId) return;
4129
- const now2 = performance.now();
4130
- if (now2 - lastEdgeHitTime < 32) {
3513
+ const now = performance.now();
3514
+ if (now - lastEdgeHitTime < 32) {
4131
3515
  if (hoveredEdgeId) {
4132
3516
  hoveredEdgeId = null;
4133
3517
  needsRender = true;
@@ -4137,7 +3521,7 @@ function createGraph(container, spec, options) {
4137
3521
  }
4138
3522
  return;
4139
3523
  }
4140
- lastEdgeHitTime = now2;
3524
+ lastEdgeHitTime = now;
4141
3525
  const transform = interactionManager?.getTransform();
4142
3526
  const threshold = 5 / (transform?.k ?? 1);
4143
3527
  const edgeId = hitTestEdge(graphX, graphY, threshold);
@@ -4168,13 +3552,13 @@ function createGraph(container, spec, options) {
4168
3552
  },
4169
3553
  onNodeDragStart(nodeId) {
4170
3554
  const node = positionedNodes.find((n) => n.id === nodeId);
4171
- const x3 = node?.x ?? 0;
4172
- const y3 = node?.y ?? 0;
4173
- simulation?.pinNode(nodeId, x3, y3, springyDragEnabled() ? 0.3 : void 0);
3555
+ const x = node?.x ?? 0;
3556
+ const y = node?.y ?? 0;
3557
+ simulation?.pinNode(nodeId, x, y, springyDragEnabled() ? 0.3 : void 0);
4174
3558
  canvas?.classList.add("oc-graph-canvas--dragging");
4175
3559
  },
4176
- onNodeDrag(nodeId, x3, y3) {
4177
- simulation?.dragNode(nodeId, x3, y3);
3560
+ onNodeDrag(nodeId, x, y) {
3561
+ simulation?.dragNode(nodeId, x, y);
4178
3562
  },
4179
3563
  onNodeDragEnd(nodeId) {
4180
3564
  simulation?.unpinNode(nodeId, springyDragEnabled() ? 0 : void 0);
@@ -4182,9 +3566,9 @@ function createGraph(container, spec, options) {
4182
3566
  },
4183
3567
  onPointerMove(graphX, graphY) {
4184
3568
  if (!cursorForceEnabled()) return;
4185
- const now2 = performance.now();
4186
- if (now2 - lastPointerFeedTime < CURSOR_POINTER_THROTTLE_MS) return;
4187
- lastPointerFeedTime = now2;
3569
+ const now = performance.now();
3570
+ if (now - lastPointerFeedTime < CURSOR_POINTER_THROTTLE_MS) return;
3571
+ lastPointerFeedTime = now;
4188
3572
  simulation?.setPointer(graphX, graphY, true);
4189
3573
  },
4190
3574
  onPointerLeave() {
@@ -4271,8 +3655,8 @@ function createGraph(container, spec, options) {
4271
3655
  const k = clampK(target.k ?? interactionManager.getTransform().k);
4272
3656
  flyCamera(new ZoomTransform(cw / 2 - target.x * k, ch / 2 - target.y * k, k), opts);
4273
3657
  }
4274
- function centerAt(x3, y3, opts) {
4275
- flyTo({ x: x3, y: y3 }, opts);
3658
+ function centerAt(x, y, opts) {
3659
+ flyTo({ x, y }, opts);
4276
3660
  }
4277
3661
  function getCamera() {
4278
3662
  const t = interactionManager?.getTransform() ?? ZoomTransform.identity();
@@ -4401,9 +3785,9 @@ function createGraph(container, spec, options) {
4401
3785
  for (const node of positionedNodes) {
4402
3786
  posMap.set(node.id, { x: node.x, y: node.y });
4403
3787
  }
4404
- positionedNodes = compilation.nodes.map((node, index2) => {
3788
+ positionedNodes = compilation.nodes.map((node, index) => {
4405
3789
  const pos = posMap.get(node.id) ?? { x: 0, y: 0 };
4406
- return { ...node, x: pos.x, y: pos.y, index: index2 };
3790
+ return { ...node, x: pos.x, y: pos.y, index };
4407
3791
  });
4408
3792
  positionedEdges = compilation.edges.map((edge) => {
4409
3793
  const src = posMap.get(edge.source) ?? { x: 0, y: 0 };
@@ -4441,9 +3825,9 @@ function createGraph(container, spec, options) {
4441
3825
  );
4442
3826
  const changeRatio = Math.max(nodeRatio, edgeRatio);
4443
3827
  const initialAlpha = Math.min(1, 0.3 + 0.7 * changeRatio);
4444
- positionedNodes = compilation.nodes.map((node, index2) => {
3828
+ positionedNodes = compilation.nodes.map((node, index) => {
4445
3829
  const pos = positions.get(node.id) ?? { x: 0, y: 0 };
4446
- return { ...node, x: pos.x, y: pos.y, index: index2 };
3830
+ return { ...node, x: pos.x, y: pos.y, index };
4447
3831
  });
4448
3832
  positionedEdges = compilation.edges.map((edge) => {
4449
3833
  const src = positions.get(edge.source) ?? { x: 0, y: 0 };
@@ -4650,7 +4034,7 @@ function applyCellStyle(td, cell) {
4650
4034
  }
4651
4035
  }
4652
4036
  function countryToEmoji(code) {
4653
- return [...code.toUpperCase()].map((c2) => String.fromCodePoint(c2.charCodeAt(0) + 127397)).join("");
4037
+ return [...code.toUpperCase()].map((c) => String.fromCodePoint(c.charCodeAt(0) + 127397)).join("");
4654
4038
  }
4655
4039
  var COUNTRY_NAMES = {
4656
4040
  US: "United States",
@@ -4851,11 +4235,11 @@ function renderSparklineCell(cell) {
4851
4235
  const barW = Math.max(1, (innerW - gap * (barCount - 1)) / barCount);
4852
4236
  for (let i = 0; i < barCount; i++) {
4853
4237
  const barH = Math.max(1, sparklineData.bars[i] * innerH);
4854
- const x3 = padding + i * (barW + gap);
4855
- const y3 = padding + innerH - barH;
4238
+ const x = padding + i * (barW + gap);
4239
+ const y = padding + innerH - barH;
4856
4240
  const rect = document.createElementNS(svgNS, "rect");
4857
- rect.setAttribute("x", String(x3));
4858
- rect.setAttribute("y", String(y3));
4241
+ rect.setAttribute("x", String(x));
4242
+ rect.setAttribute("y", String(y));
4859
4243
  rect.setAttribute("width", String(barW));
4860
4244
  rect.setAttribute("height", String(barH));
4861
4245
  rect.setAttribute("rx", "1.5");
@@ -4881,11 +4265,11 @@ function renderSparklineCell(cell) {
4881
4265
  const barH = Math.max(1, (innerH - gap * (barCount - 1)) / barCount);
4882
4266
  for (let i = 0; i < barCount; i++) {
4883
4267
  const barW = Math.max(1, sparklineData.bars[i] * innerW);
4884
- const x3 = padding;
4885
- const y3 = padding + i * (barH + gap);
4268
+ const x = padding;
4269
+ const y = padding + i * (barH + gap);
4886
4270
  const rect = document.createElementNS(svgNS, "rect");
4887
- rect.setAttribute("x", String(x3));
4888
- rect.setAttribute("y", String(y3));
4271
+ rect.setAttribute("x", String(x));
4272
+ rect.setAttribute("y", String(y));
4889
4273
  rect.setAttribute("width", String(barW));
4890
4274
  rect.setAttribute("height", String(barH));
4891
4275
  rect.setAttribute("rx", "1.5");
@@ -5073,12 +4457,12 @@ function renderBrand(parent, layout) {
5073
4457
  const { chrome } = layout;
5074
4458
  const firstBottom = chrome.source ?? chrome.byline ?? chrome.footer;
5075
4459
  const chromeY = firstBottom ? bottomOffset + firstBottom.y : bottomOffset + layout.theme.spacing.chartToFooter;
5076
- const a2 = createSVGElement2("a");
5077
- a2.setAttribute("href", BRAND_URL2);
5078
- a2.setAttributeNS(XLINK_NS2, "xlink:href", BRAND_URL2);
5079
- a2.setAttribute("target", "_blank");
5080
- a2.setAttribute("rel", "noopener");
5081
- a2.setAttribute("class", "oc-chrome-ref");
4460
+ const a = createSVGElement2("a");
4461
+ a.setAttribute("href", BRAND_URL2);
4462
+ a.setAttributeNS(XLINK_NS2, "xlink:href", BRAND_URL2);
4463
+ a.setAttribute("target", "_blank");
4464
+ a.setAttribute("rel", "noopener");
4465
+ a.setAttribute("class", "oc-chrome-ref");
5082
4466
  const BRAND_LARGE = 16;
5083
4467
  const text = createSVGElement2("text");
5084
4468
  setAttrs2(text, {
@@ -5103,8 +4487,8 @@ function renderBrand(parent, layout) {
5103
4487
  text.appendChild(trySpan);
5104
4488
  text.appendChild(openDataSpan);
5105
4489
  text.appendChild(aiSpan);
5106
- a2.appendChild(text);
5107
- parent.appendChild(a2);
4490
+ a.appendChild(text);
4491
+ parent.appendChild(a);
5108
4492
  }
5109
4493
  function renderLegend(parent, legendLayout) {
5110
4494
  if (!("entries" in legendLayout) || legendLayout.entries.length === 0) return;
@@ -5204,9 +4588,9 @@ function renderGradientDefs(defs, links, nodePositions) {
5204
4588
  const sourcePos = nodePositions.get(link.sourceId);
5205
4589
  const targetPos = nodePositions.get(link.targetId);
5206
4590
  const x1 = sourcePos ? sourcePos.x + sourcePos.width : 0;
5207
- const x22 = targetPos ? targetPos.x : 0;
4591
+ const x2 = targetPos ? targetPos.x : 0;
5208
4592
  gradient.setAttribute("x1", String(x1));
5209
- gradient.setAttribute("x2", String(x22));
4593
+ gradient.setAttribute("x2", String(x2));
5210
4594
  const stop0 = createSVGElement2("stop");
5211
4595
  setAttrs2(stop0, { offset: "0%", "stop-color": link.sourceColor });
5212
4596
  gradient.appendChild(stop0);
@@ -5408,20 +4792,24 @@ function createSankey(container, spec, options) {
5408
4792
  }
5409
4793
  function wireTooltipAndInteraction(svg, layout) {
5410
4794
  const cleanups = [];
4795
+ const nodesById = /* @__PURE__ */ new Map();
4796
+ for (const n of layout.nodes) {
4797
+ if (!nodesById.has(n.nodeId)) nodesById.set(n.nodeId, n);
4798
+ }
5411
4799
  const nodeElements = svg.querySelectorAll(".oc-sankey-node");
5412
4800
  for (const el of nodeElements) {
5413
4801
  const markId = el.getAttribute("data-mark-id");
5414
4802
  if (!markId) continue;
5415
4803
  const content = layout.tooltipDescriptors.get(markId);
5416
4804
  const nodeId = el.getAttribute("data-node-id");
5417
- const nodeData = nodeId ? layout.nodes.find((n) => n.nodeId === nodeId)?.data ?? {} : {};
4805
+ const nodeData = nodeId ? nodesById.get(nodeId)?.data ?? {} : {};
5418
4806
  const handleMouseEnter = (e) => {
5419
4807
  const mouseEvent = e;
5420
4808
  if (content && tooltipManager) {
5421
4809
  const svgRect = svg.getBoundingClientRect();
5422
- const x3 = mouseEvent.clientX - svgRect.left;
5423
- const y3 = mouseEvent.clientY - svgRect.top;
5424
- tooltipManager.show(content, x3, y3);
4810
+ const x = mouseEvent.clientX - svgRect.left;
4811
+ const y = mouseEvent.clientY - svgRect.top;
4812
+ tooltipManager.show(content, x, y);
5425
4813
  }
5426
4814
  options?.onNodeHover?.(nodeData);
5427
4815
  if (nodeId) highlightConnectedLinks(svg, nodeId, layout);
@@ -5430,9 +4818,9 @@ function createSankey(container, spec, options) {
5430
4818
  if (content && tooltipManager) {
5431
4819
  const mouseEvent = e;
5432
4820
  const svgRect = svg.getBoundingClientRect();
5433
- const x3 = mouseEvent.clientX - svgRect.left;
5434
- const y3 = mouseEvent.clientY - svgRect.top;
5435
- tooltipManager.show(content, x3, y3);
4821
+ const x = mouseEvent.clientX - svgRect.left;
4822
+ const y = mouseEvent.clientY - svgRect.top;
4823
+ tooltipManager.show(content, x, y);
5436
4824
  }
5437
4825
  };
5438
4826
  const handleMouseLeave = () => {
@@ -5466,9 +4854,9 @@ function createSankey(container, spec, options) {
5466
4854
  const mouseEvent = e;
5467
4855
  if (content && tooltipManager) {
5468
4856
  const svgRect = svg.getBoundingClientRect();
5469
- const x3 = mouseEvent.clientX - svgRect.left;
5470
- const y3 = mouseEvent.clientY - svgRect.top;
5471
- tooltipManager.show(content, x3, y3);
4857
+ const x = mouseEvent.clientX - svgRect.left;
4858
+ const y = mouseEvent.clientY - svgRect.top;
4859
+ tooltipManager.show(content, x, y);
5472
4860
  }
5473
4861
  options?.onLinkHover?.(linkData);
5474
4862
  };
@@ -5476,9 +4864,9 @@ function createSankey(container, spec, options) {
5476
4864
  if (content && tooltipManager) {
5477
4865
  const mouseEvent = e;
5478
4866
  const svgRect = svg.getBoundingClientRect();
5479
- const x3 = mouseEvent.clientX - svgRect.left;
5480
- const y3 = mouseEvent.clientY - svgRect.top;
5481
- tooltipManager.show(content, x3, y3);
4867
+ const x = mouseEvent.clientX - svgRect.left;
4868
+ const y = mouseEvent.clientY - svgRect.top;
4869
+ tooltipManager.show(content, x, y);
5482
4870
  }
5483
4871
  };
5484
4872
  const handleMouseLeave = () => {
@@ -5915,21 +5303,6 @@ import { compileTable } from "@opendata-ai/openchart-engine";
5915
5303
  // src/table-renderer.ts
5916
5304
  import { BRAND_FONT_SIZE as BRAND_FONT_SIZE3 } from "@opendata-ai/openchart-core";
5917
5305
  import { clampStaggerDelay as clampStaggerDelay2 } from "@opendata-ai/openchart-engine";
5918
-
5919
- // src/dom-helpers.ts
5920
- function applySrOnlyStyles(el) {
5921
- el.style.position = "absolute";
5922
- el.style.width = "1px";
5923
- el.style.height = "1px";
5924
- el.style.padding = "0";
5925
- el.style.margin = "-1px";
5926
- el.style.overflow = "hidden";
5927
- el.style.clipPath = "inset(50%)";
5928
- el.style.whiteSpace = "nowrap";
5929
- el.style.borderWidth = "0";
5930
- }
5931
-
5932
- // src/table-renderer.ts
5933
5306
  var BRAND_URL3 = "https://tryopendata.ai";
5934
5307
  function renderChromeBlock(layout, position) {
5935
5308
  const chrome = layout.chrome;
@@ -6007,12 +5380,12 @@ function renderTbody(rows, columns) {
6007
5380
  tr.setAttribute("role", "row");
6008
5381
  tr.setAttribute("data-row-id", row.id);
6009
5382
  tr.style.setProperty("--oc-row-index", String(r));
6010
- for (let c2 = 0; c2 < columns.length; c2++) {
6011
- const cell = row.cells[c2];
5383
+ for (let c = 0; c < columns.length; c++) {
5384
+ const cell = row.cells[c];
6012
5385
  if (!cell) continue;
6013
5386
  const td = renderCell(cell);
6014
5387
  td.setAttribute("role", "gridcell");
6015
- td.style.textAlign = columns[c2].align;
5388
+ td.style.textAlign = columns[c].align;
6016
5389
  tr.appendChild(td);
6017
5390
  }
6018
5391
  tbody.appendChild(tr);
@@ -6476,7 +5849,7 @@ function createTable(container, spec, options) {
6476
5849
  search: state.search || void 0
6477
5850
  // No page/pageSize: get all rows
6478
5851
  });
6479
- const headers = fullLayout.columns.map((c2) => c2.label);
5852
+ const headers = fullLayout.columns.map((c) => c.label);
6480
5853
  const csvRows = [headers.map(csvEscape).join(",")];
6481
5854
  for (const row of fullLayout.rows) {
6482
5855
  const values = row.cells.map((cell) => csvEscape(cell.formattedValue));
@@ -6609,19 +5982,23 @@ function createTileMap(container, spec, options) {
6609
5982
  }
6610
5983
  function wireTooltipAndInteraction(svg, layout) {
6611
5984
  const cleanups = [];
5985
+ const tilesByStateCode = /* @__PURE__ */ new Map();
5986
+ for (const t of layout.tiles) {
5987
+ if (!tilesByStateCode.has(t.stateCode)) tilesByStateCode.set(t.stateCode, t);
5988
+ }
6612
5989
  const tileElements = svg.querySelectorAll(".oc-tilemap-tile");
6613
5990
  for (const el of tileElements) {
6614
5991
  const stateCode = el.getAttribute("data-state");
6615
5992
  if (!stateCode) continue;
6616
5993
  const content = layout.tooltipDescriptors.get(stateCode);
6617
- const tile = layout.tiles.find((t) => t.stateCode === stateCode);
5994
+ const tile = tilesByStateCode.get(stateCode);
6618
5995
  const handleMouseEnter = (e) => {
6619
5996
  const mouseEvent = e;
6620
5997
  if (content && tooltipManager && options?.tooltip !== false) {
6621
5998
  const svgRect = svg.getBoundingClientRect();
6622
- const x3 = mouseEvent.clientX - svgRect.left;
6623
- const y3 = mouseEvent.clientY - svgRect.top;
6624
- tooltipManager.show(content, x3, y3);
5999
+ const x = mouseEvent.clientX - svgRect.left;
6000
+ const y = mouseEvent.clientY - svgRect.top;
6001
+ tooltipManager.show(content, x, y);
6625
6002
  }
6626
6003
  if (tile) {
6627
6004
  options?.onTileHover?.({
@@ -6636,9 +6013,9 @@ function createTileMap(container, spec, options) {
6636
6013
  if (content && tooltipManager && options?.tooltip !== false) {
6637
6014
  const mouseEvent = e;
6638
6015
  const svgRect = svg.getBoundingClientRect();
6639
- const x3 = mouseEvent.clientX - svgRect.left;
6640
- const y3 = mouseEvent.clientY - svgRect.top;
6641
- tooltipManager.show(content, x3, y3);
6016
+ const x = mouseEvent.clientX - svgRect.left;
6017
+ const y = mouseEvent.clientY - svgRect.top;
6018
+ tooltipManager.show(content, x, y);
6642
6019
  }
6643
6020
  };
6644
6021
  const handleMouseLeave = () => {