@almadar/ui 5.146.3 → 5.148.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.
@@ -15328,7 +15328,10 @@ var init_LearningCanvas = __esm({
15328
15328
  ctx.fillRect(0, 0, width, height);
15329
15329
  }
15330
15330
  for (const shape of shapes) {
15331
- drawShape(ctx, shape, width, height);
15331
+ if (shape.type !== "text") drawShape(ctx, shape, width, height);
15332
+ }
15333
+ for (const shape of shapes) {
15334
+ if (shape.type === "text") drawShape(ctx, shape, width, height);
15332
15335
  }
15333
15336
  }, [width, height, backgroundColor, shapes]);
15334
15337
  React94.useEffect(() => {
@@ -16891,7 +16894,7 @@ var init_AlgorithmCanvas = __esm({
16891
16894
  DEFAULT_CELL_COLOR = "#e5e7eb";
16892
16895
  DEFAULT_POINTER_COLOR = "#dc2626";
16893
16896
  POINTER_BAND = 34;
16894
- TOP_PAD = 12;
16897
+ TOP_PAD = 26;
16895
16898
  AlgorithmCanvas = ({
16896
16899
  className,
16897
16900
  width = 600,
@@ -27670,6 +27673,7 @@ var init_FilterGroup = __esm({
27670
27673
  init_Badge();
27671
27674
  init_Stack();
27672
27675
  init_Icon();
27676
+ init_RangeSlider();
27673
27677
  init_useEventBus();
27674
27678
  init_useQuerySingleton();
27675
27679
  resolveFilterType = (filter) => filter.filterType ?? filter.type;
@@ -27864,6 +27868,35 @@ var init_FilterGroup = __esm({
27864
27868
  onClear: () => handleFilterSelect(`${filter.field}_to`, null)
27865
27869
  }
27866
27870
  )
27871
+ ] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
27872
+ /* @__PURE__ */ jsxRuntime.jsx(
27873
+ RangeSlider,
27874
+ {
27875
+ min: filter.min ?? 0,
27876
+ max: filter.max ?? 100,
27877
+ step: filter.step ?? 1,
27878
+ value: Number(
27879
+ selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
27880
+ ),
27881
+ onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
27882
+ showTooltip: true,
27883
+ "aria-label": t("filterGroup.from")
27884
+ }
27885
+ ),
27886
+ /* @__PURE__ */ jsxRuntime.jsx(
27887
+ RangeSlider,
27888
+ {
27889
+ min: filter.min ?? 0,
27890
+ max: filter.max ?? 100,
27891
+ step: filter.step ?? 1,
27892
+ value: Number(
27893
+ selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
27894
+ ),
27895
+ onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
27896
+ showTooltip: true,
27897
+ "aria-label": t("filterGroup.to")
27898
+ }
27899
+ )
27867
27900
  ] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
27868
27901
  Input,
27869
27902
  {
@@ -27946,6 +27979,36 @@ var init_FilterGroup = __esm({
27946
27979
  className: "text-sm min-w-[100px]"
27947
27980
  }
27948
27981
  )
27982
+ ] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
27983
+ /* @__PURE__ */ jsxRuntime.jsx(
27984
+ RangeSlider,
27985
+ {
27986
+ min: filter.min ?? 0,
27987
+ max: filter.max ?? 100,
27988
+ step: filter.step ?? 1,
27989
+ value: Number(
27990
+ selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
27991
+ ),
27992
+ onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
27993
+ className: "min-w-[100px]",
27994
+ "aria-label": t("filterGroup.from")
27995
+ }
27996
+ ),
27997
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
27998
+ /* @__PURE__ */ jsxRuntime.jsx(
27999
+ RangeSlider,
28000
+ {
28001
+ min: filter.min ?? 0,
28002
+ max: filter.max ?? 100,
28003
+ step: filter.step ?? 1,
28004
+ value: Number(
28005
+ selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
28006
+ ),
28007
+ onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
28008
+ className: "min-w-[100px]",
28009
+ "aria-label": t("filterGroup.to")
28010
+ }
28011
+ )
27949
28012
  ] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
27950
28013
  Input,
27951
28014
  {
@@ -28064,6 +28127,38 @@ var init_FilterGroup = __esm({
28064
28127
  className: "min-w-[130px]"
28065
28128
  }
28066
28129
  )
28130
+ ] }) : resolveFilterType(filter) === "numberrange" || resolveFilterType(filter) === "number-range" ? /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", align: "center", children: [
28131
+ /* @__PURE__ */ jsxRuntime.jsx(
28132
+ RangeSlider,
28133
+ {
28134
+ min: filter.min ?? 0,
28135
+ max: filter.max ?? 100,
28136
+ step: filter.step ?? 1,
28137
+ value: Number(
28138
+ selectedValues[`${filter.field}_min`] ?? filter.min ?? 0
28139
+ ),
28140
+ onChange: (v) => handleFilterSelect(`${filter.field}_min`, String(v)),
28141
+ showTooltip: true,
28142
+ className: "min-w-[130px]",
28143
+ "aria-label": t("filterGroup.from")
28144
+ }
28145
+ ),
28146
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "-" }),
28147
+ /* @__PURE__ */ jsxRuntime.jsx(
28148
+ RangeSlider,
28149
+ {
28150
+ min: filter.min ?? 0,
28151
+ max: filter.max ?? 100,
28152
+ step: filter.step ?? 1,
28153
+ value: Number(
28154
+ selectedValues[`${filter.field}_max`] ?? filter.max ?? 100
28155
+ ),
28156
+ onChange: (v) => handleFilterSelect(`${filter.field}_max`, String(v)),
28157
+ showTooltip: true,
28158
+ className: "min-w-[130px]",
28159
+ "aria-label": t("filterGroup.to")
28160
+ }
28161
+ )
28067
28162
  ] }) : resolveFilterType(filter) === "text" ? /* @__PURE__ */ jsxRuntime.jsx(
28068
28163
  Input,
28069
28164
  {
@@ -29963,7 +30058,12 @@ function daysAgo(n) {
29963
30058
  d.setDate(d.getDate() - n);
29964
30059
  return d;
29965
30060
  }
29966
- var DEFAULT_PRESETS, DateRangePicker;
30061
+ function resolvePresetRange(preset) {
30062
+ if (typeof preset.range === "function") return preset.range();
30063
+ if (preset.range) return preset.range;
30064
+ return TOKEN_RANGES[preset.value]?.() ?? null;
30065
+ }
30066
+ var TOKEN_RANGES, DEFAULT_PRESETS, DateRangePicker;
29967
30067
  var init_DateRangePicker = __esm({
29968
30068
  "components/core/molecules/DateRangePicker.tsx"() {
29969
30069
  "use client";
@@ -29973,32 +30073,19 @@ var init_DateRangePicker = __esm({
29973
30073
  init_Stack();
29974
30074
  init_Typography();
29975
30075
  init_useEventBus();
30076
+ TOKEN_RANGES = {
30077
+ "7d": () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) }),
30078
+ "30d": () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) }),
30079
+ month: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
30080
+ quarter: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) }),
30081
+ ytd: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
30082
+ };
29976
30083
  DEFAULT_PRESETS = [
29977
- {
29978
- label: "Last 7 days",
29979
- value: "7d",
29980
- range: () => ({ from: toISODate(daysAgo(7)), to: toISODate(/* @__PURE__ */ new Date()) })
29981
- },
29982
- {
29983
- label: "Last 30 days",
29984
- value: "30d",
29985
- range: () => ({ from: toISODate(daysAgo(30)), to: toISODate(/* @__PURE__ */ new Date()) })
29986
- },
29987
- {
29988
- label: "This Month",
29989
- value: "month",
29990
- range: () => ({ from: toISODate(startOfMonth(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
29991
- },
29992
- {
29993
- label: "This Quarter",
29994
- value: "quarter",
29995
- range: () => ({ from: toISODate(startOfQuarter(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
29996
- },
29997
- {
29998
- label: "YTD",
29999
- value: "ytd",
30000
- range: () => ({ from: toISODate(startOfYear(/* @__PURE__ */ new Date())), to: toISODate(/* @__PURE__ */ new Date()) })
30001
- }
30084
+ { label: "Last 7 days", value: "7d" },
30085
+ { label: "Last 30 days", value: "30d" },
30086
+ { label: "This Month", value: "month" },
30087
+ { label: "This Quarter", value: "quarter" },
30088
+ { label: "YTD", value: "ytd" }
30002
30089
  ];
30003
30090
  DateRangePicker = ({
30004
30091
  from: fromProp,
@@ -30039,7 +30126,8 @@ var init_DateRangePicker = __esm({
30039
30126
  );
30040
30127
  const handlePreset = React94.useCallback(
30041
30128
  (preset) => {
30042
- const range = preset.range();
30129
+ const range = resolvePresetRange(preset);
30130
+ if (range === null) return;
30043
30131
  setFrom(range.from);
30044
30132
  setTo(range.to);
30045
30133
  setActivePreset(preset.value);
@@ -30047,8 +30135,12 @@ var init_DateRangePicker = __esm({
30047
30135
  },
30048
30136
  [emit]
30049
30137
  );
30138
+ const renderablePresets = React94.useMemo(
30139
+ () => presets.filter((p) => p.range !== void 0 || TOKEN_RANGES[p.value] !== void 0),
30140
+ [presets]
30141
+ );
30050
30142
  const presetButtons = React94.useMemo(
30051
- () => presets.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
30143
+ () => renderablePresets.map((preset) => /* @__PURE__ */ jsxRuntime.jsx(
30052
30144
  Button,
30053
30145
  {
30054
30146
  variant: activePreset === preset.value ? "primary" : "ghost",
@@ -30058,7 +30150,7 @@ var init_DateRangePicker = __esm({
30058
30150
  },
30059
30151
  preset.value
30060
30152
  )),
30061
- [presets, activePreset, handlePreset]
30153
+ [renderablePresets, activePreset, handlePreset]
30062
30154
  );
30063
30155
  return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", className: cn(className), children: [
30064
30156
  /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "md", align: "end", children: [
@@ -30085,7 +30177,7 @@ var init_DateRangePicker = __esm({
30085
30177
  )
30086
30178
  ] })
30087
30179
  ] }),
30088
- presets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
30180
+ renderablePresets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", wrap: true, children: presetButtons })
30089
30181
  ] });
30090
30182
  };
30091
30183
  DateRangePicker.displayName = "DateRangePicker";
@@ -30527,6 +30619,208 @@ var init_PhysicsCanvas = __esm({
30527
30619
  };
30528
30620
  }
30529
30621
  });
30622
+
30623
+ // lib/graphViewLayouts.ts
30624
+ function buildAdjacency(nodeIds, edges) {
30625
+ const known = new Set(nodeIds);
30626
+ const out = /* @__PURE__ */ new Map();
30627
+ const inMap = /* @__PURE__ */ new Map();
30628
+ for (const id of nodeIds) {
30629
+ out.set(id, []);
30630
+ inMap.set(id, []);
30631
+ }
30632
+ for (const edge of edges) {
30633
+ if (!known.has(edge.source) || !known.has(edge.target)) continue;
30634
+ out.get(edge.source)?.push(edge.target);
30635
+ inMap.get(edge.target)?.push(edge.source);
30636
+ }
30637
+ return { out, in: inMap };
30638
+ }
30639
+ function findRoots(nodeIds, adjacency) {
30640
+ return nodeIds.filter((id) => (adjacency.in.get(id)?.length ?? 0) === 0);
30641
+ }
30642
+ function assignLayers(nodeIds, adjacency, roots) {
30643
+ const layer = new Map(nodeIds.map((id) => [id, 0]));
30644
+ const onStack = /* @__PURE__ */ new Set();
30645
+ const visit = (id) => {
30646
+ onStack.add(id);
30647
+ const currentLayer = layer.get(id) ?? 0;
30648
+ for (const next of adjacency.out.get(id) ?? []) {
30649
+ if (onStack.has(next)) continue;
30650
+ const candidate = currentLayer + 1;
30651
+ if (candidate > (layer.get(next) ?? 0)) {
30652
+ layer.set(next, candidate);
30653
+ }
30654
+ visit(next);
30655
+ }
30656
+ onStack.delete(id);
30657
+ };
30658
+ for (const root of roots) visit(root);
30659
+ return layer;
30660
+ }
30661
+ function computeVisitOrder(nodeIds, adjacency, roots) {
30662
+ const order = /* @__PURE__ */ new Map();
30663
+ const visited = /* @__PURE__ */ new Set();
30664
+ let counter = 0;
30665
+ const visit = (id) => {
30666
+ if (visited.has(id)) return;
30667
+ visited.add(id);
30668
+ order.set(id, counter++);
30669
+ for (const next of adjacency.out.get(id) ?? []) visit(next);
30670
+ };
30671
+ for (const root of roots) visit(root);
30672
+ for (const id of nodeIds) {
30673
+ if (!visited.has(id)) order.set(id, counter++);
30674
+ }
30675
+ return order;
30676
+ }
30677
+ function bfsDepthAndOrder(nodeIds, adjacency, roots) {
30678
+ const depth = new Map(nodeIds.map((id) => [id, 0]));
30679
+ const visitOrder = /* @__PURE__ */ new Map();
30680
+ const visited = /* @__PURE__ */ new Set();
30681
+ const queue = [];
30682
+ let counter = 0;
30683
+ for (const root of roots) {
30684
+ if (visited.has(root)) continue;
30685
+ visited.add(root);
30686
+ depth.set(root, 0);
30687
+ visitOrder.set(root, counter++);
30688
+ queue.push(root);
30689
+ }
30690
+ let head = 0;
30691
+ while (head < queue.length) {
30692
+ const id = queue[head++];
30693
+ const d = depth.get(id) ?? 0;
30694
+ for (const next of adjacency.out.get(id) ?? []) {
30695
+ if (visited.has(next)) continue;
30696
+ visited.add(next);
30697
+ depth.set(next, d + 1);
30698
+ visitOrder.set(next, counter++);
30699
+ queue.push(next);
30700
+ }
30701
+ }
30702
+ for (const id of nodeIds) {
30703
+ if (!visited.has(id)) visitOrder.set(id, counter++);
30704
+ }
30705
+ return { depth, visitOrder };
30706
+ }
30707
+ function edgeWalkOrder(nodeIds, adjacency) {
30708
+ const visited = /* @__PURE__ */ new Set();
30709
+ const result = [];
30710
+ for (const start of nodeIds) {
30711
+ if (visited.has(start)) continue;
30712
+ let current = start;
30713
+ while (current !== void 0 && !visited.has(current)) {
30714
+ visited.add(current);
30715
+ result.push(current);
30716
+ const outs = adjacency.out.get(current) ?? [];
30717
+ current = outs.find((next) => !visited.has(next));
30718
+ }
30719
+ }
30720
+ return result;
30721
+ }
30722
+ function groupByTier(nodeIds, tierOf, maxTier) {
30723
+ const groups = Array.from({ length: maxTier + 1 }, () => []);
30724
+ for (const id of nodeIds) {
30725
+ groups[tierOf.get(id) ?? 0].push(id);
30726
+ }
30727
+ return groups;
30728
+ }
30729
+ function distributeAxis(count, start, end) {
30730
+ if (count <= 0) return [];
30731
+ const slot = (end - start) / count;
30732
+ return Array.from({ length: count }, (_, i) => start + slot * (i + 0.5));
30733
+ }
30734
+ function orderByParentPositionThenInput(group, adjacency, positioned, inputIndex) {
30735
+ const withKey = group.map((id) => {
30736
+ const parentValues = (adjacency.in.get(id) ?? []).map((p) => positioned.get(p)).filter((v) => v !== void 0);
30737
+ const avg = parentValues.length > 0 ? parentValues.reduce((a, b) => a + b, 0) / parentValues.length : Number.POSITIVE_INFINITY;
30738
+ return { id, avg, idx: inputIndex.get(id) ?? 0 };
30739
+ });
30740
+ withKey.sort((a, b) => a.avg !== b.avg ? a.avg - b.avg : a.idx - b.idx);
30741
+ return withKey.map((k) => k.id);
30742
+ }
30743
+ function layoutFlow(nodeIds, adjacency, roots, width, height, margin) {
30744
+ const inputIndex = new Map(nodeIds.map((id, i) => [id, i]));
30745
+ const layers = assignLayers(nodeIds, adjacency, roots);
30746
+ const maxLayer = Math.max(...Array.from(layers.values()));
30747
+ const layerGroups = groupByTier(nodeIds, layers, maxLayer);
30748
+ const positions = /* @__PURE__ */ new Map();
30749
+ const yById = /* @__PURE__ */ new Map();
30750
+ for (let l = 0; l <= maxLayer; l++) {
30751
+ const x = margin + l * (width - 2 * margin) / Math.max(1, maxLayer);
30752
+ const ordered2 = orderByParentPositionThenInput(layerGroups[l], adjacency, yById, inputIndex);
30753
+ const ys = distributeAxis(ordered2.length, margin, height - margin);
30754
+ ordered2.forEach((id, i) => {
30755
+ positions.set(id, { id, x, y: ys[i] });
30756
+ yById.set(id, ys[i]);
30757
+ });
30758
+ }
30759
+ return nodeIds.map((id) => positions.get(id));
30760
+ }
30761
+ function layoutTree2(nodeIds, adjacency, roots, width, height, margin) {
30762
+ const effectiveRoots = roots.length > 0 ? roots : [nodeIds[0]];
30763
+ const layers = assignLayers(nodeIds, adjacency, effectiveRoots);
30764
+ const maxLayer = Math.max(...Array.from(layers.values()));
30765
+ const visitOrder = computeVisitOrder(nodeIds, adjacency, effectiveRoots);
30766
+ const layerGroups = groupByTier(nodeIds, layers, maxLayer);
30767
+ const positions = /* @__PURE__ */ new Map();
30768
+ for (let l = 0; l <= maxLayer; l++) {
30769
+ const ordered2 = [...layerGroups[l]].sort(
30770
+ (a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
30771
+ );
30772
+ const y = margin + l * (height - 2 * margin) / Math.max(1, maxLayer);
30773
+ const xs = distributeAxis(ordered2.length, margin, width - margin);
30774
+ ordered2.forEach((id, i) => positions.set(id, { id, x: xs[i], y }));
30775
+ }
30776
+ return nodeIds.map((id) => positions.get(id));
30777
+ }
30778
+ function layoutRadial(nodeIds, adjacency, roots, width, height, margin) {
30779
+ const cx = width / 2;
30780
+ const cy = height / 2;
30781
+ const maxRadius = Math.min(width, height) / 2 - margin;
30782
+ if (roots.length === 0) {
30783
+ const order = edgeWalkOrder(nodeIds, adjacency);
30784
+ const k = order.length;
30785
+ const positions2 = /* @__PURE__ */ new Map();
30786
+ order.forEach((id, i) => {
30787
+ const angle = i / k * 2 * Math.PI;
30788
+ positions2.set(id, { id, x: cx + maxRadius * Math.cos(angle), y: cy + maxRadius * Math.sin(angle) });
30789
+ });
30790
+ return nodeIds.map((id) => positions2.get(id));
30791
+ }
30792
+ const { depth, visitOrder } = bfsDepthAndOrder(nodeIds, adjacency, roots);
30793
+ const maxDepth = Math.max(...Array.from(depth.values()));
30794
+ const ringGroups = groupByTier(nodeIds, depth, maxDepth);
30795
+ const positions = /* @__PURE__ */ new Map();
30796
+ for (let d = 0; d <= maxDepth; d++) {
30797
+ const ordered2 = [...ringGroups[d]].sort(
30798
+ (a, b) => (visitOrder.get(a) ?? 0) - (visitOrder.get(b) ?? 0)
30799
+ );
30800
+ const radius = d * maxRadius / Math.max(1, maxDepth);
30801
+ const k = ordered2.length;
30802
+ ordered2.forEach((id, i) => {
30803
+ const angle = i / k * 2 * Math.PI;
30804
+ positions.set(id, { id, x: cx + radius * Math.cos(angle), y: cy + radius * Math.sin(angle) });
30805
+ });
30806
+ }
30807
+ return nodeIds.map((id) => positions.get(id));
30808
+ }
30809
+ function computeStaticLayout(mode, input) {
30810
+ const { nodeIds, edges, width, height } = input;
30811
+ const margin = input.margin ?? 40;
30812
+ if (nodeIds.length === 0) return [];
30813
+ if (nodeIds.length === 1) return [{ id: nodeIds[0], x: width / 2, y: height / 2 }];
30814
+ const adjacency = buildAdjacency(nodeIds, edges);
30815
+ const roots = findRoots(nodeIds, adjacency);
30816
+ if (mode === "flow") return layoutFlow(nodeIds, adjacency, roots, width, height, margin);
30817
+ if (mode === "tree") return layoutTree2(nodeIds, adjacency, roots, width, height, margin);
30818
+ return layoutRadial(nodeIds, adjacency, roots, width, height, margin);
30819
+ }
30820
+ var init_graphViewLayouts = __esm({
30821
+ "lib/graphViewLayouts.ts"() {
30822
+ }
30823
+ });
30530
30824
  function resolveNodeColor(node, groups) {
30531
30825
  if (node.color) return node.color;
30532
30826
  if (node.group) {
@@ -30541,6 +30835,7 @@ var init_GraphView = __esm({
30541
30835
  "use client";
30542
30836
  init_cn();
30543
30837
  init_atoms();
30838
+ init_graphViewLayouts();
30544
30839
  GROUP_COLORS = [
30545
30840
  "#3b82f6",
30546
30841
  // blue-500
@@ -30571,11 +30866,13 @@ var init_GraphView = __esm({
30571
30866
  height: propHeight,
30572
30867
  className,
30573
30868
  showLabels = true,
30574
- zoomToFit = true
30869
+ zoomToFit = true,
30870
+ layout = "force"
30575
30871
  }) => {
30576
30872
  const { t } = hooks.useTranslate();
30577
30873
  const containerRef = React94.useRef(null);
30578
30874
  const animRef = React94.useRef(0);
30875
+ const arrowMarkerId = React94.useId();
30579
30876
  const [simNodes, setSimNodes] = React94.useState([]);
30580
30877
  const [settled, setSettled] = React94.useState(false);
30581
30878
  const [hoveredId, setHoveredId] = React94.useState(null);
@@ -30632,6 +30929,22 @@ var init_GraphView = __esm({
30632
30929
  fy: 0
30633
30930
  };
30634
30931
  });
30932
+ if (layout !== "force") {
30933
+ const points = computeStaticLayout(layout, {
30934
+ nodeIds: nodes.map((n) => n.id),
30935
+ edges,
30936
+ width: w,
30937
+ height: h
30938
+ });
30939
+ const pointById = new Map(points.map((p) => [p.id, p]));
30940
+ const laidOut = initialNodes.map((node) => {
30941
+ const point = pointById.get(node.id);
30942
+ return point ? { ...node, x: point.x, y: point.y } : node;
30943
+ });
30944
+ setSimNodes(laidOut);
30945
+ setSettled(true);
30946
+ return;
30947
+ }
30635
30948
  let iterations = 0;
30636
30949
  const maxIterations = 120;
30637
30950
  let currentNodes = initialNodes;
@@ -30700,7 +31013,7 @@ var init_GraphView = __esm({
30700
31013
  return () => {
30701
31014
  cancelAnimationFrame(animRef.current);
30702
31015
  };
30703
- }, [nodes, edges, w, h, groups]);
31016
+ }, [nodes, edges, w, h, groups, layout]);
30704
31017
  const viewBox = React94.useMemo(() => {
30705
31018
  if (!zoomToFit || !settled || simNodes.length === 0) {
30706
31019
  return `0 0 ${w} ${h}`;
@@ -30775,6 +31088,19 @@ var init_GraphView = __esm({
30775
31088
  viewBox,
30776
31089
  preserveAspectRatio: "xMidYMid meet",
30777
31090
  children: [
31091
+ layout !== "force" && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
31092
+ "marker",
31093
+ {
31094
+ id: arrowMarkerId,
31095
+ viewBox: "0 0 10 10",
31096
+ refX: "9",
31097
+ refY: "5",
31098
+ markerWidth: "6",
31099
+ markerHeight: "6",
31100
+ orient: "auto-start-reverse",
31101
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L10,5 L0,10 z", fill: "currentColor" })
31102
+ }
31103
+ ) }),
30778
31104
  edges.map((edge, idx) => {
30779
31105
  const source = nodeMap.get(edge.source);
30780
31106
  const target = nodeMap.get(edge.target);
@@ -30789,8 +31115,10 @@ var init_GraphView = __esm({
30789
31115
  x2: target.x,
30790
31116
  y2: target.y,
30791
31117
  stroke: edge.color ?? DEFAULT_EDGE_COLOR,
31118
+ color: edge.color ?? DEFAULT_EDGE_COLOR,
30792
31119
  strokeWidth: 1.5,
30793
- opacity: isHighlighted ? 0.8 : 0.15
31120
+ opacity: isHighlighted ? 0.8 : 0.15,
31121
+ markerEnd: layout !== "force" ? `url(#${arrowMarkerId})` : void 0
30794
31122
  }
30795
31123
  ),
30796
31124
  showLabels && edge.label && /* @__PURE__ */ jsxRuntime.jsx(