@likec4/diagram 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/KeepAspectRatioContainer.d.ts +1 -1
  2. package/dist/LikeC4Diagram.d.ts +1 -1
  3. package/dist/LikeC4Diagram.props.d.ts +22 -12
  4. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.mjs +2209 -706
  7. package/dist/mantine/EnsureMantine.d.ts +1 -1
  8. package/dist/state/DiagramContext.d.ts +2143 -19
  9. package/dist/state/WhenInitialized.d.ts +1 -1
  10. package/dist/state/diagramStore.d.ts +2152 -19
  11. package/dist/state/useDiagramStore.d.ts +2142 -18
  12. package/dist/style.css +256 -118
  13. package/dist/theme.css.d.ts +1 -0
  14. package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
  15. package/dist/ui/DiagramTitlePanel.d.ts +1 -0
  16. package/dist/ui/DynamicViewWalkthrough.css.d.ts +3 -0
  17. package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
  18. package/dist/ui/OptionsPanel.d.ts +1 -3
  19. package/dist/ui/index.d.ts +1 -0
  20. package/dist/ui/options/NodeOptions.d.ts +1 -2
  21. package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -2
  22. package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
  23. package/dist/xyflow/SyncWithDiagram.d.ts +1 -2
  24. package/dist/xyflow/XYFlow.d.ts +4 -7
  25. package/dist/xyflow/XYFlowBackground.d.ts +5 -4
  26. package/dist/xyflow/XYFlowEvents.d.ts +84 -84
  27. package/dist/xyflow/XYFlowInner.d.ts +11 -0
  28. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  29. package/dist/xyflow/edges/RelationshipEdge.d.ts +14 -14
  30. package/dist/xyflow/edges/edges.css.d.ts +5 -2
  31. package/dist/xyflow/edges/utils.d.ts +2 -0
  32. package/dist/xyflow/hooks/useXYFlow.d.ts +126 -126
  33. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +1 -0
  34. package/dist/xyflow/nodes/element/ElementIcon.d.ts +1 -1
  35. package/dist/xyflow/nodes/element/ElementLink.d.ts +1 -1
  36. package/dist/xyflow/nodes/element/ElementNode.d.ts +1 -1
  37. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +2 -2
  38. package/dist/xyflow/nodes/element/element.css.d.ts +2 -1
  39. package/dist/xyflow/nodes/shared/NavigateToBtn.d.ts +1 -2
  40. package/dist/xyflow/types.d.ts +18 -18
  41. package/package.json +21 -16
  42. package/src/KeepAspectRatioContainer.tsx +1 -1
  43. package/src/LikeC4Diagram.css.ts +4 -1
  44. package/src/LikeC4Diagram.props.ts +24 -14
  45. package/src/LikeC4Diagram.tsx +18 -9
  46. package/src/StaticLikeC4Diagram.tsx +2 -0
  47. package/src/globals.css.ts +7 -1
  48. package/src/index.ts +0 -3
  49. package/src/state/DiagramContext.tsx +21 -12
  50. package/src/state/diagramStore.ts +275 -98
  51. package/src/theme.css.ts +1 -0
  52. package/src/ui/DiagramTitlePanel.css.ts +33 -0
  53. package/src/ui/DiagramTitlePanel.tsx +138 -0
  54. package/src/ui/DynamicViewWalkthrough.css.ts +46 -0
  55. package/src/ui/DynamicViewWalkthrough.tsx +86 -0
  56. package/src/ui/OptionsPanel.tsx +7 -24
  57. package/src/ui/index.ts +1 -0
  58. package/src/ui/options/NodeOptions.tsx +103 -27
  59. package/src/xyflow/FitviewOnDiagramChange.tsx +89 -69
  60. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +75 -0
  61. package/src/xyflow/SyncWithDiagram.tsx +55 -101
  62. package/src/xyflow/XYFlow.tsx +52 -32
  63. package/src/xyflow/XYFlowBackground.tsx +7 -5
  64. package/src/xyflow/XYFlowEvents.tsx +150 -104
  65. package/src/xyflow/XYFlowInner.tsx +50 -0
  66. package/src/xyflow/diagram-to-xyflow.ts +16 -21
  67. package/src/xyflow/edges/RelationshipEdge.tsx +102 -70
  68. package/src/xyflow/edges/edges.css.ts +128 -53
  69. package/src/xyflow/edges/utils.ts +31 -0
  70. package/src/xyflow/nodes/compound/CompoundNode.css.ts +20 -12
  71. package/src/xyflow/nodes/compound/CompoundNode.tsx +6 -3
  72. package/src/xyflow/nodes/element/ElementLink.tsx +13 -3
  73. package/src/xyflow/nodes/element/ElementNode.tsx +24 -19
  74. package/src/xyflow/nodes/element/element.css.ts +10 -2
  75. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -0
  76. package/src/xyflow/types.ts +7 -8
package/dist/index.mjs CHANGED
@@ -6,15 +6,17 @@ import { createContext, memo, useState, forwardRef, useCallback, useMemo, useEff
6
6
  import { createWithEqualityFn, useStoreWithEqualityFn } from "zustand/traditional";
7
7
  import { shallow } from "zustand/shallow";
8
8
  import { createPortal } from "react-dom";
9
- import { Box, MantineContext, Stack, Text, TooltipGroup, Divider, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Card, ActionIcon, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Group, Anchor, CopyButton, Button, useMantineColorScheme } from "@mantine/core";
10
- import { invariant, isAncestor, nonNullable, nonexhaustive, defaultTheme, ElementShapes } from "@likec4/core";
9
+ import { Box, MantineContext, ActionIcon, Text, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Stack, Group, Anchor, CopyButton, Button, useMantineColorScheme, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card, Paper, Spoiler } from "@mantine/core";
10
+ import { isNullish, entries, hasSubObject, hasAtLeast, first, last, zip, clamp as clamp$1, isNumber, keys, takeWhile, isNonNull } from "remeda";
11
+ import { invariant, isAncestor, nonNullable, StepEdgeId, nonexhaustive, extractStep, defaultTheme, ElementShapes } from "@likec4/core";
11
12
  import { DEV } from "esm-env";
12
13
  import { shallowEqual, deepEqual } from "fast-equals";
13
14
  import { subscribeWithSelector, devtools } from "zustand/middleware";
14
- import { useFirstMountState, useCustomCompareEffect, useDebouncedCallback, useRafEffect, useDebouncedEffect } from "@react-hookz/web";
15
- import { AnimatePresence, motion } from "framer-motion";
16
- import { isNullish, keys, hasAtLeast, takeWhile, clamp as clamp$1, isNumber } from "remeda";
17
- var rootClassName = "likec4-diagram-root";
15
+ import { useFirstMountState, useCustomCompareEffect, useDebouncedEffect } from "@react-hookz/web";
16
+ import { line, curveCatmullRomOpen } from "d3-shape";
17
+ import { motion, AnimatePresence } from "framer-motion";
18
+ import { useLocalStorage } from "@mantine/hooks";
19
+ import { IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
18
20
  function cc(names) {
19
21
  if (typeof names == "string" || typeof names == "number")
20
22
  return "" + names;
@@ -30,10 +32,10 @@ function cc(names) {
30
32
  var noop$1 = { value: () => {
31
33
  } };
32
34
  function dispatch() {
33
- for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
34
- if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t))
35
- throw new Error("illegal type: " + t);
36
- _[t] = [];
35
+ for (var i = 0, n = arguments.length, _ = {}, t2; i < n; ++i) {
36
+ if (!(t2 = arguments[i] + "") || t2 in _ || /[\s.]/.test(t2))
37
+ throw new Error("illegal type: " + t2);
38
+ _[t2] = [];
37
39
  }
38
40
  return new Dispatch(_);
39
41
  }
@@ -41,53 +43,53 @@ function Dispatch(_) {
41
43
  this._ = _;
42
44
  }
43
45
  function parseTypenames$1(typenames, types) {
44
- return typenames.trim().split(/^|\s+/).map(function(t) {
45
- var name = "", i = t.indexOf(".");
46
- if (i >= 0 && (name = t.slice(i + 1), t = t.slice(0, i)), t && !types.hasOwnProperty(t))
47
- throw new Error("unknown type: " + t);
48
- return { type: t, name };
46
+ return typenames.trim().split(/^|\s+/).map(function(t2) {
47
+ var name = "", i = t2.indexOf(".");
48
+ if (i >= 0 && (name = t2.slice(i + 1), t2 = t2.slice(0, i)), t2 && !types.hasOwnProperty(t2))
49
+ throw new Error("unknown type: " + t2);
50
+ return { type: t2, name };
49
51
  });
50
52
  }
51
53
  Dispatch.prototype = dispatch.prototype = {
52
54
  constructor: Dispatch,
53
55
  on: function(typename, callback) {
54
- var _ = this._, T = parseTypenames$1(typename + "", _), t, i = -1, n = T.length;
56
+ var _ = this._, T = parseTypenames$1(typename + "", _), t2, i = -1, n = T.length;
55
57
  if (arguments.length < 2) {
56
58
  for (; ++i < n; )
57
- if ((t = (typename = T[i]).type) && (t = get$2(_[t], typename.name)))
58
- return t;
59
+ if ((t2 = (typename = T[i]).type) && (t2 = get$2(_[t2], typename.name)))
60
+ return t2;
59
61
  return;
60
62
  }
61
63
  if (callback != null && typeof callback != "function")
62
64
  throw new Error("invalid callback: " + callback);
63
65
  for (; ++i < n; )
64
- if (t = (typename = T[i]).type)
65
- _[t] = set$1(_[t], typename.name, callback);
66
+ if (t2 = (typename = T[i]).type)
67
+ _[t2] = set$1(_[t2], typename.name, callback);
66
68
  else if (callback == null)
67
- for (t in _)
68
- _[t] = set$1(_[t], typename.name, null);
69
+ for (t2 in _)
70
+ _[t2] = set$1(_[t2], typename.name, null);
69
71
  return this;
70
72
  },
71
73
  copy: function() {
72
74
  var copy = {}, _ = this._;
73
- for (var t in _)
74
- copy[t] = _[t].slice();
75
+ for (var t2 in _)
76
+ copy[t2] = _[t2].slice();
75
77
  return new Dispatch(copy);
76
78
  },
77
79
  call: function(type, that) {
78
80
  if ((n = arguments.length - 2) > 0)
79
- for (var args = new Array(n), i = 0, n, t; i < n; ++i)
81
+ for (var args = new Array(n), i = 0, n, t2; i < n; ++i)
80
82
  args[i] = arguments[i + 2];
81
83
  if (!this._.hasOwnProperty(type))
82
84
  throw new Error("unknown type: " + type);
83
- for (t = this._[type], i = 0, n = t.length; i < n; ++i)
84
- t[i].value.apply(that, args);
85
+ for (t2 = this._[type], i = 0, n = t2.length; i < n; ++i)
86
+ t2[i].value.apply(that, args);
85
87
  },
86
88
  apply: function(type, that, args) {
87
89
  if (!this._.hasOwnProperty(type))
88
90
  throw new Error("unknown type: " + type);
89
- for (var t = this._[type], i = 0, n = t.length; i < n; ++i)
90
- t[i].value.apply(that, args);
91
+ for (var t2 = this._[type], i = 0, n = t2.length; i < n; ++i)
92
+ t2[i].value.apply(that, args);
91
93
  }
92
94
  };
93
95
  function get$2(type, name) {
@@ -569,9 +571,9 @@ function contextListener(listener) {
569
571
  };
570
572
  }
571
573
  function parseTypenames(typenames) {
572
- return typenames.trim().split(/^|\s+/).map(function(t) {
573
- var name = "", i = t.indexOf(".");
574
- return i >= 0 && (name = t.slice(i + 1), t = t.slice(0, i)), { type: t, name };
574
+ return typenames.trim().split(/^|\s+/).map(function(t2) {
575
+ var name = "", i = t2.indexOf(".");
576
+ return i >= 0 && (name = t2.slice(i + 1), t2 = t2.slice(0, i)), { type: t2, name };
575
577
  });
576
578
  }
577
579
  function onRemove(typename) {
@@ -598,13 +600,13 @@ function onAdd(typename, value, options) {
598
600
  };
599
601
  }
600
602
  function selection_on(typename, value, options) {
601
- var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
603
+ var typenames = parseTypenames(typename + ""), i, n = typenames.length, t2;
602
604
  if (arguments.length < 2) {
603
605
  var on = this.node().__on;
604
606
  if (on) {
605
607
  for (var j = 0, m = on.length, o; j < m; ++j)
606
608
  for (i = 0, o = on[j]; i < n; ++i)
607
- if ((t = typenames[i]).type === o.type && t.name === o.name)
609
+ if ((t2 = typenames[i]).type === o.type && t2.name === o.name)
608
610
  return o.value;
609
611
  }
610
612
  return;
@@ -1125,8 +1127,8 @@ function hslConvert(o) {
1125
1127
  if (o instanceof Hsl)
1126
1128
  return o;
1127
1129
  o = o.rgb();
1128
- var r2 = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r2, g, b), max = Math.max(r2, g, b), h = NaN, s = max - min, l = (max + min) / 2;
1129
- return s ? (r2 === max ? h = (g - b) / s + (g < b) * 6 : g === max ? h = (b - r2) / s + 2 : h = (r2 - g) / s + 4, s /= l < 0.5 ? max + min : 2 - max - min, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity);
1130
+ var r2 = o.r / 255, g = o.g / 255, b = o.b / 255, min2 = Math.min(r2, g, b), max2 = Math.max(r2, g, b), h = NaN, s = max2 - min2, l = (max2 + min2) / 2;
1131
+ return s ? (r2 === max2 ? h = (g - b) / s + (g < b) * 6 : g === max2 ? h = (b - r2) / s + 2 : h = (r2 - g) / s + 4, s /= l < 0.5 ? max2 + min2 : 2 - max2 - min2, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity);
1130
1132
  }
1131
1133
  function hsl(h, s, l, opacity) {
1132
1134
  return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity ?? 1);
@@ -1172,13 +1174,13 @@ function hsl2rgb(h, m1, m2) {
1172
1174
  }
1173
1175
  const constant$1 = (x) => () => x;
1174
1176
  function linear(a, d) {
1175
- return function(t) {
1176
- return a + t * d;
1177
+ return function(t2) {
1178
+ return a + t2 * d;
1177
1179
  };
1178
1180
  }
1179
1181
  function exponential(a, b, y) {
1180
- return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
1181
- return Math.pow(a + t * b, y);
1182
+ return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t2) {
1183
+ return Math.pow(a + t2 * b, y);
1182
1184
  };
1183
1185
  }
1184
1186
  function gamma(y) {
@@ -1194,15 +1196,15 @@ const interpolateRgb = function rgbGamma(y) {
1194
1196
  var color2 = gamma(y);
1195
1197
  function rgb$1(start2, end) {
1196
1198
  var r2 = color2((start2 = rgb(start2)).r, (end = rgb(end)).r), g = color2(start2.g, end.g), b = color2(start2.b, end.b), opacity = nogamma(start2.opacity, end.opacity);
1197
- return function(t) {
1198
- return start2.r = r2(t), start2.g = g(t), start2.b = b(t), start2.opacity = opacity(t), start2 + "";
1199
+ return function(t2) {
1200
+ return start2.r = r2(t2), start2.g = g(t2), start2.b = b(t2), start2.opacity = opacity(t2), start2 + "";
1199
1201
  };
1200
1202
  }
1201
1203
  return rgb$1.gamma = rgbGamma, rgb$1;
1202
1204
  }(1);
1203
1205
  function interpolateNumber(a, b) {
1204
- return a = +a, b = +b, function(t) {
1205
- return a * (1 - t) + b * t;
1206
+ return a = +a, b = +b, function(t2) {
1207
+ return a * (1 - t2) + b * t2;
1206
1208
  };
1207
1209
  }
1208
1210
  var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, reB = new RegExp(reA.source, "g");
@@ -1212,17 +1214,17 @@ function zero(b) {
1212
1214
  };
1213
1215
  }
1214
1216
  function one(b) {
1215
- return function(t) {
1216
- return b(t) + "";
1217
+ return function(t2) {
1218
+ return b(t2) + "";
1217
1219
  };
1218
1220
  }
1219
1221
  function interpolateString(a, b) {
1220
1222
  var bi = reA.lastIndex = reB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];
1221
1223
  for (a = a + "", b = b + ""; (am = reA.exec(a)) && (bm = reB.exec(b)); )
1222
1224
  (bs = bm.index) > bi && (bs = b.slice(bi, bs), s[i] ? s[i] += bs : s[++i] = bs), (am = am[0]) === (bm = bm[0]) ? s[i] ? s[i] += bm : s[++i] = bm : (s[++i] = null, q.push({ i, x: interpolateNumber(am, bm) })), bi = reB.lastIndex;
1223
- return bi < b.length && (bs = b.slice(bi), s[i] ? s[i] += bs : s[++i] = bs), s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function(t) {
1225
+ return bi < b.length && (bs = b.slice(bi), s[i] ? s[i] += bs : s[++i] = bs), s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function(t2) {
1224
1226
  for (var i2 = 0, o; i2 < b; ++i2)
1225
- s[(o = q[i2]).i] = o.x(t);
1227
+ s[(o = q[i2]).i] = o.x(t2);
1226
1228
  return s.join("");
1227
1229
  });
1228
1230
  }
@@ -1279,9 +1281,9 @@ function interpolateTransform(parse, pxComma, pxParen, degParen) {
1279
1281
  }
1280
1282
  return function(a, b) {
1281
1283
  var s = [], q = [];
1282
- return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t) {
1284
+ return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t2) {
1283
1285
  for (var i = -1, n = q.length, o; ++i < n; )
1284
- s[(o = q[i]).i] = o.x(t);
1286
+ s[(o = q[i]).i] = o.x(t2);
1285
1287
  return s.join("");
1286
1288
  };
1287
1289
  };
@@ -1300,17 +1302,17 @@ const interpolateZoom = function zoomRho(rho, rho2, rho4) {
1300
1302
  function zoom2(p0, p1) {
1301
1303
  var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;
1302
1304
  if (d2 < epsilon2)
1303
- S = Math.log(w1 / w0) / rho, i = function(t) {
1305
+ S = Math.log(w1 / w0) / rho, i = function(t2) {
1304
1306
  return [
1305
- ux0 + t * dx,
1306
- uy0 + t * dy,
1307
- w0 * Math.exp(rho * t * S)
1307
+ ux0 + t2 * dx,
1308
+ uy0 + t2 * dy,
1309
+ w0 * Math.exp(rho * t2 * S)
1308
1310
  ];
1309
1311
  };
1310
1312
  else {
1311
1313
  var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
1312
- S = (r1 - r0) / rho, i = function(t) {
1313
- var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
1314
+ S = (r1 - r0) / rho, i = function(t2) {
1315
+ var s = t2 * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
1314
1316
  return [
1315
1317
  ux0 + u * dx,
1316
1318
  uy0 + u * dy,
@@ -1349,13 +1351,13 @@ Timer.prototype = timer.prototype = {
1349
1351
  }
1350
1352
  };
1351
1353
  function timer(callback, delay, time) {
1352
- var t = new Timer();
1353
- return t.restart(callback, delay, time), t;
1354
+ var t2 = new Timer();
1355
+ return t2.restart(callback, delay, time), t2;
1354
1356
  }
1355
1357
  function timerFlush() {
1356
1358
  now(), ++frame;
1357
- for (var t = taskHead, e; t; )
1358
- (e = clockNow - t._time) >= 0 && t._call.call(void 0, e), t = t._next;
1359
+ for (var t2 = taskHead, e; t2; )
1360
+ (e = clockNow - t2._time) >= 0 && t2._call.call(void 0, e), t2 = t2._next;
1359
1361
  --frame;
1360
1362
  }
1361
1363
  function wake() {
@@ -1383,10 +1385,10 @@ function sleep(time) {
1383
1385
  }
1384
1386
  }
1385
1387
  function timeout(callback, delay, time) {
1386
- var t = new Timer();
1387
- return delay = delay == null ? 0 : +delay, t.restart((elapsed) => {
1388
- t.stop(), callback(elapsed + delay);
1389
- }, delay, time), t;
1388
+ var t2 = new Timer();
1389
+ return delay = delay == null ? 0 : +delay, t2.restart((elapsed) => {
1390
+ t2.stop(), callback(elapsed + delay);
1391
+ }, delay, time), t2;
1390
1392
  }
1391
1393
  var emptyOn = dispatch("start", "end", "cancel", "interrupt"), emptyTween = [], CREATED = 0, SCHEDULED = 1, STARTING = 2, STARTED = 3, RUNNING = 4, ENDING = 5, ENDED = 6;
1392
1394
  function schedule(node, name, id2, index2, group, timing) {
@@ -1454,8 +1456,8 @@ function create(node, id2, self) {
1454
1456
  }
1455
1457
  }
1456
1458
  function tick(elapsed) {
1457
- for (var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; ++i < n; )
1458
- tween[i].call(node, t);
1459
+ for (var t2 = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; ++i < n; )
1460
+ tween[i].call(node, t2);
1459
1461
  self.state === ENDING && (self.on.call("end", node, node.__data__, self.index, self.group), stop());
1460
1462
  }
1461
1463
  function stop() {
@@ -1507,12 +1509,12 @@ function tweenFunction(id2, name, value) {
1507
1509
  var schedule2 = set(this, id2), tween = schedule2.tween;
1508
1510
  if (tween !== tween0) {
1509
1511
  tween1 = (tween0 = tween).slice();
1510
- for (var t = { name, value }, i = 0, n = tween1.length; i < n; ++i)
1512
+ for (var t2 = { name, value }, i = 0, n = tween1.length; i < n; ++i)
1511
1513
  if (tween1[i].name === name) {
1512
- tween1[i] = t;
1514
+ tween1[i] = t2;
1513
1515
  break;
1514
1516
  }
1515
- i === n && tween1.push(t);
1517
+ i === n && tween1.push(t2);
1516
1518
  }
1517
1519
  schedule2.tween = tween1;
1518
1520
  };
@@ -1520,9 +1522,9 @@ function tweenFunction(id2, name, value) {
1520
1522
  function transition_tween(name, value) {
1521
1523
  var id2 = this._id;
1522
1524
  if (name += "", arguments.length < 2) {
1523
- for (var tween = get$1(this.node(), id2).tween, i = 0, n = tween.length, t; i < n; ++i)
1524
- if ((t = tween[i]).name === name)
1525
- return t.value;
1525
+ for (var tween = get$1(this.node(), id2).tween, i = 0, n = tween.length, t2; i < n; ++i)
1526
+ if ((t2 = tween[i]).name === name)
1527
+ return t2.value;
1526
1528
  return null;
1527
1529
  }
1528
1530
  return this.each((value == null ? tweenRemove : tweenFunction)(id2, name, value));
@@ -1583,13 +1585,13 @@ function transition_attr(name, value) {
1583
1585
  return this.attrTween(name, typeof value == "function" ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));
1584
1586
  }
1585
1587
  function attrInterpolate(name, i) {
1586
- return function(t) {
1587
- this.setAttribute(name, i.call(this, t));
1588
+ return function(t2) {
1589
+ this.setAttribute(name, i.call(this, t2));
1588
1590
  };
1589
1591
  }
1590
1592
  function attrInterpolateNS(fullname, i) {
1591
- return function(t) {
1592
- this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));
1593
+ return function(t2) {
1594
+ this.setAttributeNS(fullname.space, fullname.local, i.call(this, t2));
1593
1595
  };
1594
1596
  }
1595
1597
  function attrTweenNS(fullname, value) {
@@ -1689,9 +1691,9 @@ function transition_merge(transition) {
1689
1691
  return new Transition(merges, this._parents, this._name, this._id);
1690
1692
  }
1691
1693
  function start(name) {
1692
- return (name + "").trim().split(/^|\s+/).every(function(t) {
1693
- var i = t.indexOf(".");
1694
- return i >= 0 && (t = t.slice(0, i)), !t || t === "start";
1694
+ return (name + "").trim().split(/^|\s+/).every(function(t2) {
1695
+ var i = t2.indexOf(".");
1696
+ return i >= 0 && (t2 = t2.slice(0, i)), !t2 || t2 === "start";
1695
1697
  });
1696
1698
  }
1697
1699
  function onFunction(id2, name, listener) {
@@ -1779,15 +1781,15 @@ function transition_style(name, value, priority) {
1779
1781
  return value == null ? this.styleTween(name, styleNull(name, i)).on("end.style." + name, styleRemove(name)) : typeof value == "function" ? this.styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value))).each(styleMaybeRemove(this._id, name)) : this.styleTween(name, styleConstant(name, i, value), priority).on("end.style." + name, null);
1780
1782
  }
1781
1783
  function styleInterpolate(name, i, priority) {
1782
- return function(t) {
1783
- this.style.setProperty(name, i.call(this, t), priority);
1784
+ return function(t2) {
1785
+ this.style.setProperty(name, i.call(this, t2), priority);
1784
1786
  };
1785
1787
  }
1786
1788
  function styleTween(name, value, priority) {
1787
- var t, i0;
1789
+ var t2, i0;
1788
1790
  function tween() {
1789
1791
  var i = value.apply(this, arguments);
1790
- return i !== i0 && (t = (i0 = i) && styleInterpolate(name, i, priority)), t;
1792
+ return i !== i0 && (t2 = (i0 = i) && styleInterpolate(name, i, priority)), t2;
1791
1793
  }
1792
1794
  return tween._value = value, tween;
1793
1795
  }
@@ -1816,8 +1818,8 @@ function transition_text(value) {
1816
1818
  return this.tween("text", typeof value == "function" ? textFunction(tweenValue(this, "text", value)) : textConstant(value == null ? "" : value + ""));
1817
1819
  }
1818
1820
  function textInterpolate(i) {
1819
- return function(t) {
1820
- this.textContent = i.call(this, t);
1821
+ return function(t2) {
1822
+ this.textContent = i.call(this, t2);
1821
1823
  };
1822
1824
  }
1823
1825
  function textTween(value) {
@@ -1904,8 +1906,8 @@ Transition.prototype = {
1904
1906
  end: transition_end,
1905
1907
  [Symbol.iterator]: selection_prototype[Symbol.iterator]
1906
1908
  };
1907
- function cubicInOut(t) {
1908
- return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
1909
+ function cubicInOut(t2) {
1910
+ return ((t2 *= 2) <= 1 ? t2 * t2 * t2 : (t2 -= 2) * t2 * t2 + 2) / 2;
1909
1911
  }
1910
1912
  var defaultTiming = {
1911
1913
  time: null,
@@ -2050,8 +2052,8 @@ function zoom() {
2050
2052
  }, null, event);
2051
2053
  }, zoom2.translateTo = function(selection2, x, y, p, event) {
2052
2054
  zoom2.transform(selection2, function() {
2053
- var e = extent.apply(this, arguments), t = this.__zoom, p0 = p == null ? centroid(e) : typeof p == "function" ? p.apply(this, arguments) : p;
2054
- return constrain(identity.translate(p0[0], p0[1]).scale(t.k).translate(
2055
+ var e = extent.apply(this, arguments), t2 = this.__zoom, p0 = p == null ? centroid(e) : typeof p == "function" ? p.apply(this, arguments) : p;
2056
+ return constrain(identity.translate(p0[0], p0[1]).scale(t2.k).translate(
2055
2057
  typeof x == "function" ? -x.apply(this, arguments) : -x,
2056
2058
  typeof y == "function" ? -y.apply(this, arguments) : -y
2057
2059
  ), e, translateExtent);
@@ -2074,14 +2076,14 @@ function zoom() {
2074
2076
  gesture(this, arguments).event(event).end();
2075
2077
  }).tween("zoom", function() {
2076
2078
  var that = this, args = arguments, g = gesture(that, args).event(event), e = extent.apply(that, args), p = point == null ? centroid(e) : typeof point == "function" ? point.apply(that, args) : point, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform2 == "function" ? transform2.apply(that, args) : transform2, i = interpolate2(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
2077
- return function(t) {
2078
- if (t === 1)
2079
- t = b;
2079
+ return function(t2) {
2080
+ if (t2 === 1)
2081
+ t2 = b;
2080
2082
  else {
2081
- var l = i(t), k = w / l[2];
2082
- t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
2083
+ var l = i(t2), k = w / l[2];
2084
+ t2 = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
2083
2085
  }
2084
- g.zoom(null, t);
2086
+ g.zoom(null, t2);
2085
2087
  };
2086
2088
  });
2087
2089
  }
@@ -2123,15 +2125,15 @@ function zoom() {
2123
2125
  function wheeled(event, ...args) {
2124
2126
  if (!filter2.apply(this, arguments))
2125
2127
  return;
2126
- var g = gesture(this, args).event(event), t = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta2.apply(this, arguments)))), p = pointer(event);
2128
+ var g = gesture(this, args).event(event), t2 = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t2.k * Math.pow(2, wheelDelta2.apply(this, arguments)))), p = pointer(event);
2127
2129
  if (g.wheel)
2128
- (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) && (g.mouse[1] = t.invert(g.mouse[0] = p)), clearTimeout(g.wheel);
2130
+ (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) && (g.mouse[1] = t2.invert(g.mouse[0] = p)), clearTimeout(g.wheel);
2129
2131
  else {
2130
- if (t.k === k)
2132
+ if (t2.k === k)
2131
2133
  return;
2132
- g.mouse = [p, t.invert(p)], interrupt(this), g.start();
2134
+ g.mouse = [p, t2.invert(p)], interrupt(this), g.start();
2133
2135
  }
2134
- noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2136
+ noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale(t2, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2135
2137
  function wheelidled() {
2136
2138
  g.wheel = null, g.end();
2137
2139
  }
@@ -2160,9 +2162,9 @@ function zoom() {
2160
2162
  }
2161
2163
  function touchstarted(event, ...args) {
2162
2164
  if (filter2.apply(this, arguments)) {
2163
- var touches = event.touches, n = touches.length, g = gesture(this, args, event.changedTouches.length === n).event(event), started, i, t, p;
2165
+ var touches = event.touches, n = touches.length, g = gesture(this, args, event.changedTouches.length === n).event(event), started, i, t2, p;
2164
2166
  for (nopropagation(event), i = 0; i < n; ++i)
2165
- t = touches[i], p = pointer(t, this), p = [p, this.__zoom.invert(p), t.identifier], g.touch0 ? !g.touch1 && g.touch0[2] !== p[2] && (g.touch1 = p, g.taps = 0) : (g.touch0 = p, started = !0, g.taps = 1 + !!touchstarting);
2167
+ t2 = touches[i], p = pointer(t2, this), p = [p, this.__zoom.invert(p), t2.identifier], g.touch0 ? !g.touch1 && g.touch0[2] !== p[2] && (g.touch1 = p, g.taps = 0) : (g.touch0 = p, started = !0, g.taps = 1 + !!touchstarting);
2166
2168
  touchstarting && (touchstarting = clearTimeout(touchstarting)), started && (g.taps < 2 && (touchfirst = p[0], touchstarting = setTimeout(function() {
2167
2169
  touchstarting = null;
2168
2170
  }, touchDelay)), interrupt(this), g.start());
@@ -2170,29 +2172,29 @@ function zoom() {
2170
2172
  }
2171
2173
  function touchmoved(event, ...args) {
2172
2174
  if (this.__zooming) {
2173
- var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t, p, l;
2175
+ var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t2, p, l;
2174
2176
  for (noevent(event), i = 0; i < n; ++i)
2175
- t = touches[i], p = pointer(t, this), g.touch0 && g.touch0[2] === t.identifier ? g.touch0[0] = p : g.touch1 && g.touch1[2] === t.identifier && (g.touch1[0] = p);
2176
- if (t = g.that.__zoom, g.touch1) {
2177
+ t2 = touches[i], p = pointer(t2, this), g.touch0 && g.touch0[2] === t2.identifier ? g.touch0[0] = p : g.touch1 && g.touch1[2] === t2.identifier && (g.touch1[0] = p);
2178
+ if (t2 = g.that.__zoom, g.touch1) {
2177
2179
  var p0 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
2178
- t = scale(t, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2180
+ t2 = scale(t2, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2179
2181
  } else if (g.touch0)
2180
2182
  p = g.touch0[0], l = g.touch0[1];
2181
2183
  else
2182
2184
  return;
2183
- g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));
2185
+ g.zoom("touch", constrain(translate(t2, p, l), g.extent, translateExtent));
2184
2186
  }
2185
2187
  }
2186
2188
  function touchended(event, ...args) {
2187
2189
  if (this.__zooming) {
2188
- var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t;
2190
+ var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t2;
2189
2191
  for (nopropagation(event), touchending && clearTimeout(touchending), touchending = setTimeout(function() {
2190
2192
  touchending = null;
2191
2193
  }, touchDelay), i = 0; i < n; ++i)
2192
- t = touches[i], g.touch0 && g.touch0[2] === t.identifier ? delete g.touch0 : g.touch1 && g.touch1[2] === t.identifier && delete g.touch1;
2194
+ t2 = touches[i], g.touch0 && g.touch0[2] === t2.identifier ? delete g.touch0 : g.touch1 && g.touch1[2] === t2.identifier && delete g.touch1;
2193
2195
  if (g.touch1 && !g.touch0 && (g.touch0 = g.touch1, delete g.touch1), g.touch0)
2194
2196
  g.touch0[1] = this.__zoom.invert(g.touch0[0]);
2195
- else if (g.end(), g.taps === 2 && (t = pointer(t, this), Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance)) {
2197
+ else if (g.end(), g.taps === 2 && (t2 = pointer(t2, this), Math.hypot(touchfirst[0] - t2[0], touchfirst[1] - t2[1]) < tapDistance)) {
2196
2198
  var p = select(this).on("dblclick.zoom");
2197
2199
  p && p.apply(this, arguments);
2198
2200
  }
@@ -2267,7 +2269,7 @@ var Position;
2267
2269
  (function(Position2) {
2268
2270
  Position2.Left = "left", Position2.Top = "top", Position2.Right = "right", Position2.Bottom = "bottom";
2269
2271
  })(Position || (Position = {}));
2270
- const isEdgeBase = (element) => "id" in element && "source" in element && "target" in element, isNodeBase = (element) => "id" in element && "position" in element && !("source" in element) && !("target" in element), getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
2272
+ const isEdgeBase = (element2) => "id" in element2 && "source" in element2 && "target" in element2, isNodeBase = (element2) => "id" in element2 && "position" in element2 && !("source" in element2) && !("target" in element2), getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
2271
2273
  const { width, height } = getNodeDimensions(node), positionAbsolute = "internals" in node ? node.internals.positionAbsolute : node.position, origin = node.origin || nodeOrigin, offsetX = width * origin[0], offsetY = height * origin[1];
2272
2274
  return {
2273
2275
  position: {
@@ -2385,10 +2387,10 @@ async function getElementsToRemove({ nodesToRemove = [], edgesToRemove = [], nod
2385
2387
  });
2386
2388
  return typeof onBeforeDeleteResult == "boolean" ? onBeforeDeleteResult ? { edges: matchingEdges, nodes: matchingNodes } : { edges: [], nodes: [] } : onBeforeDeleteResult;
2387
2389
  }
2388
- const clamp = (val, min = 0, max = 1) => Math.min(Math.max(val, min), max), clampPosition = (position = { x: 0, y: 0 }, extent) => ({
2390
+ const clamp = (val, min2 = 0, max2 = 1) => Math.min(Math.max(val, min2), max2), clampPosition = (position = { x: 0, y: 0 }, extent) => ({
2389
2391
  x: clamp(position.x, extent[0][0], extent[1][0]),
2390
2392
  y: clamp(position.y, extent[0][1], extent[1][1])
2391
- }), calcAutoPanVelocity = (value, min, max) => value < min ? clamp(Math.abs(value - min), 1, 50) / 50 : value > max ? -clamp(Math.abs(value - max), 1, 50) / 50 : 0, calcAutoPan = (pos, bounds) => {
2393
+ }), calcAutoPanVelocity = (value, min2, max2) => value < min2 ? clamp(Math.abs(value - min2), 1, 50) / 50 : value > max2 ? -clamp(Math.abs(value - max2), 1, 50) / 50 : 0, calcAutoPan = (pos, bounds) => {
2392
2394
  const xMovement = calcAutoPanVelocity(pos.x, 35, bounds.width - 35) * 20, yMovement = calcAutoPanVelocity(pos.y, 35, bounds.height - 35) * 20;
2393
2395
  return [xMovement, yMovement];
2394
2396
  }, getBoundsOfBoxes = (box1, box2) => ({
@@ -2487,9 +2489,9 @@ function getPointerPosition(event, { snapGrid = [0, 0], snapToGrid = !1, transfo
2487
2489
  const getDimensions = (node) => ({
2488
2490
  width: node.offsetWidth,
2489
2491
  height: node.offsetHeight
2490
- }), getHostForElement = (element) => {
2492
+ }), getHostForElement = (element2) => {
2491
2493
  var _a;
2492
- return ((_a = element.getRootNode) == null ? void 0 : _a.call(element)) || (window == null ? void 0 : window.document);
2494
+ return ((_a = element2.getRootNode) == null ? void 0 : _a.call(element2)) || (window == null ? void 0 : window.document);
2493
2495
  }, inputTags = ["INPUT", "SELECT", "TEXTAREA"];
2494
2496
  function isInputDOMNode(event) {
2495
2497
  var _a, _b;
@@ -3958,10 +3960,10 @@ function applyChanges(changes, elements) {
3958
3960
  const elementChanges = changesMap.get(change.id);
3959
3961
  elementChanges ? elementChanges.push(change) : changesMap.set(change.id, [change]);
3960
3962
  }
3961
- for (const element of elements) {
3962
- const changes2 = changesMap.get(element.id);
3963
+ for (const element2 of elements) {
3964
+ const changes2 = changesMap.get(element2.id);
3963
3965
  if (!changes2) {
3964
- updatedElements.push(element);
3966
+ updatedElements.push(element2);
3965
3967
  continue;
3966
3968
  }
3967
3969
  if (changes2[0].type === "remove")
@@ -3970,25 +3972,25 @@ function applyChanges(changes, elements) {
3970
3972
  updatedElements.push({ ...changes2[0].item });
3971
3973
  continue;
3972
3974
  }
3973
- const updatedElement = { ...element };
3975
+ const updatedElement = { ...element2 };
3974
3976
  for (const change of changes2)
3975
3977
  applyChange(change, updatedElement);
3976
3978
  updatedElements.push(updatedElement);
3977
3979
  }
3978
3980
  return updatedElements;
3979
3981
  }
3980
- function applyChange(change, element) {
3982
+ function applyChange(change, element2) {
3981
3983
  switch (change.type) {
3982
3984
  case "select": {
3983
- element.selected = change.selected;
3985
+ element2.selected = change.selected;
3984
3986
  break;
3985
3987
  }
3986
3988
  case "position": {
3987
- typeof change.position < "u" && (element.position = change.position), typeof change.dragging < "u" && (element.dragging = change.dragging);
3989
+ typeof change.position < "u" && (element2.position = change.position), typeof change.dragging < "u" && (element2.dragging = change.dragging);
3988
3990
  break;
3989
3991
  }
3990
3992
  case "dimensions": {
3991
- typeof change.dimensions < "u" && (element.measured ?? (element.measured = {}), element.measured.width = change.dimensions.width, element.measured.height = change.dimensions.height, change.setAttributes && (element.width = change.dimensions.width, element.height = change.dimensions.height)), typeof change.resizing == "boolean" && (element.resizing = change.resizing);
3993
+ typeof change.dimensions < "u" && (element2.measured ?? (element2.measured = {}), element2.measured.width = change.dimensions.width, element2.measured.height = change.dimensions.height, change.setAttributes && (element2.width = change.dimensions.width, element2.height = change.dimensions.height)), typeof change.resizing == "boolean" && (element2.resizing = change.resizing);
3992
3994
  break;
3993
3995
  }
3994
3996
  }
@@ -4031,7 +4033,7 @@ function elementToRemoveChange(item) {
4031
4033
  type: "remove"
4032
4034
  };
4033
4035
  }
4034
- const isNode = (element) => isNodeBase(element);
4036
+ const isNode = (element2) => isNodeBase(element2);
4035
4037
  function fixedForwardRef(render) {
4036
4038
  return forwardRef(render);
4037
4039
  }
@@ -4669,9 +4671,9 @@ function useVisibleNodeIds(onlyRenderVisible) {
4669
4671
  }
4670
4672
  const selector$e = (s) => s.updateNodeInternals;
4671
4673
  function useResizeObserver() {
4672
- const updateNodeInternals2 = useStore(selector$e), [resizeObserver] = useState(() => typeof ResizeObserver > "u" ? null : new ResizeObserver((entries) => {
4674
+ const updateNodeInternals2 = useStore(selector$e), [resizeObserver] = useState(() => typeof ResizeObserver > "u" ? null : new ResizeObserver((entries2) => {
4673
4675
  const updates = /* @__PURE__ */ new Map();
4674
- entries.forEach((entry) => {
4676
+ entries2.forEach((entry) => {
4675
4677
  const id2 = entry.target.getAttribute("data-id");
4676
4678
  updates.set(id2, {
4677
4679
  id: id2,
@@ -5481,6 +5483,16 @@ function EdgeLabelRenderer({ children: children2 }) {
5481
5483
  const edgeLabelRenderer = useStore(selector$8);
5482
5484
  return edgeLabelRenderer ? createPortal(children2, edgeLabelRenderer) : null;
5483
5485
  }
5486
+ function useOnViewportChange({ onStart, onChange, onEnd }) {
5487
+ const store = useStoreApi();
5488
+ useEffect(() => {
5489
+ store.setState({ onViewportChangeStart: onStart });
5490
+ }, [onStart]), useEffect(() => {
5491
+ store.setState({ onViewportChange: onChange });
5492
+ }, [onChange]), useEffect(() => {
5493
+ store.setState({ onViewportChangeEnd: onEnd });
5494
+ }, [onEnd]);
5495
+ }
5484
5496
  function useOnSelectionChange({ onChange }) {
5485
5497
  const store = useStoreApi();
5486
5498
  useEffect(() => {
@@ -5491,19 +5503,6 @@ function useOnSelectionChange({ onChange }) {
5491
5503
  };
5492
5504
  }, [onChange]);
5493
5505
  }
5494
- const selector$6 = (options) => (s) => {
5495
- if (s.nodeLookup.size === 0)
5496
- return !1;
5497
- for (const [, { hidden, internals }] of s.nodeLookup)
5498
- if ((options.includeHiddenNodes || !hidden) && (internals.handleBounds === void 0 || !nodeHasDimensions(internals.userNode)))
5499
- return !1;
5500
- return !0;
5501
- }, defaultOptions = {
5502
- includeHiddenNodes: !1
5503
- };
5504
- function useNodesInitialized(options = defaultOptions) {
5505
- return useStore(selector$6(options));
5506
- }
5507
5506
  function useNodesData(nodeIds) {
5508
5507
  return useStore(useCallback((s) => {
5509
5508
  const data = [], isArrayOfIds = Array.isArray(nodeIds), _nodeIds = isArrayOfIds ? nodeIds : [nodeIds];
@@ -5607,7 +5606,7 @@ function MiniMapNodeComponent({ id: id2, x, y, width, height, style: style2, col
5607
5606
  strokeWidth
5608
5607
  }, shapeRendering, onClick: onClick ? (event) => onClick(event, id2) : void 0 });
5609
5608
  }
5610
- const MiniMapNode = memo(MiniMapNodeComponent), selector$2 = (s) => s.nodeOrigin, selectorNodeIds = (s) => s.nodes.map((node) => node.id), getAttrFunction = (func) => func instanceof Function ? func : () => func;
5609
+ const MiniMapNode = memo(MiniMapNodeComponent), selector$2$1 = (s) => s.nodeOrigin, selectorNodeIds = (s) => s.nodes.map((node) => node.id), getAttrFunction = (func) => func instanceof Function ? func : () => func;
5611
5610
  function MiniMapNodes({
5612
5611
  nodeStrokeColor,
5613
5612
  nodeColor,
@@ -5619,7 +5618,7 @@ function MiniMapNodes({
5619
5618
  nodeComponent: NodeComponent = MiniMapNode,
5620
5619
  onClick
5621
5620
  }) {
5622
- const nodeIds = useStore(selectorNodeIds, shallow), nodeOrigin = useStore(selector$2), nodeColorFunc = getAttrFunction(nodeColor), nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor), nodeClassNameFunc = getAttrFunction(nodeClassName), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision";
5621
+ const nodeIds = useStore(selectorNodeIds, shallow), nodeOrigin = useStore(selector$2$1), nodeColorFunc = getAttrFunction(nodeColor), nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor), nodeClassNameFunc = getAttrFunction(nodeClassName), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision";
5623
5622
  return jsx(Fragment, { children: nodeIds.map((nodeId) => (
5624
5623
  // The split of responsibilities between MiniMapNodes and
5625
5624
  // NodeComponentWrapper may appear weird. However, it’s designed to
@@ -5645,7 +5644,7 @@ function NodeComponentWrapperInner({ id: id2, nodeOrigin, nodeColorFunc, nodeStr
5645
5644
  }
5646
5645
  const NodeComponentWrapper = memo(NodeComponentWrapperInner);
5647
5646
  var MiniMapNodes$1 = memo(MiniMapNodes);
5648
- const defaultWidth = 200, defaultHeight = 150, selector$1 = (s) => {
5647
+ const defaultWidth = 200, defaultHeight = 150, selector$1$1 = (s) => {
5649
5648
  const viewBB = {
5650
5649
  x: -s.transform[0] / s.transform[2],
5651
5650
  y: -s.transform[1] / s.transform[2],
@@ -5688,7 +5687,7 @@ function MiniMapComponent({
5688
5687
  zoomStep = 10,
5689
5688
  offsetScale = 5
5690
5689
  }) {
5691
- const store = useStoreApi(), svg = useRef(null), { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1, shallow), elementWidth = (style2 == null ? void 0 : style2.width) ?? defaultWidth, elementHeight = (style2 == null ? void 0 : style2.height) ?? defaultHeight, scaledWidth = boundingRect.width / elementWidth, scaledHeight = boundingRect.height / elementHeight, viewScale = Math.max(scaledWidth, scaledHeight), viewWidth = viewScale * elementWidth, viewHeight = viewScale * elementHeight, offset = offsetScale * viewScale, x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset, y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset, width = viewWidth + offset * 2, height = viewHeight + offset * 2, labelledBy = `${ARIA_LABEL_KEY}-${rfId}`, viewScaleRef = useRef(0), minimapInstance = useRef();
5690
+ const store = useStoreApi(), svg = useRef(null), { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1$1, shallow), elementWidth = (style2 == null ? void 0 : style2.width) ?? defaultWidth, elementHeight = (style2 == null ? void 0 : style2.height) ?? defaultHeight, scaledWidth = boundingRect.width / elementWidth, scaledHeight = boundingRect.height / elementHeight, viewScale = Math.max(scaledWidth, scaledHeight), viewWidth = viewScale * elementWidth, viewHeight = viewScale * elementHeight, offset = offsetScale * viewScale, x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset, y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset, width = viewWidth + offset * 2, height = viewHeight + offset * 2, labelledBy = `${ARIA_LABEL_KEY}-${rfId}`, viewScaleRef = useRef(0), minimapInstance = useRef();
5692
5691
  viewScaleRef.current = viewScale, useEffect(() => {
5693
5692
  if (svg.current && panZoom)
5694
5693
  return minimapInstance.current = XYMinimap({
@@ -5840,25 +5839,25 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
5840
5839
  }
5841
5840
  memo(ResizeControl);
5842
5841
  function r(e) {
5843
- var t, f, n = "";
5842
+ var t2, f, n = "";
5844
5843
  if (typeof e == "string" || typeof e == "number")
5845
5844
  n += e;
5846
5845
  else if (typeof e == "object")
5847
5846
  if (Array.isArray(e)) {
5848
5847
  var o = e.length;
5849
- for (t = 0; t < o; t++)
5850
- e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
5848
+ for (t2 = 0; t2 < o; t2++)
5849
+ e[t2] && (f = r(e[t2])) && (n && (n += " "), n += f);
5851
5850
  } else
5852
5851
  for (f in e)
5853
5852
  e[f] && (n && (n += " "), n += f);
5854
5853
  return n;
5855
5854
  }
5856
5855
  function clsx() {
5857
- for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++)
5858
- (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
5856
+ for (var e, t2, f = 0, n = "", o = arguments.length; f < o; f++)
5857
+ (e = arguments[f]) && (t2 = r(e)) && (n && (n += " "), n += t2);
5859
5858
  return n;
5860
5859
  }
5861
- var keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5860
+ var rootClassName = "likec4-diagram-root", keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5862
5861
  function KeepAspectRatioContainer({
5863
5862
  children: children2,
5864
5863
  width,
@@ -5876,7 +5875,7 @@ function KeepAspectRatioContainer({
5876
5875
  style: enabled ? {
5877
5876
  ...style2,
5878
5877
  aspectRatio: `${Math.ceil(width)}/${Math.ceil(height)}`,
5879
- maxHeight: Math.ceil(height)
5878
+ maxHeight: `var(--likec4-view-max-height, ${Math.ceil(height)}px)`
5880
5879
  } : style2,
5881
5880
  children: children2
5882
5881
  }
@@ -5995,8 +5994,8 @@ class IndexedMap {
5995
5994
  if (i === void 0)
5996
5995
  return;
5997
5996
  this.index[key.id()] = void 0;
5998
- const pair = this.array[i], last = this.array.pop();
5999
- return pair !== last && (this.array[i] = last, this.index[last.first.id()] = i), pair;
5997
+ const pair = this.array[i], last2 = this.array.pop();
5998
+ return pair !== last2 && (this.array[i] = last2, this.index[last2.first.id()] = i), pair;
6000
5999
  }
6001
6000
  /**
6002
6001
  * Create a copy of this associative array.
@@ -6017,10 +6016,10 @@ class Pair {
6017
6016
  * @param first The first item of the pair.
6018
6017
  * @param second The second item of the pair.
6019
6018
  */
6020
- constructor(first, second) {
6019
+ constructor(first2, second) {
6021
6020
  __publicField(this, "first");
6022
6021
  __publicField(this, "second");
6023
- this.first = first, this.second = second;
6022
+ this.first = first2, this.second = second;
6024
6023
  }
6025
6024
  /**
6026
6025
  * Create a copy of the pair.
@@ -6434,7 +6433,7 @@ class Solver {
6434
6433
  * @return {Constraint[]}
6435
6434
  */
6436
6435
  getConstraints() {
6437
- return this._cnMap.array.map(({ first }) => first);
6436
+ return this._cnMap.array.map(({ first: first2 }) => first2);
6438
6437
  }
6439
6438
  /**
6440
6439
  * Add an edit variable to the solver.
@@ -6771,7 +6770,7 @@ class Solver {
6771
6770
  * @private
6772
6771
  */
6773
6772
  _getMarkerLeavingSymbol(marker) {
6774
- let dmax = Number.MAX_VALUE, r1 = dmax, r2 = dmax, invalid = INVALID_SYMBOL, first = invalid, second = invalid, third = invalid, rows = this._rowMap;
6773
+ let dmax = Number.MAX_VALUE, r1 = dmax, r2 = dmax, invalid = INVALID_SYMBOL, first2 = invalid, second = invalid, third = invalid, rows = this._rowMap;
6775
6774
  for (let i = 0, n = rows.size(); i < n; ++i) {
6776
6775
  let pair = rows.itemAt(i), row = pair.second, c = row.coefficientFor(marker);
6777
6776
  if (c === 0)
@@ -6781,13 +6780,13 @@ class Solver {
6781
6780
  third = symbol;
6782
6781
  else if (c < 0) {
6783
6782
  let r3 = -row.constant() / c;
6784
- r3 < r1 && (r1 = r3, first = symbol);
6783
+ r3 < r1 && (r1 = r3, first2 = symbol);
6785
6784
  } else {
6786
6785
  let r3 = row.constant() / c;
6787
6786
  r3 < r2 && (r2 = r3, second = symbol);
6788
6787
  }
6789
6788
  }
6790
- return first !== invalid ? first : second !== invalid ? second : third;
6789
+ return first2 !== invalid ? first2 : second !== invalid ? second : third;
6791
6790
  }
6792
6791
  /**
6793
6792
  * Remove the effects of a constraint on the objective function.
@@ -7220,15 +7219,18 @@ const ZIndexes = {
7220
7219
  Compound: 1,
7221
7220
  Edge: 2,
7222
7221
  Element: 3
7223
- }, MinZoom = 0.05, DEFAULT_PROPS = {
7222
+ }, MinZoom = 0.05, StringSet = Set, DEFAULT_PROPS = {
7224
7223
  initialized: !1,
7224
+ xyflowSynced: !1,
7225
7225
  previousViews: [],
7226
7226
  viewportChanged: !1,
7227
+ activeDynamicViewStep: null,
7227
7228
  focusedNodeId: null,
7228
7229
  hoveredNodeId: null,
7229
7230
  hoveredEdgeId: null,
7230
7231
  lastClickedNodeId: null,
7231
7232
  lastClickedEdgeId: null,
7233
+ dimmed: new StringSet(),
7232
7234
  lastOnNavigate: null,
7233
7235
  onChange: null,
7234
7236
  onNavigateTo: null,
@@ -7241,7 +7243,7 @@ const ZIndexes = {
7241
7243
  onCanvasDblClick: null
7242
7244
  }, noReplace = !1;
7243
7245
  let storeDevId = 1;
7244
- const containsWithId = (arr, id2) => arr.some((x) => x.id === id2);
7246
+ const EmptyStringSet = new StringSet();
7245
7247
  function createDiagramStore(props) {
7246
7248
  return createWithEqualityFn(
7247
7249
  subscribeWithSelector(
@@ -7249,39 +7251,76 @@ function createDiagramStore(props) {
7249
7251
  (set2, get2) => ({
7250
7252
  ...DEFAULT_PROPS,
7251
7253
  ...props,
7252
- updateView: (view) => {
7254
+ isDynamicView: () => {
7255
+ var _a;
7256
+ return ((_a = get2().view) == null ? void 0 : _a.__) === "dynamic";
7257
+ },
7258
+ updateView: (nextView) => {
7253
7259
  let {
7254
- view: currentView,
7260
+ dimmed: dimmed2,
7261
+ xyflowSynced,
7262
+ view: current,
7255
7263
  lastOnNavigate,
7256
7264
  previousViews,
7257
7265
  focusedNodeId,
7258
7266
  lastClickedNodeId,
7259
7267
  lastClickedEdgeId,
7268
+ activeDynamicViewStep,
7260
7269
  hoveredEdgeId,
7261
7270
  hoveredNodeId
7262
7271
  } = get2();
7263
- if (shallowEqual(currentView, view)) {
7264
- DEV && console.debug("store: skip updateView");
7272
+ if (shallowEqual(current, nextView)) {
7273
+ xyflowSynced || set2({ xyflowSynced: !0 }, noReplace, "updateView: xyflow synced"), DEV && console.debug("store: skip updateView");
7265
7274
  return;
7266
7275
  }
7267
- lastOnNavigate && lastOnNavigate.toView !== view.id && lastOnNavigate.fromView !== view.id && (lastOnNavigate = null), currentView.id === view.id ? (lastClickedNodeId && !containsWithId(view.nodes, lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !containsWithId(view.nodes, hoveredNodeId) && (hoveredNodeId = null), focusedNodeId && !containsWithId(view.nodes, focusedNodeId) && (focusedNodeId = null), lastClickedEdgeId && !containsWithId(view.edges, lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !containsWithId(view.edges, hoveredEdgeId) && (hoveredEdgeId = null)) : (lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, previousViews = [
7268
- currentView,
7269
- ...previousViews.filter((v) => v.id !== view.id && v.id !== currentView.id)
7270
- ]), set2(
7276
+ if (current.id === nextView.id) {
7277
+ const nodeIds = new StringSet(nextView.nodes.map((n) => n.id)), edgeIds = new StringSet(nextView.edges.map((e) => e.id));
7278
+ if (lastClickedNodeId && !nodeIds.has(lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !nodeIds.has(hoveredNodeId) && (hoveredNodeId = null), focusedNodeId && !nodeIds.has(focusedNodeId) && (focusedNodeId = null), lastClickedEdgeId && !edgeIds.has(lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !edgeIds.has(hoveredEdgeId) && (hoveredEdgeId = null), activeDynamicViewStep && !edgeIds.has(StepEdgeId(activeDynamicViewStep)) && (activeDynamicViewStep = null), xyflowSynced = deepEqual(current.nodes, nextView.nodes) && deepEqual(current.edges, nextView.edges), !xyflowSynced) {
7279
+ let nextDimmed = new StringSet([...dimmed2].filter((id2) => nodeIds.has(id2) || edgeIds.has(id2)));
7280
+ nextDimmed.size !== dimmed2.size && (dimmed2 = nextDimmed);
7281
+ }
7282
+ } else
7283
+ lastOnNavigate && lastOnNavigate.toView !== nextView.id && lastOnNavigate.fromView !== nextView.id && (lastOnNavigate = null), lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, activeDynamicViewStep = null, dimmed2 = EmptyStringSet, previousViews = [
7284
+ current,
7285
+ ...previousViews.filter((v) => v.id !== nextView.id && v.id !== current.id)
7286
+ ], xyflowSynced = !1;
7287
+ set2(
7271
7288
  {
7272
- view,
7289
+ view: nextView,
7290
+ activeDynamicViewStep,
7291
+ xyflowSynced,
7273
7292
  lastOnNavigate,
7274
7293
  previousViews,
7275
7294
  lastClickedNodeId,
7276
7295
  lastClickedEdgeId,
7277
7296
  focusedNodeId,
7278
7297
  hoveredEdgeId,
7279
- hoveredNodeId
7298
+ hoveredNodeId,
7299
+ dimmed: dimmed2
7280
7300
  },
7281
7301
  noReplace,
7282
7302
  "update-view"
7283
7303
  );
7284
7304
  },
7305
+ focusOnNode: (nodeId) => {
7306
+ const { focusedNodeId, view } = get2();
7307
+ if (nodeId !== focusedNodeId) {
7308
+ const notDimmed = new StringSet([nodeId]), dimmed2 = new StringSet();
7309
+ for (const edge of view.edges)
7310
+ edge.source === nodeId || edge.target === nodeId ? (notDimmed.add(edge.source), notDimmed.add(edge.target)) : dimmed2.add(edge.id);
7311
+ for (const node of view.nodes)
7312
+ notDimmed.has(node.id) || dimmed2.add(node.id);
7313
+ set2(
7314
+ {
7315
+ activeDynamicViewStep: null,
7316
+ focusedNodeId: nodeId,
7317
+ dimmed: dimmed2
7318
+ },
7319
+ noReplace,
7320
+ `focus on node: ${nodeId}`
7321
+ );
7322
+ }
7323
+ },
7285
7324
  setHoveredNode: (nodeId) => {
7286
7325
  nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId }, noReplace, nodeId ? "setHoveredNode" : "unsetHoveredNode");
7287
7326
  },
@@ -7294,66 +7333,103 @@ function createDiagramStore(props) {
7294
7333
  setLastClickedEdge: (edgeId) => {
7295
7334
  edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId }, noReplace, edgeId ? "setLastClickedEdge" : "unsetLastClickedEdge");
7296
7335
  },
7336
+ resetLastClicked: () => {
7337
+ let {
7338
+ focusedNodeId,
7339
+ lastClickedNodeId,
7340
+ lastClickedEdgeId
7341
+ } = get2();
7342
+ (focusedNodeId || lastClickedNodeId || lastClickedEdgeId) && set2(
7343
+ {
7344
+ focusedNodeId: null,
7345
+ lastClickedNodeId: null,
7346
+ lastClickedEdgeId: null,
7347
+ dimmed: EmptyStringSet
7348
+ },
7349
+ noReplace,
7350
+ "resetLastClicked"
7351
+ );
7352
+ },
7297
7353
  getElement: (fqn) => {
7298
7354
  const { view } = get2();
7299
7355
  return view.nodes.find(({ id: id2 }) => id2 === fqn) ?? null;
7300
7356
  },
7301
7357
  triggerOnChange: (changes) => {
7302
7358
  var _a, _b;
7303
- const newShapes = /* @__PURE__ */ new Map(), newColor = /* @__PURE__ */ new Map();
7359
+ DEV && console.debug("triggerOnChange", changes);
7360
+ const newShapes = /* @__PURE__ */ new Map(), newColor = /* @__PURE__ */ new Map(), newOpacity = /* @__PURE__ */ new Map(), newBorder = /* @__PURE__ */ new Map();
7304
7361
  for (const change of changes) {
7305
- if (change.op === "change-shape") {
7306
- for (const target of change.targets)
7307
- newShapes.set(target, change.shape);
7308
- continue;
7309
- }
7310
- if (change.op === "change-color") {
7311
- for (const target of change.targets)
7312
- newColor.set(target, change.color);
7313
- continue;
7314
- }
7315
- nonexhaustive(change);
7362
+ change.op !== "change-element-style" && nonexhaustive(change.op);
7363
+ for (const target of change.targets)
7364
+ for (const [key, value] of entries.strict(change.style))
7365
+ switch (key) {
7366
+ case "shape":
7367
+ newShapes.set(target, value);
7368
+ break;
7369
+ case "color":
7370
+ newColor.set(target, value);
7371
+ break;
7372
+ case "opacity":
7373
+ newOpacity.set(target, value);
7374
+ break;
7375
+ case "border":
7376
+ newBorder.set(target, value);
7377
+ break;
7378
+ default:
7379
+ nonexhaustive(key);
7380
+ }
7316
7381
  }
7317
7382
  get2().xyflow.setNodes(
7318
7383
  (nodes) => nodes.map((node) => {
7319
- let { data } = node;
7320
- const shape = newShapes.get(data.fqn);
7321
- shape && shape !== data.element.shape && (node = {
7322
- ...node,
7323
- data: {
7324
- ...data,
7325
- element: {
7326
- ...data.element,
7327
- shape
7328
- }
7384
+ var _a2, _b2;
7385
+ let element2 = node.data.element;
7386
+ const shape = newShapes.get(element2.id);
7387
+ shape && shape !== element2.shape && (element2 = {
7388
+ ...element2,
7389
+ shape
7390
+ });
7391
+ const color2 = newColor.get(element2.id);
7392
+ color2 && color2 !== element2.color && (element2 = {
7393
+ ...element2,
7394
+ color: color2
7395
+ });
7396
+ const opacity = newOpacity.get(element2.id);
7397
+ opacity && opacity !== ((_a2 = element2.style) == null ? void 0 : _a2.opacity) && (element2 = {
7398
+ ...element2,
7399
+ style: {
7400
+ ...element2.style,
7401
+ opacity
7402
+ }
7403
+ });
7404
+ const border = newBorder.get(element2.id);
7405
+ return border && border !== ((_b2 = element2.style) == null ? void 0 : _b2.border) && (element2 = {
7406
+ ...element2,
7407
+ style: {
7408
+ ...element2.style,
7409
+ border
7329
7410
  }
7330
- }, data = node.data);
7331
- const color2 = newColor.get(data.fqn);
7332
- return color2 && color2 !== data.element.color && (node = {
7411
+ }), element2 === node.data.element ? node : {
7333
7412
  ...node,
7334
7413
  data: {
7335
- ...data,
7336
- element: {
7337
- ...data.element,
7338
- color: color2
7339
- }
7414
+ ...node.data,
7415
+ element: element2
7340
7416
  }
7341
- }), node;
7417
+ };
7342
7418
  })
7343
7419
  ), (_b = (_a = get2()).onChange) == null || _b.call(_a, { changes });
7344
7420
  },
7345
7421
  triggerOnNavigateTo: (xynodeId, event) => {
7346
7422
  var _a, _b;
7347
- const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element = xynode == null ? void 0 : xynode.data.element;
7348
- invariant(!!xynode && (element == null ? void 0 : element.navigateTo), `node is not navigable: ${xynodeId}`);
7423
+ const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element2 = xynode == null ? void 0 : xynode.data.element;
7424
+ invariant(!!xynode && (element2 == null ? void 0 : element2.navigateTo), `node is not navigable: ${xynodeId}`);
7349
7425
  const dimensions = getNodeDimensions(xynode);
7350
7426
  set2(
7351
7427
  {
7352
7428
  lastClickedNodeId: xynodeId,
7353
7429
  lastOnNavigate: {
7354
7430
  fromView: view.id,
7355
- toView: element.navigateTo,
7356
- element,
7431
+ toView: element2.navigateTo,
7432
+ element: element2,
7357
7433
  elementCenterScreenPosition: xyflow.flowToScreenPosition({
7358
7434
  x: xynode.internals.positionAbsolute.x + dimensions.width / 2,
7359
7435
  y: xynode.internals.positionAbsolute.y + dimensions.height / 2
@@ -7365,22 +7441,72 @@ function createDiagramStore(props) {
7365
7441
  "triggerOnNavigateTo"
7366
7442
  ), (_b = (_a = get2()).onNavigateTo) == null || _b.call(
7367
7443
  _a,
7368
- element.navigateTo,
7444
+ element2.navigateTo,
7369
7445
  event,
7370
- element,
7446
+ element2,
7371
7447
  xynode.internals.userNode
7372
7448
  );
7373
7449
  },
7374
- fitDiagram: (centerNode) => {
7375
- const { fitViewPadding, xyflow, focusedNodeId } = get2();
7450
+ fitDiagram: (xyStore) => {
7451
+ const { width, height, panZoom } = xyStore.getState(), { fitViewPadding, view, focusedNodeId } = get2(), bounds = {
7452
+ x: 0,
7453
+ y: 0,
7454
+ width: view.width,
7455
+ height: view.height
7456
+ }, viewport = getViewportForBounds(bounds, width, height, MinZoom, 1, fitViewPadding);
7457
+ panZoom == null || panZoom.setViewport(viewport, { duration: 400 }), focusedNodeId && set2(
7458
+ {
7459
+ focusedNodeId: null,
7460
+ dimmed: EmptyStringSet
7461
+ },
7462
+ noReplace,
7463
+ "unfocus"
7464
+ );
7465
+ },
7466
+ nextDynamicStep: (increment = 1) => {
7467
+ const { view, activeDynamicViewStep, xyflow, fitViewPadding } = get2();
7468
+ invariant(view.__ === "dynamic", "view is not dynamic");
7469
+ const nextStep = (activeDynamicViewStep ?? 0) + increment, edgeId = StepEdgeId(nextStep), dimmed2 = new StringSet();
7470
+ let edge = null;
7471
+ for (const e of xyflow.getEdges()) {
7472
+ if (e.id === edgeId) {
7473
+ edge = e;
7474
+ continue;
7475
+ }
7476
+ dimmed2.add(e.id);
7477
+ }
7478
+ invariant(!!edge, `edge not found: ${edgeId}`);
7479
+ const selected2 = [];
7480
+ for (const n of xyflow.getNodes()) {
7481
+ if (n.id === edge.source || n.id === edge.target) {
7482
+ selected2.push(n);
7483
+ continue;
7484
+ }
7485
+ dimmed2.add(n.id);
7486
+ }
7376
7487
  xyflow.fitView({
7377
- includeHiddenNodes: !0,
7378
- duration: centerNode && focusedNodeId ? 300 : 400,
7379
- padding: centerNode ? 0 : fitViewPadding,
7488
+ duration: 400,
7489
+ maxZoom: 1,
7380
7490
  minZoom: MinZoom,
7491
+ padding: fitViewPadding,
7492
+ nodes: selected2
7493
+ }), set2({
7494
+ focusedNodeId: null,
7495
+ activeDynamicViewStep: nextStep,
7496
+ dimmed: dimmed2
7497
+ });
7498
+ },
7499
+ stopDynamicView: () => {
7500
+ const { xyflow, fitViewPadding } = get2();
7501
+ set2({
7502
+ activeDynamicViewStep: null,
7503
+ dimmed: EmptyStringSet
7504
+ }), xyflow.fitView({
7505
+ duration: 400,
7381
7506
  maxZoom: 1,
7382
- ...centerNode && { nodes: [centerNode] }
7383
- }), centerNode && focusedNodeId !== centerNode.id && set2({ focusedNodeId: centerNode.id }, noReplace, "focus node"), !centerNode && focusedNodeId && set2({ focusedNodeId: null }, noReplace, "unfocus");
7507
+ minZoom: MinZoom,
7508
+ padding: fitViewPadding
7509
+ });
7384
7510
  }
7385
7511
  }),
7386
7512
  {
@@ -7399,211 +7525,966 @@ function DiagramContextProvider({ children: children2, view, ...props }) {
7399
7525
  xyflow,
7400
7526
  view,
7401
7527
  ...props
7402
- })), useUpdateEffect(
7403
- () => {
7404
- var _a;
7405
- return (_a = store.current) == null ? void 0 : _a.setState({ xyflow }, !1, "update xyflow");
7406
- },
7407
- [xyflow],
7408
- Object.is
7409
- ), useUpdateEffect(
7528
+ })), useEffect(
7410
7529
  () => {
7411
- var _a;
7412
- return (_a = store.current) == null ? void 0 : _a.getState().updateView(view);
7530
+ var _a, _b;
7531
+ ((_a = store.current) == null ? void 0 : _a.getState().xyflow) !== xyflow && ((_b = store.current) == null || _b.setState({ xyflow }, !1, "update xyflow"));
7413
7532
  },
7414
- [view]
7533
+ [xyflow]
7415
7534
  ), useUpdateEffect(
7416
7535
  () => {
7417
- var _a;
7418
- return (_a = store.current) == null ? void 0 : _a.setState(props, !1, "update incoming props");
7536
+ if (!store.current)
7537
+ return;
7538
+ const state = store.current.getState();
7539
+ state.view !== view && state.updateView(view), hasSubObject(state, props) || store.current.setState(props, !1, "update incoming props");
7419
7540
  },
7420
- [props]
7541
+ [view, props]
7421
7542
  ), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
7422
7543
  }
7423
- const {
7424
- primary,
7425
- secondary,
7426
- muted,
7427
- ...otherColors
7428
- } = defaultTheme.elements, themedColors = [
7429
- { key: "primary", value: primary.fill },
7430
- { key: "secondary", value: secondary.fill },
7431
- { key: "muted", value: muted.fill }
7432
- ], colors = keys.strict(otherColors).map((key) => ({
7433
- key,
7434
- value: defaultTheme.elements[key].fill
7435
- }));
7436
- function NodeOptions({ selectedNodeIds }) {
7437
- const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
7438
- if (!hasAtLeast(nodes, 1))
7439
- return null;
7440
- const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes;
7441
- return /* @__PURE__ */ jsxs(Stack, { children: [
7442
- /* @__PURE__ */ jsx(Box, { maw: 200, children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
7443
- showShapeOption && /* @__PURE__ */ jsx(
7444
- ShapeOption,
7544
+ const { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
7545
+ function crt(v) {
7546
+ return v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);
7547
+ }
7548
+ const pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = Number.MAX_SAFE_INTEGER || 9007199254740991, nMin = Number.MIN_SAFE_INTEGER || -9007199254740991, ZERO = { x: 0, y: 0, z: 0 }, utils = {
7549
+ // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
7550
+ Tvalues: [
7551
+ -0.06405689286260563,
7552
+ 0.06405689286260563,
7553
+ -0.1911188674736163,
7554
+ 0.1911188674736163,
7555
+ -0.3150426796961634,
7556
+ 0.3150426796961634,
7557
+ -0.4337935076260451,
7558
+ 0.4337935076260451,
7559
+ -0.5454214713888396,
7560
+ 0.5454214713888396,
7561
+ -0.6480936519369755,
7562
+ 0.6480936519369755,
7563
+ -0.7401241915785544,
7564
+ 0.7401241915785544,
7565
+ -0.820001985973903,
7566
+ 0.820001985973903,
7567
+ -0.8864155270044011,
7568
+ 0.8864155270044011,
7569
+ -0.9382745520027328,
7570
+ 0.9382745520027328,
7571
+ -0.9747285559713095,
7572
+ 0.9747285559713095,
7573
+ -0.9951872199970213,
7574
+ 0.9951872199970213
7575
+ ],
7576
+ // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article)
7577
+ Cvalues: [
7578
+ 0.12793819534675216,
7579
+ 0.12793819534675216,
7580
+ 0.1258374563468283,
7581
+ 0.1258374563468283,
7582
+ 0.12167047292780339,
7583
+ 0.12167047292780339,
7584
+ 0.1155056680537256,
7585
+ 0.1155056680537256,
7586
+ 0.10744427011596563,
7587
+ 0.10744427011596563,
7588
+ 0.09761865210411388,
7589
+ 0.09761865210411388,
7590
+ 0.08619016153195327,
7591
+ 0.08619016153195327,
7592
+ 0.0733464814110803,
7593
+ 0.0733464814110803,
7594
+ 0.05929858491543678,
7595
+ 0.05929858491543678,
7596
+ 0.04427743881741981,
7597
+ 0.04427743881741981,
7598
+ 0.028531388628933663,
7599
+ 0.028531388628933663,
7600
+ 0.0123412297999872,
7601
+ 0.0123412297999872
7602
+ ],
7603
+ arcfn: function(t2, derivativeFn) {
7604
+ const d = derivativeFn(t2);
7605
+ let l = d.x * d.x + d.y * d.y;
7606
+ return typeof d.z < "u" && (l += d.z * d.z), sqrt$1(l);
7607
+ },
7608
+ compute: function(t2, points, _3d) {
7609
+ if (t2 === 0)
7610
+ return points[0].t = 0, points[0];
7611
+ const order = points.length - 1;
7612
+ if (t2 === 1)
7613
+ return points[order].t = 1, points[order];
7614
+ const mt = 1 - t2;
7615
+ let p = points;
7616
+ if (order === 0)
7617
+ return points[0].t = t2, points[0];
7618
+ if (order === 1) {
7619
+ const ret = {
7620
+ x: mt * p[0].x + t2 * p[1].x,
7621
+ y: mt * p[0].y + t2 * p[1].y,
7622
+ t: t2
7623
+ };
7624
+ return _3d && (ret.z = mt * p[0].z + t2 * p[1].z), ret;
7625
+ }
7626
+ if (order < 4) {
7627
+ let mt2 = mt * mt, t22 = t2 * t2, a, b, c, d = 0;
7628
+ order === 2 ? (p = [p[0], p[1], p[2], ZERO], a = mt2, b = mt * t2 * 2, c = t22) : order === 3 && (a = mt2 * mt, b = mt2 * t2 * 3, c = mt * t22 * 3, d = t2 * t22);
7629
+ const ret = {
7630
+ x: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,
7631
+ y: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,
7632
+ t: t2
7633
+ };
7634
+ return _3d && (ret.z = a * p[0].z + b * p[1].z + c * p[2].z + d * p[3].z), ret;
7635
+ }
7636
+ const dCpts = JSON.parse(JSON.stringify(points));
7637
+ for (; dCpts.length > 1; ) {
7638
+ for (let i = 0; i < dCpts.length - 1; i++)
7639
+ dCpts[i] = {
7640
+ x: dCpts[i].x + (dCpts[i + 1].x - dCpts[i].x) * t2,
7641
+ y: dCpts[i].y + (dCpts[i + 1].y - dCpts[i].y) * t2
7642
+ }, typeof dCpts[i].z < "u" && (dCpts[i].z = dCpts[i].z + (dCpts[i + 1].z - dCpts[i].z) * t2);
7643
+ dCpts.splice(dCpts.length - 1, 1);
7644
+ }
7645
+ return dCpts[0].t = t2, dCpts[0];
7646
+ },
7647
+ computeWithRatios: function(t2, points, ratios, _3d) {
7648
+ const mt = 1 - t2, r2 = ratios, p = points;
7649
+ let f1 = r2[0], f2 = r2[1], f3 = r2[2], f4 = r2[3], d;
7650
+ if (f1 *= mt, f2 *= t2, p.length === 2)
7651
+ return d = f1 + f2, {
7652
+ x: (f1 * p[0].x + f2 * p[1].x) / d,
7653
+ y: (f1 * p[0].y + f2 * p[1].y) / d,
7654
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z) / d : !1,
7655
+ t: t2
7656
+ };
7657
+ if (f1 *= mt, f2 *= 2 * mt, f3 *= t2 * t2, p.length === 3)
7658
+ return d = f1 + f2 + f3, {
7659
+ x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x) / d,
7660
+ y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y) / d,
7661
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z) / d : !1,
7662
+ t: t2
7663
+ };
7664
+ if (f1 *= mt, f2 *= 1.5 * mt, f3 *= 3 * mt, f4 *= t2 * t2 * t2, p.length === 4)
7665
+ return d = f1 + f2 + f3 + f4, {
7666
+ x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x + f4 * p[3].x) / d,
7667
+ y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y + f4 * p[3].y) / d,
7668
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z + f4 * p[3].z) / d : !1,
7669
+ t: t2
7670
+ };
7671
+ },
7672
+ derive: function(points, _3d) {
7673
+ const dpoints = [];
7674
+ for (let p = points, d = p.length, c = d - 1; d > 1; d--, c--) {
7675
+ const list = [];
7676
+ for (let j = 0, dpt; j < c; j++)
7677
+ dpt = {
7678
+ x: c * (p[j + 1].x - p[j].x),
7679
+ y: c * (p[j + 1].y - p[j].y)
7680
+ }, _3d && (dpt.z = c * (p[j + 1].z - p[j].z)), list.push(dpt);
7681
+ dpoints.push(list), p = list;
7682
+ }
7683
+ return dpoints;
7684
+ },
7685
+ between: function(v, m, M) {
7686
+ return m <= v && v <= M || utils.approximately(v, m) || utils.approximately(v, M);
7687
+ },
7688
+ approximately: function(a, b, precision) {
7689
+ return abs$1(a - b) <= (precision || epsilon);
7690
+ },
7691
+ length: function(derivativeFn) {
7692
+ const len = utils.Tvalues.length;
7693
+ let sum = 0;
7694
+ for (let i = 0, t2; i < len; i++)
7695
+ t2 = 0.5 * utils.Tvalues[i] + 0.5, sum += utils.Cvalues[i] * utils.arcfn(t2, derivativeFn);
7696
+ return 0.5 * sum;
7697
+ },
7698
+ map: function(v, ds, de, ts, te) {
7699
+ const d1 = de - ds, d2 = te - ts, v2 = v - ds, r2 = v2 / d1;
7700
+ return ts + d2 * r2;
7701
+ },
7702
+ lerp: function(r2, v1, v2) {
7703
+ const ret = {
7704
+ x: v1.x + r2 * (v2.x - v1.x),
7705
+ y: v1.y + r2 * (v2.y - v1.y)
7706
+ };
7707
+ return v1.z !== void 0 && v2.z !== void 0 && (ret.z = v1.z + r2 * (v2.z - v1.z)), ret;
7708
+ },
7709
+ pointToString: function(p) {
7710
+ let s = p.x + "/" + p.y;
7711
+ return typeof p.z < "u" && (s += "/" + p.z), s;
7712
+ },
7713
+ pointsToString: function(points) {
7714
+ return "[" + points.map(utils.pointToString).join(", ") + "]";
7715
+ },
7716
+ copy: function(obj) {
7717
+ return JSON.parse(JSON.stringify(obj));
7718
+ },
7719
+ angle: function(o, v1, v2) {
7720
+ const dx1 = v1.x - o.x, dy1 = v1.y - o.y, dx2 = v2.x - o.x, dy2 = v2.y - o.y, cross = dx1 * dy2 - dy1 * dx2, dot = dx1 * dx2 + dy1 * dy2;
7721
+ return atan2(cross, dot);
7722
+ },
7723
+ // round as string, to avoid rounding errors
7724
+ round: function(v, d) {
7725
+ const s = "" + v, pos = s.indexOf(".");
7726
+ return parseFloat(s.substring(0, pos + 1 + d));
7727
+ },
7728
+ dist: function(p1, p2) {
7729
+ const dx = p1.x - p2.x, dy = p1.y - p2.y;
7730
+ return sqrt$1(dx * dx + dy * dy);
7731
+ },
7732
+ closest: function(LUT, point) {
7733
+ let mdist = pow(2, 63), mpos, d;
7734
+ return LUT.forEach(function(p, idx) {
7735
+ d = utils.dist(point, p), d < mdist && (mdist = d, mpos = idx);
7736
+ }), { mdist, mpos };
7737
+ },
7738
+ abcratio: function(t2, n) {
7739
+ if (n !== 2 && n !== 3)
7740
+ return !1;
7741
+ if (typeof t2 > "u")
7742
+ t2 = 0.5;
7743
+ else if (t2 === 0 || t2 === 1)
7744
+ return t2;
7745
+ const bottom = pow(t2, n) + pow(1 - t2, n), top = bottom - 1;
7746
+ return abs$1(top / bottom);
7747
+ },
7748
+ projectionratio: function(t2, n) {
7749
+ if (n !== 2 && n !== 3)
7750
+ return !1;
7751
+ if (typeof t2 > "u")
7752
+ t2 = 0.5;
7753
+ else if (t2 === 0 || t2 === 1)
7754
+ return t2;
7755
+ const top = pow(1 - t2, n), bottom = pow(t2, n) + top;
7756
+ return top / bottom;
7757
+ },
7758
+ lli8: function(x1, y1, x2, y2, x3, y3, x4, y4) {
7759
+ const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
7760
+ return d == 0 ? !1 : { x: nx / d, y: ny / d };
7761
+ },
7762
+ lli4: function(p1, p2, p3, p4) {
7763
+ const x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y, x4 = p4.x, y4 = p4.y;
7764
+ return utils.lli8(x1, y1, x2, y2, x3, y3, x4, y4);
7765
+ },
7766
+ lli: function(v1, v2) {
7767
+ return utils.lli4(v1, v1.c, v2, v2.c);
7768
+ },
7769
+ makeline: function(p1, p2) {
7770
+ return new Bezier(
7771
+ p1.x,
7772
+ p1.y,
7773
+ (p1.x + p2.x) / 2,
7774
+ (p1.y + p2.y) / 2,
7775
+ p2.x,
7776
+ p2.y
7777
+ );
7778
+ },
7779
+ findbbox: function(sections) {
7780
+ let mx = nMax, my = nMax, MX = nMin, MY = nMin;
7781
+ return sections.forEach(function(s) {
7782
+ const bbox = s.bbox();
7783
+ mx > bbox.x.min && (mx = bbox.x.min), my > bbox.y.min && (my = bbox.y.min), MX < bbox.x.max && (MX = bbox.x.max), MY < bbox.y.max && (MY = bbox.y.max);
7784
+ }), {
7785
+ x: { min: mx, mid: (mx + MX) / 2, max: MX, size: MX - mx },
7786
+ y: { min: my, mid: (my + MY) / 2, max: MY, size: MY - my }
7787
+ };
7788
+ },
7789
+ shapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) {
7790
+ if (!utils.bboxoverlap(bbox1, bbox2))
7791
+ return [];
7792
+ const intersections = [], a1 = [s1.startcap, s1.forward, s1.back, s1.endcap], a2 = [s2.startcap, s2.forward, s2.back, s2.endcap];
7793
+ return a1.forEach(function(l1) {
7794
+ l1.virtual || a2.forEach(function(l2) {
7795
+ if (l2.virtual)
7796
+ return;
7797
+ const iss = l1.intersects(l2, curveIntersectionThreshold);
7798
+ iss.length > 0 && (iss.c1 = l1, iss.c2 = l2, iss.s1 = s1, iss.s2 = s2, intersections.push(iss));
7799
+ });
7800
+ }), intersections;
7801
+ },
7802
+ makeshape: function(forward, back, curveIntersectionThreshold) {
7803
+ const bpl = back.points.length, fpl = forward.points.length, start2 = utils.makeline(back.points[bpl - 1], forward.points[0]), end = utils.makeline(forward.points[fpl - 1], back.points[0]), shape = {
7804
+ startcap: start2,
7805
+ forward,
7806
+ back,
7807
+ endcap: end,
7808
+ bbox: utils.findbbox([start2, forward, back, end])
7809
+ };
7810
+ return shape.intersections = function(s2) {
7811
+ return utils.shapeintersections(
7812
+ shape,
7813
+ shape.bbox,
7814
+ s2,
7815
+ s2.bbox,
7816
+ curveIntersectionThreshold
7817
+ );
7818
+ }, shape;
7819
+ },
7820
+ getminmax: function(curve2, d, list) {
7821
+ if (!list)
7822
+ return { min: 0, max: 0 };
7823
+ let min2 = nMax, max2 = nMin, t2, c;
7824
+ list.indexOf(0) === -1 && (list = [0].concat(list)), list.indexOf(1) === -1 && list.push(1);
7825
+ for (let i = 0, len = list.length; i < len; i++)
7826
+ t2 = list[i], c = curve2.get(t2), c[d] < min2 && (min2 = c[d]), c[d] > max2 && (max2 = c[d]);
7827
+ return { min: min2, mid: (min2 + max2) / 2, max: max2, size: max2 - min2 };
7828
+ },
7829
+ align: function(points, line2) {
7830
+ const tx = line2.p1.x, ty = line2.p1.y, a = -atan2(line2.p2.y - ty, line2.p2.x - tx), d = function(v) {
7831
+ return {
7832
+ x: (v.x - tx) * cos$1(a) - (v.y - ty) * sin$1(a),
7833
+ y: (v.x - tx) * sin$1(a) + (v.y - ty) * cos$1(a)
7834
+ };
7835
+ };
7836
+ return points.map(d);
7837
+ },
7838
+ roots: function(points, line2) {
7839
+ line2 = line2 || { p1: { x: 0, y: 0 }, p2: { x: 1, y: 0 } };
7840
+ const order = points.length - 1, aligned = utils.align(points, line2), reduce = function(t2) {
7841
+ return 0 <= t2 && t2 <= 1;
7842
+ };
7843
+ if (order === 2) {
7844
+ const a2 = aligned[0].y, b2 = aligned[1].y, c2 = aligned[2].y, d2 = a2 - 2 * b2 + c2;
7845
+ if (d2 !== 0) {
7846
+ const m1 = -sqrt$1(b2 * b2 - a2 * c2), m2 = -a2 + b2, v12 = -(m1 + m2) / d2, v2 = -(-m1 + m2) / d2;
7847
+ return [v12, v2].filter(reduce);
7848
+ } else if (b2 !== c2 && d2 === 0)
7849
+ return [(2 * b2 - c2) / (2 * b2 - 2 * c2)].filter(reduce);
7850
+ return [];
7851
+ }
7852
+ const pa = aligned[0].y, pb = aligned[1].y, pc = aligned[2].y, pd = aligned[3].y;
7853
+ let d = -pa + 3 * pb - 3 * pc + pd, a = 3 * pa - 6 * pb + 3 * pc, b = -3 * pa + 3 * pb, c = pa;
7854
+ if (utils.approximately(d, 0)) {
7855
+ if (utils.approximately(a, 0))
7856
+ return utils.approximately(b, 0) ? [] : [-c / b].filter(reduce);
7857
+ const q3 = sqrt$1(b * b - 4 * a * c), a2 = 2 * a;
7858
+ return [(q3 - b) / a2, (-b - q3) / a2].filter(reduce);
7859
+ }
7860
+ a /= d, b /= d, c /= d;
7861
+ const p = (3 * b - a * a) / 3, p3 = p / 3, q = (2 * a * a * a - 9 * a * b + 27 * c) / 27, q2 = q / 2, discriminant = q2 * q2 + p3 * p3 * p3;
7862
+ let u1, v1, x1, x2, x3;
7863
+ if (discriminant < 0) {
7864
+ const mp3 = -p / 3, mp33 = mp3 * mp3 * mp3, r2 = sqrt$1(mp33), t2 = -q / (2 * r2), cosphi = t2 < -1 ? -1 : t2 > 1 ? 1 : t2, phi = acos$1(cosphi), crtr = crt(r2), t1 = 2 * crtr;
7865
+ return x1 = t1 * cos$1(phi / 3) - a / 3, x2 = t1 * cos$1((phi + tau) / 3) - a / 3, x3 = t1 * cos$1((phi + 2 * tau) / 3) - a / 3, [x1, x2, x3].filter(reduce);
7866
+ } else {
7867
+ if (discriminant === 0)
7868
+ return u1 = q2 < 0 ? crt(-q2) : -crt(q2), x1 = 2 * u1 - a / 3, x2 = -u1 - a / 3, [x1, x2].filter(reduce);
7445
7869
  {
7446
- nodes,
7447
- onShapeChange: (shape) => {
7448
- const targets = [];
7449
- for (const nd of nodes)
7450
- nd.data.element.shape !== shape && targets.push(nd.data.element.id);
7451
- hasAtLeast(targets, 1) && diagramApi.getState().triggerOnChange([{
7452
- op: "change-shape",
7453
- shape,
7454
- targets
7455
- }]);
7456
- }
7870
+ const sd = sqrt$1(discriminant);
7871
+ return u1 = crt(-q2 + sd), v1 = crt(q2 + sd), [u1 - v1 - a / 3].filter(reduce);
7457
7872
  }
7458
- ),
7459
- /* @__PURE__ */ jsx(
7460
- Colors,
7461
- {
7462
- nodes,
7463
- onColorChange: (color2) => {
7464
- const targets = [];
7465
- for (const nd of nodes)
7466
- nd.data.element.color !== color2 && targets.push(nd.data.element.id);
7467
- hasAtLeast(targets, 1) && diagramApi.getState().triggerOnChange([{
7468
- op: "change-color",
7469
- color: color2,
7470
- targets
7471
- }]);
7472
- }
7873
+ }
7874
+ },
7875
+ droots: function(p) {
7876
+ if (p.length === 3) {
7877
+ const a = p[0], b = p[1], c = p[2], d = a - 2 * b + c;
7878
+ if (d !== 0) {
7879
+ const m1 = -sqrt$1(b * b - a * c), m2 = -a + b, v1 = -(m1 + m2) / d, v2 = -(-m1 + m2) / d;
7880
+ return [v1, v2];
7881
+ } else if (b !== c && d === 0)
7882
+ return [(2 * b - c) / (2 * (b - c))];
7883
+ return [];
7884
+ }
7885
+ if (p.length === 2) {
7886
+ const a = p[0], b = p[1];
7887
+ return a !== b ? [a / (a - b)] : [];
7888
+ }
7889
+ return [];
7890
+ },
7891
+ curvature: function(t2, d1, d2, _3d, kOnly) {
7892
+ let num, dnm, adk, dk, k = 0, r2 = 0;
7893
+ const d = utils.compute(t2, d1), dd = utils.compute(t2, d2), qdsum = d.x * d.x + d.y * d.y;
7894
+ if (_3d ? (num = sqrt$1(
7895
+ pow(d.y * dd.z - dd.y * d.z, 2) + pow(d.z * dd.x - dd.z * d.x, 2) + pow(d.x * dd.y - dd.x * d.y, 2)
7896
+ ), dnm = pow(qdsum + d.z * d.z, 3 / 2)) : (num = d.x * dd.y - d.y * dd.x, dnm = pow(qdsum, 3 / 2)), num === 0 || dnm === 0)
7897
+ return { k: 0, r: 0 };
7898
+ if (k = num / dnm, r2 = dnm / num, !kOnly) {
7899
+ const pk = utils.curvature(t2 - 1e-3, d1, d2, _3d, !0).k, nk = utils.curvature(t2 + 1e-3, d1, d2, _3d, !0).k;
7900
+ dk = (nk - k + (k - pk)) / 2, adk = (abs$1(nk - k) + abs$1(k - pk)) / 2;
7901
+ }
7902
+ return { k, r: r2, dk, adk };
7903
+ },
7904
+ inflections: function(points) {
7905
+ if (points.length < 4)
7906
+ return [];
7907
+ const p = utils.align(points, { p1: points[0], p2: points.slice(-1)[0] }), a = p[2].x * p[1].y, b = p[3].x * p[1].y, c = p[1].x * p[2].y, d = p[3].x * p[2].y, v1 = 18 * (-3 * a + 2 * b + 3 * c - d), v2 = 18 * (3 * a - b - 3 * c), v3 = 18 * (c - a);
7908
+ if (utils.approximately(v1, 0)) {
7909
+ if (!utils.approximately(v2, 0)) {
7910
+ let t2 = -v3 / v2;
7911
+ if (0 <= t2 && t2 <= 1)
7912
+ return [t2];
7473
7913
  }
7474
- ),
7475
- /* @__PURE__ */ jsx(NavigateToOption, { nodes })
7476
- ] });
7477
- }
7478
- function Colors({
7479
- nodes: [firstNode, ...nodes],
7480
- onColorChange
7481
- }) {
7482
- let selectedColor = firstNode.data.element.color;
7483
- takeWhile(nodes, (node) => node.data.element.color !== selectedColor ? (selectedColor = null, !1) : !0);
7484
- const changeColor = (color2) => () => {
7485
- selectedColor !== color2 && onColorChange(color2);
7486
- };
7487
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
7488
- /* @__PURE__ */ jsx(Divider, { label: "color", labelPosition: "left" }),
7489
- /* @__PURE__ */ jsx(Flex, { mt: "xs", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: themedColors.map(({ key, value }) => /* @__PURE__ */ jsx(
7490
- Tooltip,
7491
- {
7492
- label: key,
7493
- fz: "xs",
7494
- color: "dark",
7495
- offset: 2,
7496
- transitionProps: { duration: 140, transition: "slide-up" },
7497
- children: /* @__PURE__ */ jsx(
7498
- ColorSwatch,
7499
- {
7500
- color: value,
7501
- size: 20,
7502
- withShadow: !0,
7503
- onClick: changeColor(key),
7504
- style: { color: "#fff", cursor: "pointer" },
7505
- children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
7914
+ return [];
7915
+ }
7916
+ const d2 = 2 * v1;
7917
+ if (utils.approximately(d2, 0))
7918
+ return [];
7919
+ const trm = v2 * v2 - 4 * v1 * v3;
7920
+ if (trm < 0)
7921
+ return [];
7922
+ const sq = Math.sqrt(trm);
7923
+ return [(sq - v2) / d2, -(v2 + sq) / d2].filter(function(r2) {
7924
+ return 0 <= r2 && r2 <= 1;
7925
+ });
7926
+ },
7927
+ bboxoverlap: function(b1, b2) {
7928
+ const dims = ["x", "y"], len = dims.length;
7929
+ for (let i = 0, dim, l, t2, d; i < len; i++)
7930
+ if (dim = dims[i], l = b1[dim].mid, t2 = b2[dim].mid, d = (b1[dim].size + b2[dim].size) / 2, abs$1(l - t2) >= d)
7931
+ return !1;
7932
+ return !0;
7933
+ },
7934
+ expandbox: function(bbox, _bbox) {
7935
+ _bbox.x.min < bbox.x.min && (bbox.x.min = _bbox.x.min), _bbox.y.min < bbox.y.min && (bbox.y.min = _bbox.y.min), _bbox.z && _bbox.z.min < bbox.z.min && (bbox.z.min = _bbox.z.min), _bbox.x.max > bbox.x.max && (bbox.x.max = _bbox.x.max), _bbox.y.max > bbox.y.max && (bbox.y.max = _bbox.y.max), _bbox.z && _bbox.z.max > bbox.z.max && (bbox.z.max = _bbox.z.max), bbox.x.mid = (bbox.x.min + bbox.x.max) / 2, bbox.y.mid = (bbox.y.min + bbox.y.max) / 2, bbox.z && (bbox.z.mid = (bbox.z.min + bbox.z.max) / 2), bbox.x.size = bbox.x.max - bbox.x.min, bbox.y.size = bbox.y.max - bbox.y.min, bbox.z && (bbox.z.size = bbox.z.max - bbox.z.min);
7936
+ },
7937
+ pairiteration: function(c1, c2, curveIntersectionThreshold) {
7938
+ const c1b = c1.bbox(), c2b = c2.bbox(), r2 = 1e5, threshold = curveIntersectionThreshold || 0.5;
7939
+ if (c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold)
7940
+ return [
7941
+ (r2 * (c1._t1 + c1._t2) / 2 | 0) / r2 + "/" + (r2 * (c2._t1 + c2._t2) / 2 | 0) / r2
7942
+ ];
7943
+ let cc1 = c1.split(0.5), cc2 = c2.split(0.5), pairs = [
7944
+ { left: cc1.left, right: cc2.left },
7945
+ { left: cc1.left, right: cc2.right },
7946
+ { left: cc1.right, right: cc2.right },
7947
+ { left: cc1.right, right: cc2.left }
7948
+ ];
7949
+ pairs = pairs.filter(function(pair) {
7950
+ return utils.bboxoverlap(pair.left.bbox(), pair.right.bbox());
7951
+ });
7952
+ let results = [];
7953
+ return pairs.length === 0 || (pairs.forEach(function(pair) {
7954
+ results = results.concat(
7955
+ utils.pairiteration(pair.left, pair.right, threshold)
7956
+ );
7957
+ }), results = results.filter(function(v, i) {
7958
+ return results.indexOf(v) === i;
7959
+ })), results;
7960
+ },
7961
+ getccenter: function(p1, p2, p3) {
7962
+ const dx1 = p2.x - p1.x, dy1 = p2.y - p1.y, dx2 = p3.x - p2.x, dy2 = p3.y - p2.y, dx1p = dx1 * cos$1(quart) - dy1 * sin$1(quart), dy1p = dx1 * sin$1(quart) + dy1 * cos$1(quart), dx2p = dx2 * cos$1(quart) - dy2 * sin$1(quart), dy2p = dx2 * sin$1(quart) + dy2 * cos$1(quart), mx1 = (p1.x + p2.x) / 2, my1 = (p1.y + p2.y) / 2, mx2 = (p2.x + p3.x) / 2, my2 = (p2.y + p3.y) / 2, mx1n = mx1 + dx1p, my1n = my1 + dy1p, mx2n = mx2 + dx2p, my2n = my2 + dy2p, arc = utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n), r2 = utils.dist(arc, p1);
7963
+ let s = atan2(p1.y - arc.y, p1.x - arc.x), m = atan2(p2.y - arc.y, p2.x - arc.x), e = atan2(p3.y - arc.y, p3.x - arc.x), _;
7964
+ return s < e ? ((s > m || m > e) && (s += tau), s > e && (_ = e, e = s, s = _)) : e < m && m < s ? (_ = e, e = s, s = _) : e += tau, arc.s = s, arc.e = e, arc.r = r2, arc;
7965
+ },
7966
+ numberSort: function(a, b) {
7967
+ return a - b;
7968
+ }
7969
+ };
7970
+ class PolyBezier {
7971
+ constructor(curves) {
7972
+ this.curves = [], this._3d = !1, curves && (this.curves = curves, this._3d = this.curves[0]._3d);
7973
+ }
7974
+ valueOf() {
7975
+ return this.toString();
7976
+ }
7977
+ toString() {
7978
+ return "[" + this.curves.map(function(curve2) {
7979
+ return utils.pointsToString(curve2.points);
7980
+ }).join(", ") + "]";
7981
+ }
7982
+ addCurve(curve2) {
7983
+ this.curves.push(curve2), this._3d = this._3d || curve2._3d;
7984
+ }
7985
+ length() {
7986
+ return this.curves.map(function(v) {
7987
+ return v.length();
7988
+ }).reduce(function(a, b) {
7989
+ return a + b;
7990
+ });
7991
+ }
7992
+ curve(idx) {
7993
+ return this.curves[idx];
7994
+ }
7995
+ bbox() {
7996
+ const c = this.curves;
7997
+ for (var bbox = c[0].bbox(), i = 1; i < c.length; i++)
7998
+ utils.expandbox(bbox, c[i].bbox());
7999
+ return bbox;
8000
+ }
8001
+ offset(d) {
8002
+ const offset = [];
8003
+ return this.curves.forEach(function(v) {
8004
+ offset.push(...v.offset(d));
8005
+ }), new PolyBezier(offset);
8006
+ }
8007
+ }
8008
+ const { abs, min, max, cos, sin, acos, sqrt } = Math, pi = Math.PI;
8009
+ class Bezier {
8010
+ constructor(coords) {
8011
+ let args = coords && coords.forEach ? coords : Array.from(arguments).slice(), coordlen = !1;
8012
+ if (typeof args[0] == "object") {
8013
+ coordlen = args.length;
8014
+ const newargs = [];
8015
+ args.forEach(function(point2) {
8016
+ ["x", "y", "z"].forEach(function(d) {
8017
+ typeof point2[d] < "u" && newargs.push(point2[d]);
8018
+ });
8019
+ }), args = newargs;
8020
+ }
8021
+ let higher = !1;
8022
+ const len = args.length;
8023
+ if (coordlen) {
8024
+ if (coordlen > 4) {
8025
+ if (arguments.length !== 1)
8026
+ throw new Error(
8027
+ "Only new Bezier(point[]) is accepted for 4th and higher order curves"
8028
+ );
8029
+ higher = !0;
8030
+ }
8031
+ } else if (len !== 6 && len !== 8 && len !== 9 && len !== 12 && arguments.length !== 1)
8032
+ throw new Error(
8033
+ "Only new Bezier(point[]) is accepted for 4th and higher order curves"
8034
+ );
8035
+ const _3d = this._3d = !higher && (len === 9 || len === 12) || coords && coords[0] && typeof coords[0].z < "u", points = this.points = [];
8036
+ for (let idx = 0, step = _3d ? 3 : 2; idx < len; idx += step) {
8037
+ var point = {
8038
+ x: args[idx],
8039
+ y: args[idx + 1]
8040
+ };
8041
+ _3d && (point.z = args[idx + 2]), points.push(point);
8042
+ }
8043
+ const order = this.order = points.length - 1, dims = this.dims = ["x", "y"];
8044
+ _3d && dims.push("z"), this.dimlen = dims.length;
8045
+ const aligned = utils.align(points, { p1: points[0], p2: points[order] }), baselength = utils.dist(points[0], points[order]);
8046
+ this._linear = aligned.reduce((t2, p) => t2 + abs(p.y), 0) < baselength / 50, this._lut = [], this._t1 = 0, this._t2 = 1, this.update();
8047
+ }
8048
+ static quadraticFromPoints(p1, p2, p3, t2) {
8049
+ if (typeof t2 > "u" && (t2 = 0.5), t2 === 0)
8050
+ return new Bezier(p2, p2, p3);
8051
+ if (t2 === 1)
8052
+ return new Bezier(p1, p2, p2);
8053
+ const abc = Bezier.getABC(2, p1, p2, p3, t2);
8054
+ return new Bezier(p1, abc.A, p3);
8055
+ }
8056
+ static cubicFromPoints(S, B, E, t2, d1) {
8057
+ typeof t2 > "u" && (t2 = 0.5);
8058
+ const abc = Bezier.getABC(3, S, B, E, t2);
8059
+ typeof d1 > "u" && (d1 = utils.dist(B, abc.C));
8060
+ const d2 = d1 * (1 - t2) / t2, selen = utils.dist(S, E), lx = (E.x - S.x) / selen, ly = (E.y - S.y) / selen, bx1 = d1 * lx, by1 = d1 * ly, bx2 = d2 * lx, by2 = d2 * ly, e1 = { x: B.x - bx1, y: B.y - by1 }, e2 = { x: B.x + bx2, y: B.y + by2 }, A = abc.A, v1 = { x: A.x + (e1.x - A.x) / (1 - t2), y: A.y + (e1.y - A.y) / (1 - t2) }, v2 = { x: A.x + (e2.x - A.x) / t2, y: A.y + (e2.y - A.y) / t2 }, nc1 = { x: S.x + (v1.x - S.x) / t2, y: S.y + (v1.y - S.y) / t2 }, nc2 = {
8061
+ x: E.x + (v2.x - E.x) / (1 - t2),
8062
+ y: E.y + (v2.y - E.y) / (1 - t2)
8063
+ };
8064
+ return new Bezier(S, nc1, nc2, E);
8065
+ }
8066
+ static getUtils() {
8067
+ return utils;
8068
+ }
8069
+ getUtils() {
8070
+ return Bezier.getUtils();
8071
+ }
8072
+ static get PolyBezier() {
8073
+ return PolyBezier;
8074
+ }
8075
+ valueOf() {
8076
+ return this.toString();
8077
+ }
8078
+ toString() {
8079
+ return utils.pointsToString(this.points);
8080
+ }
8081
+ toSVG() {
8082
+ if (this._3d)
8083
+ return !1;
8084
+ const p = this.points, x = p[0].x, y = p[0].y, s = ["M", x, y, this.order === 2 ? "Q" : "C"];
8085
+ for (let i = 1, last2 = p.length; i < last2; i++)
8086
+ s.push(p[i].x), s.push(p[i].y);
8087
+ return s.join(" ");
8088
+ }
8089
+ setRatios(ratios) {
8090
+ if (ratios.length !== this.points.length)
8091
+ throw new Error("incorrect number of ratio values");
8092
+ this.ratios = ratios, this._lut = [];
8093
+ }
8094
+ verify() {
8095
+ const print = this.coordDigest();
8096
+ print !== this._print && (this._print = print, this.update());
8097
+ }
8098
+ coordDigest() {
8099
+ return this.points.map(function(c, pos) {
8100
+ return "" + pos + c.x + c.y + (c.z ? c.z : 0);
8101
+ }).join("");
8102
+ }
8103
+ update() {
8104
+ this._lut = [], this.dpoints = utils.derive(this.points, this._3d), this.computedirection();
8105
+ }
8106
+ computedirection() {
8107
+ const points = this.points, angle = utils.angle(points[0], points[this.order], points[1]);
8108
+ this.clockwise = angle > 0;
8109
+ }
8110
+ length() {
8111
+ return utils.length(this.derivative.bind(this));
8112
+ }
8113
+ static getABC(order = 2, S, B, E, t2 = 0.5) {
8114
+ const u = utils.projectionratio(t2, order), um = 1 - u, C = {
8115
+ x: u * S.x + um * E.x,
8116
+ y: u * S.y + um * E.y
8117
+ }, s = utils.abcratio(t2, order);
8118
+ return { A: {
8119
+ x: B.x + (B.x - C.x) / s,
8120
+ y: B.y + (B.y - C.y) / s
8121
+ }, B, C, S, E };
8122
+ }
8123
+ getABC(t2, B) {
8124
+ B = B || this.get(t2);
8125
+ let S = this.points[0], E = this.points[this.order];
8126
+ return Bezier.getABC(this.order, S, B, E, t2);
8127
+ }
8128
+ getLUT(steps) {
8129
+ if (this.verify(), steps = steps || 100, this._lut.length === steps + 1)
8130
+ return this._lut;
8131
+ this._lut = [], steps++, this._lut = [];
8132
+ for (let i = 0, p, t2; i < steps; i++)
8133
+ t2 = i / (steps - 1), p = this.compute(t2), p.t = t2, this._lut.push(p);
8134
+ return this._lut;
8135
+ }
8136
+ on(point, error) {
8137
+ error = error || 5;
8138
+ const lut = this.getLUT(), hits = [];
8139
+ for (let i = 0, c, t2 = 0; i < lut.length; i++)
8140
+ c = lut[i], utils.dist(c, point) < error && (hits.push(c), t2 += i / lut.length);
8141
+ return hits.length ? t /= hits.length : !1;
8142
+ }
8143
+ project(point) {
8144
+ const LUT = this.getLUT(), l = LUT.length - 1, closest = utils.closest(LUT, point), mpos = closest.mpos, t1 = (mpos - 1) / l, t2 = (mpos + 1) / l, step = 0.1 / l;
8145
+ let mdist = closest.mdist, t3 = t1, ft = t3, p;
8146
+ mdist += 1;
8147
+ for (let d; t3 < t2 + step; t3 += step)
8148
+ p = this.compute(t3), d = utils.dist(point, p), d < mdist && (mdist = d, ft = t3);
8149
+ return ft = ft < 0 ? 0 : ft > 1 ? 1 : ft, p = this.compute(ft), p.t = ft, p.d = mdist, p;
8150
+ }
8151
+ get(t2) {
8152
+ return this.compute(t2);
8153
+ }
8154
+ point(idx) {
8155
+ return this.points[idx];
8156
+ }
8157
+ compute(t2) {
8158
+ return this.ratios ? utils.computeWithRatios(t2, this.points, this.ratios, this._3d) : utils.compute(t2, this.points, this._3d, this.ratios);
8159
+ }
8160
+ raise() {
8161
+ const p = this.points, np = [p[0]], k = p.length;
8162
+ for (let i = 1, pi2, pim; i < k; i++)
8163
+ pi2 = p[i], pim = p[i - 1], np[i] = {
8164
+ x: (k - i) / k * pi2.x + i / k * pim.x,
8165
+ y: (k - i) / k * pi2.y + i / k * pim.y
8166
+ };
8167
+ return np[k] = p[k - 1], new Bezier(np);
8168
+ }
8169
+ derivative(t2) {
8170
+ return utils.compute(t2, this.dpoints[0], this._3d);
8171
+ }
8172
+ dderivative(t2) {
8173
+ return utils.compute(t2, this.dpoints[1], this._3d);
8174
+ }
8175
+ align() {
8176
+ let p = this.points;
8177
+ return new Bezier(utils.align(p, { p1: p[0], p2: p[p.length - 1] }));
8178
+ }
8179
+ curvature(t2) {
8180
+ return utils.curvature(t2, this.dpoints[0], this.dpoints[1], this._3d);
8181
+ }
8182
+ inflections() {
8183
+ return utils.inflections(this.points);
8184
+ }
8185
+ normal(t2) {
8186
+ return this._3d ? this.__normal3(t2) : this.__normal2(t2);
8187
+ }
8188
+ __normal2(t2) {
8189
+ const d = this.derivative(t2), q = sqrt(d.x * d.x + d.y * d.y);
8190
+ return { t: t2, x: -d.y / q, y: d.x / q };
8191
+ }
8192
+ __normal3(t2) {
8193
+ const r1 = this.derivative(t2), r2 = this.derivative(t2 + 0.01), q1 = sqrt(r1.x * r1.x + r1.y * r1.y + r1.z * r1.z), q2 = sqrt(r2.x * r2.x + r2.y * r2.y + r2.z * r2.z);
8194
+ r1.x /= q1, r1.y /= q1, r1.z /= q1, r2.x /= q2, r2.y /= q2, r2.z /= q2;
8195
+ const c = {
8196
+ x: r2.y * r1.z - r2.z * r1.y,
8197
+ y: r2.z * r1.x - r2.x * r1.z,
8198
+ z: r2.x * r1.y - r2.y * r1.x
8199
+ }, m = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);
8200
+ c.x /= m, c.y /= m, c.z /= m;
8201
+ const R = [
8202
+ c.x * c.x,
8203
+ c.x * c.y - c.z,
8204
+ c.x * c.z + c.y,
8205
+ c.x * c.y + c.z,
8206
+ c.y * c.y,
8207
+ c.y * c.z - c.x,
8208
+ c.x * c.z - c.y,
8209
+ c.y * c.z + c.x,
8210
+ c.z * c.z
8211
+ ];
8212
+ return {
8213
+ t: t2,
8214
+ x: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z,
8215
+ y: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z,
8216
+ z: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z
8217
+ };
8218
+ }
8219
+ hull(t2) {
8220
+ let p = this.points, _p = [], q = [], idx = 0;
8221
+ for (q[idx++] = p[0], q[idx++] = p[1], q[idx++] = p[2], this.order === 3 && (q[idx++] = p[3]); p.length > 1; ) {
8222
+ _p = [];
8223
+ for (let i = 0, pt, l = p.length - 1; i < l; i++)
8224
+ pt = utils.lerp(t2, p[i], p[i + 1]), q[idx++] = pt, _p.push(pt);
8225
+ p = _p;
8226
+ }
8227
+ return q;
8228
+ }
8229
+ split(t1, t2) {
8230
+ if (t1 === 0 && t2)
8231
+ return this.split(t2).left;
8232
+ if (t2 === 1)
8233
+ return this.split(t1).right;
8234
+ const q = this.hull(t1), result = {
8235
+ left: this.order === 2 ? new Bezier([q[0], q[3], q[5]]) : new Bezier([q[0], q[4], q[7], q[9]]),
8236
+ right: this.order === 2 ? new Bezier([q[5], q[4], q[2]]) : new Bezier([q[9], q[8], q[6], q[3]]),
8237
+ span: q
8238
+ };
8239
+ return result.left._t1 = utils.map(0, 0, 1, this._t1, this._t2), result.left._t2 = utils.map(t1, 0, 1, this._t1, this._t2), result.right._t1 = utils.map(t1, 0, 1, this._t1, this._t2), result.right._t2 = utils.map(1, 0, 1, this._t1, this._t2), t2 ? (t2 = utils.map(t2, t1, 1, 0, 1), result.right.split(t2).left) : result;
8240
+ }
8241
+ extrema() {
8242
+ const result = {};
8243
+ let roots = [];
8244
+ return this.dims.forEach(
8245
+ (function(dim) {
8246
+ let mfn = function(v) {
8247
+ return v[dim];
8248
+ }, p = this.dpoints[0].map(mfn);
8249
+ result[dim] = utils.droots(p), this.order === 3 && (p = this.dpoints[1].map(mfn), result[dim] = result[dim].concat(utils.droots(p))), result[dim] = result[dim].filter(function(t2) {
8250
+ return t2 >= 0 && t2 <= 1;
8251
+ }), roots = roots.concat(result[dim].sort(utils.numberSort));
8252
+ }).bind(this)
8253
+ ), result.values = roots.sort(utils.numberSort).filter(function(v, idx) {
8254
+ return roots.indexOf(v) === idx;
8255
+ }), result;
8256
+ }
8257
+ bbox() {
8258
+ const extrema = this.extrema(), result = {};
8259
+ return this.dims.forEach(
8260
+ (function(d) {
8261
+ result[d] = utils.getminmax(this, d, extrema[d]);
8262
+ }).bind(this)
8263
+ ), result;
8264
+ }
8265
+ overlaps(curve2) {
8266
+ const lbbox = this.bbox(), tbbox = curve2.bbox();
8267
+ return utils.bboxoverlap(lbbox, tbbox);
8268
+ }
8269
+ offset(t2, d) {
8270
+ if (typeof d < "u") {
8271
+ const c = this.get(t2), n = this.normal(t2), ret = {
8272
+ c,
8273
+ n,
8274
+ x: c.x + n.x * d,
8275
+ y: c.y + n.y * d
8276
+ };
8277
+ return this._3d && (ret.z = c.z + n.z * d), ret;
8278
+ }
8279
+ if (this._linear) {
8280
+ const nv = this.normal(0), coords = this.points.map(function(p) {
8281
+ const ret = {
8282
+ x: p.x + t2 * nv.x,
8283
+ y: p.y + t2 * nv.y
8284
+ };
8285
+ return p.z && nv.z && (ret.z = p.z + t2 * nv.z), ret;
8286
+ });
8287
+ return [new Bezier(coords)];
8288
+ }
8289
+ return this.reduce().map(function(s) {
8290
+ return s._linear ? s.offset(t2)[0] : s.scale(t2);
8291
+ });
8292
+ }
8293
+ simple() {
8294
+ if (this.order === 3) {
8295
+ const a1 = utils.angle(this.points[0], this.points[3], this.points[1]), a2 = utils.angle(this.points[0], this.points[3], this.points[2]);
8296
+ if (a1 > 0 && a2 < 0 || a1 < 0 && a2 > 0)
8297
+ return !1;
8298
+ }
8299
+ const n1 = this.normal(0), n2 = this.normal(1);
8300
+ let s = n1.x * n2.x + n1.y * n2.y;
8301
+ return this._3d && (s += n1.z * n2.z), abs(acos(s)) < pi / 3;
8302
+ }
8303
+ reduce() {
8304
+ let i, t1 = 0, t2 = 0, step = 0.01, segment, pass1 = [], pass2 = [], extrema = this.extrema().values;
8305
+ for (extrema.indexOf(0) === -1 && (extrema = [0].concat(extrema)), extrema.indexOf(1) === -1 && extrema.push(1), t1 = extrema[0], i = 1; i < extrema.length; i++)
8306
+ t2 = extrema[i], segment = this.split(t1, t2), segment._t1 = t1, segment._t2 = t2, pass1.push(segment), t1 = t2;
8307
+ return pass1.forEach(function(p1) {
8308
+ for (t1 = 0, t2 = 0; t2 <= 1; )
8309
+ for (t2 = t1 + step; t2 <= 1 + step; t2 += step)
8310
+ if (segment = p1.split(t1, t2), !segment.simple()) {
8311
+ if (t2 -= step, abs(t1 - t2) < step)
8312
+ return [];
8313
+ segment = p1.split(t1, t2), segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2), segment._t2 = utils.map(t2, 0, 1, p1._t1, p1._t2), pass2.push(segment), t1 = t2;
8314
+ break;
7506
8315
  }
7507
- )
7508
- },
7509
- key
7510
- )) }),
7511
- /* @__PURE__ */ jsx(Flex, { mt: "sm", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: colors.map(({ key, value }) => /* @__PURE__ */ jsx(
7512
- Tooltip,
7513
- {
7514
- label: key,
7515
- fz: "xs",
7516
- color: "dark",
7517
- offset: 2,
7518
- transitionProps: { duration: 140, transition: "slide-up" },
7519
- children: /* @__PURE__ */ jsx(
7520
- ColorSwatch,
7521
- {
7522
- color: value,
7523
- size: 20,
7524
- onClick: changeColor(key),
7525
- style: { color: "#fff", cursor: "pointer" },
7526
- children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
8316
+ t1 < 1 && (segment = p1.split(t1, 1), segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2), segment._t2 = p1._t2, pass2.push(segment));
8317
+ }), pass2;
8318
+ }
8319
+ translate(v, d1, d2) {
8320
+ d2 = typeof d2 == "number" ? d2 : d1;
8321
+ const o = this.order;
8322
+ let d = this.points.map((_, i) => (1 - i / o) * d1 + i / o * d2);
8323
+ return new Bezier(
8324
+ this.points.map((p, i) => ({
8325
+ x: p.x + v.x * d[i],
8326
+ y: p.y + v.y * d[i]
8327
+ }))
8328
+ );
8329
+ }
8330
+ scale(d) {
8331
+ const order = this.order;
8332
+ let distanceFn = !1;
8333
+ if (typeof d == "function" && (distanceFn = d), distanceFn && order === 2)
8334
+ return this.raise().scale(distanceFn);
8335
+ const clockwise = this.clockwise, points = this.points;
8336
+ if (this._linear)
8337
+ return this.translate(
8338
+ this.normal(0),
8339
+ distanceFn ? distanceFn(0) : d,
8340
+ distanceFn ? distanceFn(1) : d
8341
+ );
8342
+ const r1 = distanceFn ? distanceFn(0) : d, r2 = distanceFn ? distanceFn(1) : d, v = [this.offset(0, 10), this.offset(1, 10)], np = [], o = utils.lli4(v[0], v[0].c, v[1], v[1].c);
8343
+ if (!o)
8344
+ throw new Error("cannot scale this curve. Try reducing it first.");
8345
+ return [0, 1].forEach(function(t2) {
8346
+ const p = np[t2 * order] = utils.copy(points[t2 * order]);
8347
+ p.x += (t2 ? r2 : r1) * v[t2].n.x, p.y += (t2 ? r2 : r1) * v[t2].n.y;
8348
+ }), distanceFn ? ([0, 1].forEach(function(t2) {
8349
+ if (!(order === 2 && t2)) {
8350
+ var p = points[t2 + 1], ov = {
8351
+ x: p.x - o.x,
8352
+ y: p.y - o.y
8353
+ }, rc = distanceFn ? distanceFn((t2 + 1) / order) : d;
8354
+ distanceFn && !clockwise && (rc = -rc);
8355
+ var m = sqrt(ov.x * ov.x + ov.y * ov.y);
8356
+ ov.x /= m, ov.y /= m, np[t2 + 1] = {
8357
+ x: p.x + rc * ov.x,
8358
+ y: p.y + rc * ov.y
8359
+ };
8360
+ }
8361
+ }), new Bezier(np)) : ([0, 1].forEach((t2) => {
8362
+ if (order === 2 && t2)
8363
+ return;
8364
+ const p = np[t2 * order], d2 = this.derivative(t2), p2 = { x: p.x + d2.x, y: p.y + d2.y };
8365
+ np[t2 + 1] = utils.lli4(p, p2, o, points[t2 + 1]);
8366
+ }), new Bezier(np));
8367
+ }
8368
+ outline(d1, d2, d3, d4) {
8369
+ if (d2 = d2 === void 0 ? d1 : d2, this._linear) {
8370
+ const n = this.normal(0), start2 = this.points[0], end = this.points[this.points.length - 1];
8371
+ let s, mid, e;
8372
+ d3 === void 0 && (d3 = d1, d4 = d2), s = { x: start2.x + n.x * d1, y: start2.y + n.y * d1 }, e = { x: end.x + n.x * d3, y: end.y + n.y * d3 }, mid = { x: (s.x + e.x) / 2, y: (s.y + e.y) / 2 };
8373
+ const fline = [s, mid, e];
8374
+ s = { x: start2.x - n.x * d2, y: start2.y - n.y * d2 }, e = { x: end.x - n.x * d4, y: end.y - n.y * d4 }, mid = { x: (s.x + e.x) / 2, y: (s.y + e.y) / 2 };
8375
+ const bline = [e, mid, s], ls2 = utils.makeline(bline[2], fline[0]), le2 = utils.makeline(fline[2], bline[0]), segments2 = [ls2, new Bezier(fline), le2, new Bezier(bline)];
8376
+ return new PolyBezier(segments2);
8377
+ }
8378
+ const reduced = this.reduce(), len = reduced.length, fcurves = [];
8379
+ let bcurves = [], p, alen = 0, tlen = this.length();
8380
+ const graduated = typeof d3 < "u" && typeof d4 < "u";
8381
+ function linearDistanceFunction(s, e, tlen2, alen2, slen) {
8382
+ return function(v) {
8383
+ const f1 = alen2 / tlen2, f2 = (alen2 + slen) / tlen2, d = e - s;
8384
+ return utils.map(v, 0, 1, s + f1 * d, s + f2 * d);
8385
+ };
8386
+ }
8387
+ reduced.forEach(function(segment) {
8388
+ const slen = segment.length();
8389
+ graduated ? (fcurves.push(
8390
+ segment.scale(linearDistanceFunction(d1, d3, tlen, alen, slen))
8391
+ ), bcurves.push(
8392
+ segment.scale(linearDistanceFunction(-d2, -d4, tlen, alen, slen))
8393
+ )) : (fcurves.push(segment.scale(d1)), bcurves.push(segment.scale(-d2))), alen += slen;
8394
+ }), bcurves = bcurves.map(function(s) {
8395
+ return p = s.points, p[3] ? s.points = [p[3], p[2], p[1], p[0]] : s.points = [p[2], p[1], p[0]], s;
8396
+ }).reverse();
8397
+ const fs = fcurves[0].points[0], fe = fcurves[len - 1].points[fcurves[len - 1].points.length - 1], bs = bcurves[len - 1].points[bcurves[len - 1].points.length - 1], be = bcurves[0].points[0], ls = utils.makeline(bs, fs), le = utils.makeline(fe, be), segments = [ls].concat(fcurves).concat([le]).concat(bcurves);
8398
+ return new PolyBezier(segments);
8399
+ }
8400
+ outlineshapes(d1, d2, curveIntersectionThreshold) {
8401
+ d2 = d2 || d1;
8402
+ const outline = this.outline(d1, d2).curves, shapes = [];
8403
+ for (let i = 1, len = outline.length; i < len / 2; i++) {
8404
+ const shape = utils.makeshape(
8405
+ outline[i],
8406
+ outline[len - i],
8407
+ curveIntersectionThreshold
8408
+ );
8409
+ shape.startcap.virtual = i > 1, shape.endcap.virtual = i < len / 2 - 1, shapes.push(shape);
8410
+ }
8411
+ return shapes;
8412
+ }
8413
+ intersects(curve2, curveIntersectionThreshold) {
8414
+ return curve2 ? curve2.p1 && curve2.p2 ? this.lineIntersects(curve2) : (curve2 instanceof Bezier && (curve2 = curve2.reduce()), this.curveintersects(
8415
+ this.reduce(),
8416
+ curve2,
8417
+ curveIntersectionThreshold
8418
+ )) : this.selfintersects(curveIntersectionThreshold);
8419
+ }
8420
+ lineIntersects(line2) {
8421
+ const mx = min(line2.p1.x, line2.p2.x), my = min(line2.p1.y, line2.p2.y), MX = max(line2.p1.x, line2.p2.x), MY = max(line2.p1.y, line2.p2.y);
8422
+ return utils.roots(this.points, line2).filter((t2) => {
8423
+ var p = this.get(t2);
8424
+ return utils.between(p.x, mx, MX) && utils.between(p.y, my, MY);
8425
+ });
8426
+ }
8427
+ selfintersects(curveIntersectionThreshold) {
8428
+ const reduced = this.reduce(), len = reduced.length - 2, results = [];
8429
+ for (let i = 0, result, left, right; i < len; i++)
8430
+ left = reduced.slice(i, i + 1), right = reduced.slice(i + 2), result = this.curveintersects(left, right, curveIntersectionThreshold), results.push(...result);
8431
+ return results;
8432
+ }
8433
+ curveintersects(c1, c2, curveIntersectionThreshold) {
8434
+ const pairs = [];
8435
+ c1.forEach(function(l) {
8436
+ c2.forEach(function(r2) {
8437
+ l.overlaps(r2) && pairs.push({ left: l, right: r2 });
8438
+ });
8439
+ });
8440
+ let intersections = [];
8441
+ return pairs.forEach(function(pair) {
8442
+ const result = utils.pairiteration(
8443
+ pair.left,
8444
+ pair.right,
8445
+ curveIntersectionThreshold
8446
+ );
8447
+ result.length > 0 && (intersections = intersections.concat(result));
8448
+ }), intersections;
8449
+ }
8450
+ arcs(errorThreshold) {
8451
+ return errorThreshold = errorThreshold || 0.5, this._iterate(errorThreshold, []);
8452
+ }
8453
+ _error(pc, np1, s, e) {
8454
+ const q = (e - s) / 4, c1 = this.get(s + q), c2 = this.get(e - q), ref = utils.dist(pc, np1), d1 = utils.dist(pc, c1), d2 = utils.dist(pc, c2);
8455
+ return abs(d1 - ref) + abs(d2 - ref);
8456
+ }
8457
+ _iterate(errorThreshold, circles) {
8458
+ let t_s = 0, t_e = 1, safety;
8459
+ do {
8460
+ safety = 0, t_e = 1;
8461
+ let np1 = this.get(t_s), np2, np3, arc, prev_arc, curr_good = !1, prev_good = !1, done, t_m = t_e, prev_e = 1;
8462
+ do
8463
+ if (prev_good = curr_good, prev_arc = arc, t_m = (t_s + t_e) / 2, np2 = this.get(t_m), np3 = this.get(t_e), arc = utils.getccenter(np1, np2, np3), arc.interval = {
8464
+ start: t_s,
8465
+ end: t_e
8466
+ }, curr_good = this._error(arc, np1, t_s, t_e) <= errorThreshold, done = prev_good && !curr_good, done || (prev_e = t_e), curr_good) {
8467
+ if (t_e >= 1) {
8468
+ if (arc.interval.end = prev_e = 1, prev_arc = arc, t_e > 1) {
8469
+ let d = {
8470
+ x: arc.x + arc.r * cos(arc.e),
8471
+ y: arc.y + arc.r * sin(arc.e)
8472
+ };
8473
+ arc.e += utils.angle({ x: arc.x, y: arc.y }, d, this.get(1));
8474
+ }
8475
+ break;
7527
8476
  }
7528
- )
7529
- },
7530
- key
7531
- )) })
7532
- ] }) });
7533
- }
7534
- function ShapeOption({
7535
- nodes: [firstNode, ...nodes],
7536
- onShapeChange
7537
- }) {
7538
- let selectedShape = firstNode.data.element.shape;
7539
- return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs(Box, { children: [
7540
- /* @__PURE__ */ jsx(Divider, { label: "shape", labelPosition: "left" }),
7541
- /* @__PURE__ */ jsx(
7542
- Select,
7543
- {
7544
- mt: "xs",
7545
- size: "xs",
7546
- variant: "filled",
7547
- value: selectedShape,
7548
- placeholder: "[ multiple ]",
7549
- data: ElementShapes,
7550
- allowDeselect: !1,
7551
- checkIconPosition: "right",
7552
- onChange: (value) => {
7553
- !value || value === selectedShape || onShapeChange(value);
7554
- }
7555
- }
7556
- )
7557
- ] });
7558
- }
7559
- function NavigateToOption({
7560
- nodes: [node, ...nodes]
7561
- }) {
7562
- const isMultiple = nodes.length >= 1;
7563
- return /* @__PURE__ */ jsxs(Box, { children: [
7564
- /* @__PURE__ */ jsx(Divider, { label: "navigate to", labelPosition: "left" }),
7565
- /* @__PURE__ */ jsx(
7566
- Select,
7567
- {
7568
- mt: "xs",
7569
- size: "xs",
7570
- variant: "filled",
7571
- value: isMultiple ? null : node.data.element.navigateTo ?? null,
7572
- disabled: isMultiple,
7573
- placeholder: isMultiple ? "[ multiple ]" : "select",
7574
- data: node.data.element.navigateTo ? [{ value: node.data.element.navigateTo, label: node.data.element.navigateTo }] : [],
7575
- allowDeselect: !0,
7576
- checkIconPosition: "right"
7577
- }
7578
- )
7579
- ] });
8477
+ t_e = t_e + (t_e - t_s) / 2;
8478
+ } else
8479
+ t_e = t_m;
8480
+ while (!done && safety++ < 100);
8481
+ if (safety >= 100)
8482
+ break;
8483
+ prev_arc = prev_arc || arc, circles.push(prev_arc), t_s = prev_e;
8484
+ } while (t_e < 1);
8485
+ return circles;
8486
+ }
7580
8487
  }
7581
- var panel = "_1lmzt1h0";
7582
- const OptionsPanelMemo = /* @__PURE__ */ memo(function() {
7583
- const [selectedNodes, setSelectedNodes] = useState([]);
7584
- return useOnSelectionChange({
7585
- onChange: ({ nodes }) => {
7586
- const next = nodes.map((n) => n.id).sort();
7587
- setSelectedNodes((prev) => shallowEqual(prev, next) ? prev : next);
7588
- }
7589
- }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: selectedNodes.length > 0 && /* @__PURE__ */ jsx(
7590
- motion.div,
7591
- {
7592
- initial: { opacity: 0, scale: 0.85 },
7593
- animate: { opacity: 1, scale: 1 },
7594
- exit: {
7595
- opacity: 0,
7596
- scale: 0.85
7597
- },
7598
- transition: { duration: 0.14 },
7599
- className: clsx("react-flow__panel", panel),
7600
- style: {
7601
- transformOrigin: "center right"
7602
- },
7603
- children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
7604
- }
7605
- ) });
7606
- }), OptionsPanel2 = OptionsPanelMemo;
7607
8488
  function deriveEdgePoints(bezierSpline) {
7608
8489
  let [start2, ...bezierPoints] = bezierSpline;
7609
8490
  invariant(start2, "start should be defined");
@@ -7611,25 +8492,17 @@ function deriveEdgePoints(bezierSpline) {
7611
8492
  // start
7612
8493
  ];
7613
8494
  for (; hasAtLeast(bezierPoints, 3); ) {
7614
- const [cp1, cp2, end, ...rest] = bezierPoints, [centerX, centerY] = getBezierEdgeCenter({
7615
- sourceX: start2[0],
7616
- sourceY: start2[1],
7617
- targetX: end[0],
7618
- targetY: end[1],
7619
- sourceControlX: cp1[0],
7620
- sourceControlY: cp1[1],
7621
- targetControlX: cp2[0],
7622
- targetControlY: cp2[1]
7623
- });
7624
- handles.push(
7625
- [centerX, centerY]
7626
- ), bezierPoints = rest, start2 = end;
8495
+ const [cp1, cp2, end, ...rest] = bezierPoints, bezier = new Bezier(start2[0], start2[1], cp1[0], cp1[1], cp2[0], cp2[1], end[0], end[1]), inflections = bezier.inflections();
8496
+ inflections.length === 0 && inflections.push(0.5), inflections.forEach((t2) => {
8497
+ const { x, y } = bezier.get(t2);
8498
+ handles.push([x, y]);
8499
+ }), bezierPoints = rest, start2 = end;
7627
8500
  }
7628
8501
  return invariant(bezierPoints.length === 0, "all points should be consumed"), handles;
7629
8502
  }
7630
8503
  const nodeZIndex = (node) => node.level + 1;
7631
8504
  function diagramViewToXYFlowData(view, opts) {
7632
- const editor = {
8505
+ const isDynamicView = view.__ === "dynamic", editor = {
7633
8506
  nodes: [],
7634
8507
  edges: []
7635
8508
  }, nodeLookup = /* @__PURE__ */ new Map(), traverse = view.nodes.reduce(
@@ -7709,10 +8582,11 @@ function diagramViewToXYFlowData(view, opts) {
7709
8582
  controlPoints,
7710
8583
  headPoint: edge.headArrowPoint ?? null,
7711
8584
  tailPoint: edge.tailArrowPoint ?? null,
7712
- label: edge.labelBBox && edge.label ? {
8585
+ stepNum: isDynamicView ? extractStep(edge.id) : null,
8586
+ label: edge.labelBBox ? {
7713
8587
  bbox: edge.labelBBox,
7714
8588
  // text: edge.labels ? edge.labels.map(l => l.text).join('\n') : ''
7715
- text: edge.label
8589
+ text: edge.label ?? ""
7716
8590
  } : null
7717
8591
  },
7718
8592
  // markerEnd: {
@@ -7723,126 +8597,162 @@ function diagramViewToXYFlowData(view, opts) {
7723
8597
  }
7724
8598
  return editor;
7725
8599
  }
8600
+ function toDomPrecision(v) {
8601
+ return v === null ? 0.01 : Math.round(v * 100) / 100;
8602
+ }
7726
8603
  function selectDimensions(state) {
7727
8604
  return `${Math.round(state.width)}:${Math.round(state.height)}`;
7728
8605
  }
7729
- function FitViewOnViewportResize({ diagramApi }) {
8606
+ function FitViewOnViewportResize({ diagramApi, xyflowApi }) {
7730
8607
  const dimensions = useXYStore(selectDimensions), prevDimensionsRef = useRef(dimensions);
7731
8608
  return useDebouncedEffect(
7732
8609
  () => {
7733
- prevDimensionsRef.current !== dimensions && (diagramApi.getState().fitDiagram(), prevDimensionsRef.current = dimensions);
8610
+ const { focusedNodeId, fitDiagram } = diagramApi.getState();
8611
+ focusedNodeId || prevDimensionsRef.current === dimensions || (fitDiagram(xyflowApi), prevDimensionsRef.current = dimensions);
7734
8612
  },
7735
- [dimensions],
7736
- 150
8613
+ [dimensions, diagramApi, xyflowApi],
8614
+ 200,
8615
+ 800
7737
8616
  ), null;
7738
8617
  }
7739
- const diagramChangeId = (s) => s.view.id + "_" + s.view.autoLayout + "_" + s.fitViewPadding;
7740
- function FitViewOnDiagramChanges() {
7741
- const diagramApi = useDiagramStoreApi(), [viewportMoved, setViewportMoved] = useState(diagramApi.getState().viewportChanged), [processedChangeId, setProcessed] = useState(diagramChangeId(diagramApi.getState())), [pendingChangeId, setPending] = useState(processedChangeId), isReady = useNodesInitialized({
7742
- includeHiddenNodes: !0
7743
- }), schedulePending = useDebouncedCallback(
7744
- (pendingChangeId2) => {
7745
- setPending(pendingChangeId2);
7746
- },
7747
- [setPending],
7748
- 75
7749
- );
7750
- return useEffect(
7751
- () => diagramApi.subscribe(
7752
- (s) => diagramChangeId(s),
7753
- schedulePending
7754
- ),
7755
- [diagramApi, schedulePending]
7756
- ), useEffect(
7757
- () => diagramApi.subscribe(
7758
- (s) => s.viewportChanged,
7759
- setViewportMoved
7760
- ),
7761
- [diagramApi]
7762
- ), useRafEffect(
7763
- () => {
7764
- !isReady || processedChangeId === pendingChangeId || (diagramApi.getState().fitDiagram(), setProcessed(pendingChangeId));
7765
- },
7766
- [isReady, processedChangeId, pendingChangeId]
7767
- ), !viewportMoved && isReady ? /* @__PURE__ */ jsx(FitViewOnViewportResize, { diagramApi }) : null;
7768
- }
7769
- const selectFitViewFlag = (s) => s.fitViewEnabled, FitViewOnDiagramChange = memo(() => useDiagramState(selectFitViewFlag) ? /* @__PURE__ */ jsx(FitViewOnDiagramChanges, {}) : null);
7770
- function toDomPrecision(v) {
7771
- return v === null ? 0.01 : Math.round(v * 100) / 100;
8618
+ function selector$2({ view, xyflowSynced, viewportChanged, lastOnNavigate, ...s }) {
8619
+ const viewId = view.id + "_" + view.autoLayout + "_" + s.fitViewPadding, waitCorrection = lastOnNavigate && lastOnNavigate.toView === view.id && lastOnNavigate.positionCorrected === !1, elTo = waitCorrection ? view.nodes.find((n) => n.id === lastOnNavigate.element.id) : void 0;
8620
+ return waitCorrection && elTo ? {
8621
+ viewId,
8622
+ xyflowSynced,
8623
+ viewportChanged,
8624
+ waitCorrection: !0,
8625
+ elFrom: lastOnNavigate.element,
8626
+ elTo
8627
+ } : {
8628
+ viewId,
8629
+ xyflowSynced,
8630
+ viewportChanged,
8631
+ waitCorrection: !1,
8632
+ fromElement: null,
8633
+ toElement: null
8634
+ };
7772
8635
  }
7773
- const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is(a.parentId, b.parentId), SyncWithDiagram = memo(() => {
7774
- const _xyflow = useXYFlow(), xyflowRef = useRef(_xyflow);
7775
- xyflowRef.current = _xyflow;
7776
- const xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
7777
- return useEffect(() => diagramStoreApi.subscribe(
7778
- // selector
7779
- (state) => ({
7780
- viewId: state.view.id,
7781
- nodes: state.view.nodes,
7782
- edges: state.view.edges,
7783
- draggable: state.nodesDraggable,
7784
- selectable: state.nodesSelectable
7785
- }),
7786
- // listener
7787
- ({ viewId, nodes, edges, ...opts }) => {
7788
- const { lastOnNavigate } = diagramStoreApi.getState(), updates = diagramViewToXYFlowData({ nodes, edges }, opts);
7789
- if (xyflowRef.current.setNodes(
7790
- (prev) => updates.nodes.map((update) => {
7791
- const existing = prev.find(isSameNode(update));
7792
- return existing ? deepEqual(existing.data.element, update.data.element) ? existing : {
7793
- ...existing,
7794
- ...update
7795
- } : update;
7796
- })
7797
- ), xyflowRef.current.setEdges(
7798
- (prev) => updates.edges.map((update) => {
7799
- const existing = prev.find((e) => e.id === update.id);
7800
- return existing ? deepEqual(existing.data, update.data) ? existing : {
7801
- ...existing,
7802
- ...update
7803
- } : update;
7804
- })
7805
- ), (lastOnNavigate == null ? void 0 : lastOnNavigate.toView) === viewId && lastOnNavigate.positionCorrected !== !0) {
7806
- const elFrom = lastOnNavigate.element, elTo = nodes.find((n) => n.id === elFrom.id);
7807
- if (elTo) {
7808
- const centerFrom = lastOnNavigate.elementCenterScreenPosition;
7809
- let nextZoom = Math.min(elFrom.width / elTo.width, elFrom.height / elTo.height);
7810
- requestAnimationFrame(() => {
7811
- requestAnimationFrame(() => {
7812
- const v = xyflowRef.current.getViewport();
7813
- nextZoom < v.zoom && (nextZoom = Math.max(nextZoom, v.zoom * 0.5), xyflowRef.current.setViewport({
7814
- x: v.x,
7815
- y: v.y,
7816
- zoom: nextZoom
7817
- }));
7818
- const centerTo = xyflowRef.current.flowToScreenPosition({
7819
- x: elTo.position[0] + elTo.width / 2,
7820
- y: elTo.position[1] + elTo.height / 2
7821
- }), diff = {
7822
- x: toDomPrecision(centerFrom.x - centerTo.x),
7823
- y: toDomPrecision(centerFrom.y - centerTo.y)
7824
- };
7825
- xyflowApi.getState().panBy(diff);
7826
- });
7827
- });
7828
- }
7829
- diagramStoreApi.setState(
7830
- {
7831
- lastOnNavigate: {
7832
- ...lastOnNavigate,
7833
- positionCorrected: !0
7834
- }
7835
- },
7836
- !1,
7837
- "positionCorrected"
7838
- );
8636
+ function FitViewOnDiagramChange() {
8637
+ const xyflowApi = useXYStoreApi(), {
8638
+ viewId: pendingViewId,
8639
+ xyflowSynced,
8640
+ viewportChanged,
8641
+ waitCorrection,
8642
+ elFrom,
8643
+ elTo
8644
+ } = useDiagramState(selector$2), diagramApi = useDiagramStoreApi(), processedRef = useRef(pendingViewId);
8645
+ return useEffect(() => {
8646
+ if (!(!xyflowSynced || pendingViewId === processedRef.current)) {
8647
+ if (waitCorrection && elTo && elFrom) {
8648
+ const [x, y, zoom2] = xyflowApi.getState().transform, { xyflow, lastOnNavigate } = diagramApi.getState(), nextZoom = Math.min(
8649
+ elFrom.width / elTo.width,
8650
+ elFrom.height / elTo.height
8651
+ ), centerFrom = lastOnNavigate.elementCenterScreenPosition;
8652
+ nextZoom !== 1 && nextZoom < zoom2 && (xyflowApi.setState({ transform: [x, y, nextZoom] }), xyflow.setViewport({
8653
+ x,
8654
+ y,
8655
+ zoom: nextZoom
8656
+ }));
8657
+ const centerTo = xyflow.flowToScreenPosition({
8658
+ x: elTo.position[0] + elTo.width / 2,
8659
+ y: elTo.position[1] + elTo.height / 2
8660
+ }), diff = {
8661
+ x: toDomPrecision(centerFrom.x - centerTo.x),
8662
+ y: toDomPrecision(centerFrom.y - centerTo.y)
8663
+ };
8664
+ xyflowApi.getState().panBy(diff), diagramApi.setState({ lastOnNavigate: null });
8665
+ return;
7839
8666
  }
7840
- },
7841
- {
7842
- equalityFn: shallowEqual
8667
+ processedRef.current = pendingViewId, diagramApi.getState().fitDiagram(xyflowApi);
7843
8668
  }
7844
- ), [xyflowApi, diagramStoreApi]), null;
7845
- });
8669
+ }, [pendingViewId, xyflowSynced, waitCorrection]), !viewportChanged && xyflowSynced ? /* @__PURE__ */ jsx(FitViewOnViewportResize, { xyflowApi, diagramApi }) : null;
8670
+ }
8671
+ function SelectEdgesOnNodeFocus() {
8672
+ const focusedNodeId = useDiagramState((s) => s.focusedNodeId), diagramStore = useDiagramStoreApi(), xyflowApi = useXYStoreApi();
8673
+ return useUpdateEffect(() => {
8674
+ if (!focusedNodeId) {
8675
+ xyflowApi.getState().resetSelectedElements();
8676
+ return;
8677
+ }
8678
+ const edgeChanges = [], nodeChanges = [], { edgeLookup, nodeLookup, transform: transform2, triggerNodeChanges, fitView: fitView2, triggerEdgeChanges } = xyflowApi.getState(), fitViewNodes = /* @__PURE__ */ new Set();
8679
+ fitViewNodes.add(nonNullable(nodeLookup.get(focusedNodeId)));
8680
+ for (const [, edge] of edgeLookup)
8681
+ if (edge.source === focusedNodeId || edge.target === focusedNodeId) {
8682
+ edgeChanges.push({
8683
+ id: edge.id,
8684
+ type: "select",
8685
+ selected: !0
8686
+ });
8687
+ const anotherNode = nodeLookup.get(edge.source === focusedNodeId ? edge.target : edge.source);
8688
+ anotherNode && fitViewNodes.add(anotherNode);
8689
+ } else
8690
+ edge.selected && edgeChanges.push({
8691
+ id: edge.id,
8692
+ type: "select",
8693
+ selected: !1
8694
+ });
8695
+ for (const [, node] of nodeLookup)
8696
+ node.selected && node.id !== focusedNodeId && nodeChanges.push({
8697
+ id: node.id,
8698
+ type: "select",
8699
+ selected: !1
8700
+ });
8701
+ nodeChanges.push({
8702
+ id: focusedNodeId,
8703
+ type: "select",
8704
+ selected: !0
8705
+ }), edgeChanges.length > 0 && triggerEdgeChanges(edgeChanges), triggerNodeChanges(nodeChanges), fitView2({
8706
+ includeHiddenNodes: !0,
8707
+ duration: 300,
8708
+ padding: 0.1,
8709
+ minZoom: MinZoom,
8710
+ maxZoom: Math.max(1, transform2[2]),
8711
+ nodes: Array.from(fitViewNodes)
8712
+ });
8713
+ }, [diagramStore, xyflowApi, focusedNodeId]), null;
8714
+ }
8715
+ function SyncWithDiagram() {
8716
+ const xyflowSynced = useDiagramState((s) => s.xyflowSynced), xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
8717
+ return useEffect(() => {
8718
+ if (xyflowSynced)
8719
+ return;
8720
+ const {
8721
+ view,
8722
+ nodesDraggable,
8723
+ nodesSelectable,
8724
+ focusedNodeId
8725
+ } = diagramStoreApi.getState(), updates = diagramViewToXYFlowData(view, {
8726
+ draggable: nodesDraggable,
8727
+ selectable: nodesSelectable || focusedNodeId !== null
8728
+ }), {
8729
+ nodeLookup,
8730
+ edgeLookup,
8731
+ setNodes,
8732
+ setEdges
8733
+ } = xyflowApi.getState();
8734
+ setNodes(updates.nodes.map((update) => {
8735
+ var _a;
8736
+ const existing = (_a = nodeLookup.get(update.id)) == null ? void 0 : _a.internals.userNode;
8737
+ return existing && existing.type === update.type && deepEqual(existing.parentId, update.parentId) ? deepEqual(existing.data.element, update.data.element) ? existing : {
8738
+ ...existing,
8739
+ ...update
8740
+ } : update;
8741
+ })), setEdges(updates.edges.map((update) => {
8742
+ const existing = edgeLookup.get(update.id);
8743
+ return existing ? deepEqual(existing.data.edge, update.data.edge) ? existing : {
8744
+ ...existing,
8745
+ ...update
8746
+ } : update;
8747
+ })), diagramStoreApi.setState(
8748
+ {
8749
+ xyflowSynced: !0
8750
+ },
8751
+ !1,
8752
+ "xyflowSynced"
8753
+ );
8754
+ }, [xyflowSynced, xyflowApi, diagramStoreApi]), null;
8755
+ }
7846
8756
  function getVarName(variable) {
7847
8757
  var matches = variable.match(/^var\((.*)\)$/);
7848
8758
  return matches ? matches[1] : variable;
@@ -7888,7 +8798,14 @@ function assignInlineVars(varsOrContract, tokens) {
7888
8798
  writable: !1
7889
8799
  }), styles;
7890
8800
  }
7891
- var container$2 = "bexn7q0", edgePathBg = "bexn7q1", fillStrokeCtx = "bexn7q2", cssEdgePath = "bexn7q3", varLabelX = "var(--bexn7q4)", varLabelY = "var(--bexn7q5)", edgeLabel = "bexn7q7", edgeLabelBody = "bexn7q8";
8801
+ var container$4 = "bexn7q1", dimmed$2 = "bexn7q2", edgePathBg = "bexn7q3", markerContext = "bexn7q4", controlPoint = "bexn7q5", cssEdgePath = "bexn7q7", varLabelX = "var(--bexn7q8)", varLabelY = "var(--bexn7q9)", edgeLabel = "bexn7qb", stepEdgeNumber = "bexn7qc", edgeLabelText = "bexn7qd";
8802
+ function getNodeIntersectionFromCenterToPoint(intersectionNode, [x1, y1]) {
8803
+ const {
8804
+ width: intersectionNodeWidth,
8805
+ height: intersectionNodeHeight
8806
+ } = getNodeDimensions(intersectionNode), intersectionNodePosition = intersectionNode.internals.positionAbsolute, w = intersectionNodeWidth / 2, h = intersectionNodeHeight / 2, x2 = intersectionNodePosition.x + w, y2 = intersectionNodePosition.y + h, xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h), yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h), a = 1 / (Math.abs(xx1) + Math.abs(yy1)), xx3 = a * xx1, yy3 = a * yy1, x = w * (xx3 + yy3) + x2, y = h * (-xx3 + yy3) + y2;
8807
+ return [x, y];
8808
+ }
7892
8809
  function getNodeIntersection(intersectionNode, targetNode) {
7893
8810
  const {
7894
8811
  width: intersectionNodeWidth,
@@ -7950,28 +8867,29 @@ function bezierPath(bezierSpline) {
7950
8867
  }
7951
8868
  return invariant(points.length === 0, "all points should be consumed"), path;
7952
8869
  }
7953
- const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data, next.data), RelationshipEdge = /* @__PURE__ */ memo(function({
8870
+ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && deepEqual(prev.selected ?? !1, next.selected ?? !1) && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data.stepNum, next.data.stepNum) && deepEqual(prev.data.edge, next.data.edge) && zip(prev.data.controlPoints, next.data.controlPoints).every(
8871
+ ([a, b]) => isSamePoint(a[0], b[0]) && isSamePoint(a[1], b[1])
8872
+ ), curve = line().curve(curveCatmullRomOpen), RelationshipEdge = /* @__PURE__ */ memo(function({
7954
8873
  id: id2,
7955
8874
  data,
7956
8875
  selected: _selected,
7957
- markerEnd: _markerEnd,
7958
8876
  style: style2,
7959
8877
  source,
7960
8878
  target,
7961
8879
  interactionWidth
7962
8880
  }) {
7963
- var _a, _b, _c;
7964
- const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isNotModified = isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) && isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position);
7965
- invariant(data, "data is required");
7966
- const {
7967
- edge
7968
- } = data, color2 = edge.color ?? "gray", isHovered = useDiagramState((s) => s.hoveredEdgeId === id2), line = edge.line ?? "dashed", isDotted = line === "dotted", isDashed = isDotted || line === "dashed";
8881
+ var _a, _b, _c, _d;
8882
+ const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isModified = !isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) || !isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position), { edge: diagramEdge, controlPoints } = data, color2 = diagramEdge.color ?? "gray", isStepEdge = data.stepNum !== null, { isActive, isHovered, isDimmed } = useDiagramState((s) => ({
8883
+ isActive: s.activeDynamicViewStep !== null && s.activeDynamicViewStep === data.stepNum,
8884
+ isHovered: s.hoveredEdgeId === id2,
8885
+ isDimmed: s.dimmed.has(id2)
8886
+ })), line2 = diagramEdge.line ?? "dashed", isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
7969
8887
  let strokeDasharray;
7970
8888
  isDotted ? strokeDasharray = "1,8" : isDashed && (strokeDasharray = "8,10");
7971
8889
  const marker = `url(#arrow-${id2})`;
7972
8890
  let edgePath, labelX, labelY;
7973
- if (isNotModified)
7974
- edgePath = bezierPath(edge.points), labelX = ((_a = data.label) == null ? void 0 : _a.bbox.x) ?? 0, labelY = ((_b = data.label) == null ? void 0 : _b.bbox.y) ?? 0;
8891
+ if (!isModified)
8892
+ edgePath = bezierPath(diagramEdge.points), labelX = ((_a = data.label) == null ? void 0 : _a.bbox.x) ?? 0, labelY = ((_b = data.label) == null ? void 0 : _b.bbox.y) ?? 0;
7975
8893
  else {
7976
8894
  const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode), [_edgePath, _labelX, _labelY] = getBezierPath({
7977
8895
  sourceX: sx,
@@ -7982,55 +8900,96 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
7982
8900
  targetY: ty
7983
8901
  });
7984
8902
  edgePath = _edgePath, labelX = _labelX, labelY = _labelY;
8903
+ const sourceCenterPos = getNodePositionWithOrigin(sourceNode, [-0.5, -0.5]), targetCenterPos = getNodePositionWithOrigin(targetNode, [-0.5, -0.5]);
8904
+ edgePath = curve([
8905
+ [sourceCenterPos.positionAbsolute.x, sourceCenterPos.positionAbsolute.y],
8906
+ getNodeIntersectionFromCenterToPoint(sourceNode, first(controlPoints)),
8907
+ ...controlPoints,
8908
+ getNodeIntersectionFromCenterToPoint(targetNode, last(controlPoints)),
8909
+ [targetCenterPos.positionAbsolute.x, targetCenterPos.positionAbsolute.y]
8910
+ ]);
7985
8911
  }
7986
- return /* @__PURE__ */ jsxs("g", { className: clsx(container$2), "data-likec4-color": color2, "data-edge-hovered": isHovered, children: [
7987
- /* @__PURE__ */ jsx("g", { className: clsx(fillStrokeCtx), children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
7988
- "marker",
7989
- {
7990
- id: `arrow-${id2}`,
7991
- viewBox: "0 0 10 8",
7992
- refX: "0",
7993
- refY: "4",
7994
- markerWidth: "5",
7995
- markerHeight: "5",
7996
- markerUnits: "strokeWidth",
7997
- preserveAspectRatio: "xMaxYMid meet",
7998
- orient: "auto-start-reverse",
7999
- children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 10 4 L 0 8 z", stroke: "context-stroke", fill: "context-stroke" })
8000
- }
8001
- ) }) }),
8002
- /* @__PURE__ */ jsx(
8003
- RelationshipPath,
8004
- {
8005
- edgePath,
8006
- interactionWidth: interactionWidth ?? 10,
8007
- strokeDasharray,
8008
- markerStart: edge.tailArrow ? marker : void 0,
8009
- markerEnd: edge.headArrow ? marker : void 0,
8010
- style: style2
8011
- }
8012
- ),
8013
- data.label && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
8014
- Box,
8015
- {
8016
- className: clsx(container$2, edgeLabel),
8017
- "data-likec4-color": color2,
8018
- style: {
8019
- ...assignInlineVars({
8020
- [varLabelX]: toDomPrecision(labelX) + "px",
8021
- [varLabelY]: toDomPrecision(labelY) + "px"
8022
- }),
8023
- maxWidth: data.label.bbox.width + 10,
8024
- zIndex: ((_c = edgeLookup.get(id2)) == null ? void 0 : _c.zIndex) ?? ZIndexes.Edge
8025
- },
8026
- mod: {
8027
- "data-edge-hovered": isHovered
8028
- },
8029
- children: /* @__PURE__ */ jsx(Box, { className: edgeLabelBody, children: data.label.text })
8030
- }
8031
- ) })
8032
- ] });
8033
- }, isEqualProps), RelationshipPath = memo(({
8912
+ return /* @__PURE__ */ jsxs(
8913
+ "g",
8914
+ {
8915
+ className: clsx([
8916
+ container$4,
8917
+ isDimmed && dimmed$2
8918
+ ]),
8919
+ "data-likec4-color": color2,
8920
+ "data-edge-dir": diagramEdge.dir,
8921
+ "data-edge-active": isActive,
8922
+ "data-edge-hovered": isHovered,
8923
+ children: [
8924
+ /* @__PURE__ */ jsx("g", { className: markerContext, children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8925
+ "marker",
8926
+ {
8927
+ id: `arrow-${id2}`,
8928
+ viewBox: "0 0 16 10",
8929
+ refX: isModified ? "12" : "10",
8930
+ refY: "5",
8931
+ markerWidth: "5",
8932
+ markerHeight: "4",
8933
+ markerUnits: "strokeWidth",
8934
+ preserveAspectRatio: "xMaxYMid meet",
8935
+ orient: "auto-start-reverse",
8936
+ children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 16 5 L 0 10 z", stroke: "context-stroke", fill: "context-stroke" })
8937
+ }
8938
+ ) }) }),
8939
+ /* @__PURE__ */ jsx(
8940
+ RelationshipPath,
8941
+ {
8942
+ edgePath,
8943
+ interactionWidth: interactionWidth ?? 10,
8944
+ strokeDasharray,
8945
+ markerStart: diagramEdge.tailArrow ? marker : void 0,
8946
+ markerEnd: diagramEdge.headArrow ? marker : void 0,
8947
+ style: style2
8948
+ }
8949
+ ),
8950
+ isModified && controlPoints.map((p, i) => /* @__PURE__ */ jsx(
8951
+ "circle",
8952
+ {
8953
+ className: controlPoint,
8954
+ cx: p[0],
8955
+ cy: p[1],
8956
+ r: 3
8957
+ },
8958
+ i
8959
+ )),
8960
+ (data.label || isStepEdge) && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsxs(
8961
+ Box,
8962
+ {
8963
+ className: clsx([
8964
+ container$4,
8965
+ edgeLabel,
8966
+ isDimmed && dimmed$2
8967
+ ]),
8968
+ "data-likec4-color": color2,
8969
+ style: {
8970
+ ...assignInlineVars({
8971
+ [varLabelX]: Math.floor(labelX) + "px",
8972
+ [varLabelY]: Math.floor(labelY) + "px"
8973
+ }),
8974
+ ...data.label && {
8975
+ maxWidth: data.label.bbox.width + 12
8976
+ },
8977
+ zIndex: ((_c = edgeLookup.get(id2)) == null ? void 0 : _c.zIndex) ?? ZIndexes.Edge
8978
+ },
8979
+ mod: {
8980
+ "data-edge-hovered": isHovered,
8981
+ "data-edge-active": isActive
8982
+ },
8983
+ children: [
8984
+ isStepEdge && /* @__PURE__ */ jsx(Box, { className: stepEdgeNumber, children: data.stepNum }),
8985
+ ((_d = data.label) == null ? void 0 : _d.text) && /* @__PURE__ */ jsx(Box, { className: edgeLabelText, children: data.label.text })
8986
+ ]
8987
+ }
8988
+ ) })
8989
+ ]
8990
+ }
8991
+ );
8992
+ }, isEqualProps), RelationshipPath = ({
8034
8993
  edgePath,
8035
8994
  interactionWidth,
8036
8995
  strokeDasharray,
@@ -8069,7 +9028,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
8069
9028
  strokeWidth: interactionWidth
8070
9029
  }
8071
9030
  )
8072
- ] })), Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9031
+ ] }), Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8073
9032
  "svg",
8074
9033
  {
8075
9034
  ref,
@@ -8122,6 +9081,7 @@ function NavigateToBtn({ xynodeId, className }) {
8122
9081
  {
8123
9082
  className: clsx("nodrag nopan", className),
8124
9083
  radius: "xl",
9084
+ onPointerDownCapture: (e) => e.stopPropagation(),
8125
9085
  onClick: (event) => {
8126
9086
  event.stopPropagation(), diagramApi.getState().triggerOnNavigateTo(xynodeId, event);
8127
9087
  },
@@ -8130,27 +9090,29 @@ function NavigateToBtn({ xynodeId, className }) {
8130
9090
  }
8131
9091
  );
8132
9092
  }
8133
- var container$1 = "lbtzdo0", varTransparency = "var(--lbtzdo1)", compoundBody = "lbtzdo2", transparent = "lbtzdo5", title$1 = "lbtzdo6", indicator$1 = "lbtzdoa", navigateBtn = "lbtzdoc";
9093
+ var container$3 = "lbtzdo0", dimmed$1 = "lbtzdo1", varTransparency = "var(--lbtzdo2)", compoundBody = "lbtzdo3", transparent = "lbtzdo6", title$2 = "lbtzdo7", indicator$1 = "lbtzdob", navigateBtn = "lbtzdod";
8134
9094
  const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8135
9095
  id: id2,
8136
9096
  data: {
8137
- element
9097
+ element: element2
8138
9098
  }
8139
9099
  }) {
8140
- const { color: color2, style: style2, depth = 1, ...compound } = element, opacity = style2.opacity ?? 100, { isHovered, hasOnNavigateTo } = useDiagramState((s) => ({
9100
+ const { color: color2, style: style2, depth = 1, ...compound } = element2, opacity = style2.opacity ?? 100, { isHovered, isDimmed, hasOnNavigateTo } = useDiagramState((s) => ({
8141
9101
  isHovered: s.hoveredNodeId === id2,
9102
+ isDimmed: s.dimmed.has(id2),
8142
9103
  hasOnNavigateTo: !!s.onNavigateTo
8143
9104
  })), isnavigable = !!compound.navigateTo && hasOnNavigateTo, transparency = clamp$1(100 - opacity, {
8144
9105
  min: 0,
8145
- max: 98
9106
+ max: 99
8146
9107
  });
8147
9108
  return /* @__PURE__ */ jsxs(
8148
9109
  Box,
8149
9110
  {
8150
9111
  className: clsx(
8151
- container$1,
9112
+ container$3,
8152
9113
  "likec4-compound-node",
8153
- opacity < 100 && "likec4-compound-transparent"
9114
+ opacity < 100 && "likec4-compound-transparent",
9115
+ isDimmed && dimmed$1
8154
9116
  ),
8155
9117
  mod: {
8156
9118
  "compound-depth": depth,
@@ -8192,7 +9154,7 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8192
9154
  Text,
8193
9155
  {
8194
9156
  component: "div",
8195
- className: clsx(title$1, "likec4-compound-title"),
9157
+ className: clsx(title$2, "likec4-compound-title"),
8196
9158
  children: compound.title
8197
9159
  }
8198
9160
  )
@@ -8211,7 +9173,7 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8211
9173
  }
8212
9174
  );
8213
9175
  });
8214
- var container = "_1b6tkn2", indicator = "_1b6tkn4", fillElementFill = "_1b6tkn5", fillMixStroke = "_1b6tkn7", title = "_1b6tkn8", description = "_1b6tkn9", technology = "_1b6tkna", cssElement = "_1b6tknb", iconMaxH = "var(--_1b6tknc)", elementIcon = "_1b6tknd", cssShapeSvg = "_1b6tkng", cssNavigateBtn = "_1b6tknh";
9176
+ var container$2 = "_1b6tkn2", dimmed = "_1b6tkn3", indicator = "_1b6tkn5", fillElementFill = "_1b6tkn6", fillMixStroke = "_1b6tkn8", title$1 = "_1b6tkn9", description$1 = "_1b6tkna", technology = "_1b6tknb", element = "_1b6tknc", iconMaxH = "var(--_1b6tknd)", elementIcon = "_1b6tkne", cssShapeSvg = "_1b6tknh", cssNavigateBtn = "_1b6tkni";
8215
9177
  function ElementIcon({
8216
9178
  node,
8217
9179
  paddingY = 32
@@ -8241,9 +9203,9 @@ function ElementIcon({
8241
9203
  }
8242
9204
  var elementLink = "_4ysv0o0", trigger = "_4ysv0o1";
8243
9205
  function ElementLink({
8244
- element
9206
+ element: element2
8245
9207
  }) {
8246
- invariant(element.links, "ElementLink: links are required");
9208
+ invariant(element2.links, "ElementLink: links are required");
8247
9209
  const id2 = useId();
8248
9210
  return /* @__PURE__ */ jsx("div", { className: elementLink, "data-likec4-linkid": id2, children: /* @__PURE__ */ jsxs(
8249
9211
  HoverCard,
@@ -8277,10 +9239,28 @@ function ElementLink({
8277
9239
  ]
8278
9240
  }
8279
9241
  ) }),
8280
- /* @__PURE__ */ jsx(HoverCardDropdown, { onClick: (e) => e.stopPropagation(), p: "xs", children: /* @__PURE__ */ jsx(Stack, { gap: "xs", children: element.links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: "sm", children: [
8281
- /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "clip", maxWidth: clamp$1(element.width, { min: 200, max: 400 }) }, children: /* @__PURE__ */ jsx(Anchor, { href: link, target: "_blank", fz: "13", truncate: "end", children: link }) }),
8282
- /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Button, { size: "compact-xs", fz: "12", onClick: copy, color: copied ? "teal" : "gray", children: copied ? "Copied" : "Copy" }) })
8283
- ] }, link)) }) })
9242
+ /* @__PURE__ */ jsx(
9243
+ HoverCardDropdown,
9244
+ {
9245
+ onPointerDownCapture: (e) => e.stopPropagation(),
9246
+ onClick: (e) => e.stopPropagation(),
9247
+ p: "xs",
9248
+ children: /* @__PURE__ */ jsx(Stack, { gap: "xs", children: element2.links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: "sm", children: [
9249
+ /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "clip", maxWidth: clamp$1(element2.width, { min: 200, max: 400 }) }, children: /* @__PURE__ */ jsx(Anchor, { href: link, target: "_blank", fz: "13", truncate: "end", children: link }) }),
9250
+ /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
9251
+ Button,
9252
+ {
9253
+ size: "compact-xs",
9254
+ fz: "10",
9255
+ variant: "light",
9256
+ onClick: copy,
9257
+ color: copied ? "teal" : "gray",
9258
+ children: copied ? "copied" : "copy"
9259
+ }
9260
+ ) })
9261
+ ] }, link)) })
9262
+ }
9263
+ )
8284
9264
  ]
8285
9265
  }
8286
9266
  ) });
@@ -8448,6 +9428,13 @@ const selectedScale = 1.015, variants = {
8448
9428
  delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
8449
9429
  }
8450
9430
  }),
9431
+ // dimmed: {
9432
+ // filter: 'brightness(0.5)',
9433
+ // transition: {
9434
+ // duration: 0.8,
9435
+ // ease: 'easeInOut',
9436
+ // }
9437
+ // },
8451
9438
  // dragging: {
8452
9439
  // scale: selectedScale
8453
9440
  // },
@@ -8478,19 +9465,20 @@ const selectedScale = 1.015, variants = {
8478
9465
  function ElementNode({
8479
9466
  id: id2,
8480
9467
  data: {
8481
- element
9468
+ element: element$1
8482
9469
  },
8483
9470
  dragging,
8484
9471
  selected: selected2 = !1,
8485
9472
  width,
8486
9473
  height
8487
9474
  }) {
8488
- const { isHovered, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
9475
+ const { isHovered, isDimmed, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
8489
9476
  isHovered: s.hoveredNodeId === id2,
9477
+ isDimmed: s.dimmed.has(id2),
8490
9478
  isInteractive: s.nodesDraggable || s.nodesSelectable || !!s.onNavigateTo,
8491
9479
  isHovercards: s.showElementLinks,
8492
9480
  hasOnNavigateTo: !!s.onNavigateTo
8493
- })), isNavigable = hasOnNavigateTo && !!element.navigateTo, w = toDomPrecision(width ?? element.width), h = toDomPrecision(height ?? element.height);
9481
+ })), isNavigable = hasOnNavigateTo && !!element$1.navigateTo, w = toDomPrecision(width ?? element$1.width), h = toDomPrecision(height ?? element$1.height);
8494
9482
  let animate = "idle";
8495
9483
  switch (!0) {
8496
9484
  case (dragging && selected2):
@@ -8510,9 +9498,13 @@ function ElementNode({
8510
9498
  motion.div,
8511
9499
  {
8512
9500
  id: id2,
8513
- className: clsx(container, "likec4-element-node"),
8514
- "data-likec4-color": element.color,
8515
- "data-likec4-shape": element.shape,
9501
+ className: clsx([
9502
+ container$2,
9503
+ isDimmed && dimmed,
9504
+ "likec4-element-node"
9505
+ ]),
9506
+ "data-likec4-color": element$1.color,
9507
+ "data-likec4-shape": element$1.shape,
8516
9508
  variants,
8517
9509
  initial: !1,
8518
9510
  animate,
@@ -8531,7 +9523,9 @@ function ElementNode({
8531
9523
  /* @__PURE__ */ jsxs(
8532
9524
  "svg",
8533
9525
  {
8534
- className: cssShapeSvg,
9526
+ className: clsx(
9527
+ cssShapeSvg
9528
+ ),
8535
9529
  viewBox: `0 0 ${w} ${h}`,
8536
9530
  width: w,
8537
9531
  height: h,
@@ -8539,7 +9533,7 @@ function ElementNode({
8539
9533
  /* @__PURE__ */ jsx("g", { className: indicator, children: /* @__PURE__ */ jsx(
8540
9534
  SelectedIndicator,
8541
9535
  {
8542
- shape: element.shape,
9536
+ shape: element$1.shape,
8543
9537
  w,
8544
9538
  h
8545
9539
  }
@@ -8547,7 +9541,7 @@ function ElementNode({
8547
9541
  /* @__PURE__ */ jsx(
8548
9542
  ElementShapeSvg,
8549
9543
  {
8550
- shape: element.shape,
9544
+ shape: element$1.shape,
8551
9545
  w,
8552
9546
  h
8553
9547
  }
@@ -8555,30 +9549,30 @@ function ElementNode({
8555
9549
  ]
8556
9550
  }
8557
9551
  ),
8558
- /* @__PURE__ */ jsxs("div", { className: clsx(cssElement, "likec4-element"), children: [
8559
- element.icon && /* @__PURE__ */ jsx(ElementIcon, { node: element }),
9552
+ /* @__PURE__ */ jsxs("div", { className: clsx(element, "likec4-element"), children: [
9553
+ element$1.icon && /* @__PURE__ */ jsx(ElementIcon, { node: element$1 }),
8560
9554
  /* @__PURE__ */ jsx(
8561
9555
  Text,
8562
9556
  {
8563
9557
  component: "div",
8564
- className: clsx(title, "likec4-element-title"),
8565
- children: element.title
9558
+ className: clsx(title$1, "likec4-element-title"),
9559
+ children: element$1.title
8566
9560
  }
8567
9561
  ),
8568
- element.technology && /* @__PURE__ */ jsx(
9562
+ element$1.technology && /* @__PURE__ */ jsx(
8569
9563
  Text,
8570
9564
  {
8571
9565
  component: "div",
8572
9566
  className: clsx(technology, "likec4-element-technology"),
8573
- children: element.technology
9567
+ children: element$1.technology
8574
9568
  }
8575
9569
  ),
8576
- element.description && /* @__PURE__ */ jsx(
9570
+ element$1.description && /* @__PURE__ */ jsx(
8577
9571
  Text,
8578
9572
  {
8579
9573
  component: "div",
8580
- className: clsx(description, "likec4-element-description"),
8581
- children: element.description
9574
+ className: clsx(description$1, "likec4-element-description"),
9575
+ children: element$1.description
8582
9576
  }
8583
9577
  )
8584
9578
  ] }),
@@ -8590,7 +9584,7 @@ function ElementNode({
8590
9584
  style: { visibility: "hidden" }
8591
9585
  }
8592
9586
  ),
8593
- isHovercards && element.links && /* @__PURE__ */ jsx(ElementLink, { element }),
9587
+ isHovercards && element$1.links && /* @__PURE__ */ jsx(ElementLink, { element: element$1 }),
8594
9588
  isNavigable && /* @__PURE__ */ jsx(NavigateToBtn, { xynodeId: id2, className: cssNavigateBtn })
8595
9589
  ]
8596
9590
  }
@@ -8608,39 +9602,31 @@ function literalToEnum(value) {
8608
9602
  nonexhaustive(value);
8609
9603
  }
8610
9604
  }
8611
- const XYFlowBackground = memo(({ background }) => {
9605
+ function XYFlowBackground({ background }) {
8612
9606
  if (typeof background == "string")
8613
9607
  return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
8614
9608
  const { variant, ...rest } = background;
8615
9609
  return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
8616
- }, deepEqual);
9610
+ }
8617
9611
  function useXYFlowEvents() {
8618
- const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickGuarg = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
9612
+ const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickLock = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
8619
9613
  dblclickTimeout.current = void 0;
8620
- }, 250), !1);
9614
+ }, 250), !1), hoveredNodeFromOnEdgeEnterRef = useRef("");
8621
9615
  return useMemo(() => ({
8622
9616
  onDoubleClick: (event) => {
8623
- diagramApi.getState().setLastClickedNode(null), diagramApi.getState().setLastClickedEdge(null);
8624
- const diagramState = diagramApi.getState();
8625
- if (diagramState.onCanvasDblClick) {
8626
- diagramState.onCanvasDblClick(event);
8627
- return;
8628
- }
8629
- if (diagramState.fitViewEnabled && diagramState.zoomable) {
8630
- diagramState.fitDiagram(), event.stopPropagation();
8631
- return;
8632
- }
9617
+ const {
9618
+ fitViewEnabled,
9619
+ onCanvasDblClick,
9620
+ resetLastClicked,
9621
+ fitDiagram
9622
+ } = diagramApi.getState();
9623
+ fitViewEnabled && (fitDiagram(xyflowApi), onCanvasDblClick || event.stopPropagation()), resetLastClicked(), onCanvasDblClick == null || onCanvasDblClick(event);
8633
9624
  },
8634
9625
  onPaneClick: (event) => {
8635
- if (dbclickGuarg())
9626
+ if (dbclickLock())
8636
9627
  return;
8637
- diagramApi.getState().setLastClickedNode(null), diagramApi.getState().setLastClickedEdge(null);
8638
- const { focusedNodeId, fitDiagram, onCanvasClick } = diagramApi.getState();
8639
- if (onCanvasClick) {
8640
- onCanvasClick(event);
8641
- return;
8642
- }
8643
- focusedNodeId && (fitDiagram(), event.stopPropagation());
9628
+ const { focusedNodeId, fitDiagram, onCanvasClick, resetLastClicked } = diagramApi.getState();
9629
+ focusedNodeId && (fitDiagram(xyflowApi), onCanvasClick || event.stopPropagation()), resetLastClicked(), onCanvasClick == null || onCanvasClick(event);
8644
9630
  },
8645
9631
  onNodeContextMenu: (event, xynode) => {
8646
9632
  var _a, _b;
@@ -8652,7 +9638,7 @@ function useXYFlowEvents() {
8652
9638
  },
8653
9639
  onPaneContextMenu: (event) => {
8654
9640
  var _a, _b;
8655
- diagramApi.getState().setLastClickedNode(null), diagramApi.getState().setLastClickedEdge(null), (_b = (_a = diagramApi.getState()).onCanvasContextMenu) == null || _b.call(_a, event);
9641
+ diagramApi.getState().resetLastClicked(), (_b = (_a = diagramApi.getState()).onCanvasContextMenu) == null || _b.call(_a, event);
8656
9642
  },
8657
9643
  onEdgeContextMenu: (event, xyedge) => {
8658
9644
  var _a, _b;
@@ -8663,25 +9649,33 @@ function useXYFlowEvents() {
8663
9649
  });
8664
9650
  },
8665
9651
  onNodeClick: (event, xynode) => {
8666
- diagramApi.getState().setLastClickedNode(xynode.id);
8667
- const { focusedNodeId, fitDiagram, onNodeClick } = diagramApi.getState();
8668
- if (onNodeClick) {
8669
- onNodeClick({
8670
- element: xynode.data.element,
8671
- xynode,
8672
- event
8673
- });
8674
- return;
8675
- }
8676
- focusedNodeId && focusedNodeId !== xynode.id && (fitDiagram(xynode), event.stopPropagation());
9652
+ const {
9653
+ focusedNodeId,
9654
+ focusOnNode,
9655
+ onNodeClick,
9656
+ setLastClickedNode
9657
+ } = diagramApi.getState();
9658
+ setLastClickedNode(xynode.id), focusedNodeId && focusedNodeId !== xynode.id && (focusOnNode(xynode.id), onNodeClick || event.stopPropagation()), onNodeClick == null || onNodeClick({
9659
+ element: xynode.data.element,
9660
+ xynode,
9661
+ event
9662
+ });
8677
9663
  },
8678
9664
  onNodeDoubleClick: (event, xynode) => {
8679
- const { zoomable, fitDiagram, onNodeClick } = diagramApi.getState();
8680
- onNodeClick || zoomable && (fitDiagram(xynode), event.stopPropagation());
9665
+ const {
9666
+ focusedNodeId,
9667
+ zoomable,
9668
+ fitViewEnabled,
9669
+ fitDiagram,
9670
+ focusOnNode,
9671
+ setLastClickedNode
9672
+ } = diagramApi.getState();
9673
+ setLastClickedNode(xynode.id), (focusedNodeId || zoomable && fitViewEnabled) && (focusedNodeId === xynode.id ? fitDiagram(xyflowApi) : focusOnNode(xynode.id), event.stopPropagation());
8681
9674
  },
8682
9675
  onEdgeClick: (event, xyedge) => {
8683
- var _a, _b;
8684
- diagramApi.getState().setLastClickedEdge(xyedge.id), (_b = (_a = diagramApi.getState()).onEdgeClick) == null || _b.call(_a, {
9676
+ diagramApi.getState().setLastClickedEdge(xyedge.id);
9677
+ const { focusedNodeId, focusOnNode, onEdgeClick } = diagramApi.getState();
9678
+ focusedNodeId && (focusedNodeId === xyedge.source || focusedNodeId === xyedge.target) && (focusOnNode(focusedNodeId === xyedge.source ? xyedge.target : xyedge.source), onEdgeClick || event.stopPropagation()), onEdgeClick == null || onEdgeClick({
8685
9679
  relation: xyedge.data.edge,
8686
9680
  xyedge,
8687
9681
  event
@@ -8692,16 +9686,24 @@ function useXYFlowEvents() {
8692
9686
  viewportChanged !== diagramApi.getState().viewportChanged && diagramApi.setState({ viewportChanged }, !1, `viewport-changed: ${viewportChanged}`);
8693
9687
  },
8694
9688
  onNodeMouseEnter: (event, xynode) => {
8695
- diagramApi.getState().setHoveredNode(xynode.id);
9689
+ hoveredNodeFromOnEdgeEnterRef.current = "";
9690
+ const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
9691
+ hoveredNodeId !== xynode.id && setHoveredNode(xynode.id);
8696
9692
  },
8697
9693
  onNodeMouseLeave: (event, xynode) => {
8698
- diagramApi.getState().setHoveredNode(null);
9694
+ const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
9695
+ hoveredNodeId === xynode.id && setHoveredNode(null);
8699
9696
  },
8700
- onEdgeMouseEnter: (event, xyedge) => {
8701
- diagramApi.getState().setHoveredEdge(xyedge.id);
9697
+ onEdgeMouseEnter: (event, { id: id2, source, target }) => {
9698
+ const { hoveredNodeId, focusedNodeId, setHoveredEdge, setHoveredNode } = diagramApi.getState();
9699
+ if (setHoveredEdge(id2), (focusedNodeId === source || focusedNodeId === target) && focusedNodeId !== hoveredNodeId) {
9700
+ const next = hoveredNodeFromOnEdgeEnterRef.current = source === focusedNodeId ? target : source;
9701
+ setHoveredNode(next);
9702
+ }
8702
9703
  },
8703
9704
  onEdgeMouseLeave: (event, xyedge) => {
8704
- diagramApi.getState().setHoveredEdge(null);
9705
+ const { hoveredEdgeId, setHoveredEdge, hoveredNodeId, setHoveredNode } = diagramApi.getState();
9706
+ hoveredEdgeId === xyedge.id && setHoveredEdge(null), hoveredNodeId === hoveredNodeFromOnEdgeEnterRef.current && (hoveredNodeFromOnEdgeEnterRef.current = "", setHoveredNode(null));
8705
9707
  }
8706
9708
  }), [diagramApi, xyflowApi]);
8707
9709
  }
@@ -8710,8 +9712,8 @@ const nodeTypes = {
8710
9712
  compound: CompoundNodeMemo
8711
9713
  }, edgeTypes = {
8712
9714
  relationship: RelationshipEdge
8713
- }, selector = (s) => ({
8714
- nodesSelectable: s.nodesSelectable,
9715
+ }, selector$1 = (s) => ({
9716
+ nodesSelectable: s.nodesSelectable || s.focusedNodeId !== null,
8715
9717
  nodesDraggable: s.nodesDraggable,
8716
9718
  fitView: s.fitViewEnabled,
8717
9719
  fitViewPadding: s.fitViewPadding,
@@ -8724,25 +9726,36 @@ const nodeTypes = {
8724
9726
  zoomable: s.zoomable,
8725
9727
  pannable: s.pannable
8726
9728
  });
8727
- function XYFlowWrapper({
9729
+ function XYFlow({
8728
9730
  className,
8729
9731
  children: children2,
8730
9732
  defaultNodes,
8731
9733
  defaultEdges,
8732
- controls,
8733
- background,
8734
9734
  style: style2
8735
9735
  }) {
8736
- const diagramApi = useDiagramStoreApi(), {
9736
+ const xyflowApi = useXYStoreApi(), diagramApi = useDiagramStoreApi(), {
8737
9737
  nodesSelectable,
8738
9738
  nodesDraggable,
8739
9739
  fitView: fitView2,
8740
9740
  fitViewPadding,
8741
9741
  pannable,
8742
9742
  zoomable,
8743
- ...editor
8744
- } = useDiagramState(selector), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), isBgWithPattern = background !== "transparent" && background !== "solid", { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
8745
- return /* @__PURE__ */ jsxs(
9743
+ hasOnNodeClick,
9744
+ hasOnNavigateTo,
9745
+ hasOnNodeContextMenu,
9746
+ hasOnCanvasContextMenu,
9747
+ hasOnEdgeContextMenu,
9748
+ hasOnEdgeClick
9749
+ } = useDiagramState(selector$1), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
9750
+ return useOnViewportChange({
9751
+ onEnd: ({ x, y, zoom: zoom2 }) => {
9752
+ const rounded = {
9753
+ x: Math.round(x),
9754
+ y: Math.round(y)
9755
+ };
9756
+ (x !== rounded.x || y !== rounded.y) && xyflowApi.setState({ transform: [rounded.x, rounded.y, zoom2] });
9757
+ }
9758
+ }), /* @__PURE__ */ jsx(
8746
9759
  index,
8747
9760
  {
8748
9761
  className,
@@ -8773,8 +9786,8 @@ function XYFlowWrapper({
8773
9786
  panOnScroll: pannable,
8774
9787
  panOnDrag: pannable,
8775
9788
  elementsSelectable: nodesSelectable,
8776
- nodesFocusable: nodesDraggable || nodesSelectable || editor.hasOnNodeClick || editor.hasOnNavigateTo,
8777
- edgesFocusable: editor.hasOnEdgeClick,
9789
+ nodesFocusable: nodesDraggable || nodesSelectable || hasOnNodeClick || hasOnNavigateTo,
9790
+ edgesFocusable: hasOnEdgeClick,
8778
9791
  ...!nodesSelectable && {
8779
9792
  selectionKeyCode: null
8780
9793
  },
@@ -8800,24 +9813,502 @@ function XYFlowWrapper({
8800
9813
  onInit: () => {
8801
9814
  diagramApi.setState({ initialized: !0 }, !1, "initialized");
8802
9815
  },
8803
- ...editor.hasOnNodeContextMenu && {
9816
+ ...hasOnNodeContextMenu && {
8804
9817
  onNodeContextMenu: handlers.onNodeContextMenu
8805
9818
  },
8806
- ...editor.hasOnEdgeContextMenu && {
9819
+ ...hasOnEdgeContextMenu && {
8807
9820
  onEdgeContextMenu: handlers.onEdgeContextMenu
8808
9821
  },
8809
- ...editor.hasOnCanvasContextMenu && {
9822
+ ...hasOnCanvasContextMenu && {
8810
9823
  onPaneContextMenu: handlers.onPaneContextMenu
8811
9824
  },
9825
+ children: children2
9826
+ }
9827
+ );
9828
+ }
9829
+ var container$1 = "_2jkb2y0", buttons = "_2jkb2y1", btn = "_2jkb2y3";
9830
+ function DynamicViewWalkthrough() {
9831
+ const {
9832
+ nextDynamicStep,
9833
+ stopDynamicView,
9834
+ activeDynamicViewStep,
9835
+ hasNextSteps
9836
+ } = useDiagramState((s) => ({
9837
+ nextDynamicStep: s.nextDynamicStep,
9838
+ stopDynamicView: s.stopDynamicView,
9839
+ activeDynamicViewStep: s.activeDynamicViewStep,
9840
+ hasNextSteps: (s.activeDynamicViewStep ?? 1) < s.view.edges.length
9841
+ })), buttonProps = {
9842
+ className: btn,
9843
+ size: "compact-xl",
9844
+ radius: "xl"
9845
+ }, nextStep = (increment = 1) => (e) => {
9846
+ e.stopPropagation(), nextDynamicStep(increment);
9847
+ };
9848
+ return /* @__PURE__ */ jsxs(
9849
+ Box,
9850
+ {
9851
+ className: clsx("react-flow__panel", container$1),
8812
9852
  children: [
8813
- isBgWithPattern && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
8814
- controls && /* @__PURE__ */ jsx(Controls, {}),
8815
- children2
9853
+ isNullish(activeDynamicViewStep) && /* @__PURE__ */ jsx(
9854
+ Button,
9855
+ {
9856
+ ...buttonProps,
9857
+ className: clsx(buttons, btn),
9858
+ rightSection: /* @__PURE__ */ jsx(IconPlayerPlayFilled, {}),
9859
+ onClick: nextStep(),
9860
+ px: "xl",
9861
+ children: "Start"
9862
+ }
9863
+ ),
9864
+ isNumber(activeDynamicViewStep) && /* @__PURE__ */ jsxs(Button.Group, { className: buttons, children: [
9865
+ /* @__PURE__ */ jsx(
9866
+ Button,
9867
+ {
9868
+ ...buttonProps,
9869
+ pl: "lg",
9870
+ disabled: activeDynamicViewStep === 1,
9871
+ onClick: nextStep(-1),
9872
+ children: /* @__PURE__ */ jsx(IconPlayerSkipBackFilled, {})
9873
+ }
9874
+ ),
9875
+ /* @__PURE__ */ jsx(
9876
+ Button,
9877
+ {
9878
+ ...buttonProps,
9879
+ px: "sm",
9880
+ onClick: (e) => {
9881
+ e.stopPropagation(), stopDynamicView();
9882
+ },
9883
+ children: /* @__PURE__ */ jsx(IconPlayerStopFilled, {})
9884
+ }
9885
+ ),
9886
+ /* @__PURE__ */ jsx(
9887
+ Button,
9888
+ {
9889
+ ...buttonProps,
9890
+ pr: "lg",
9891
+ disabled: !hasNextSteps,
9892
+ onClick: nextStep(),
9893
+ children: /* @__PURE__ */ jsx(IconPlayerSkipForwardFilled, {})
9894
+ }
9895
+ )
9896
+ ] })
8816
9897
  ]
8817
9898
  }
8818
9899
  );
8819
9900
  }
8820
- const XYFlow = memo(XYFlowWrapper);
9901
+ const {
9902
+ primary,
9903
+ secondary,
9904
+ muted,
9905
+ ...otherColors
9906
+ } = defaultTheme.elements, themedColors = [
9907
+ { key: "primary", value: primary.fill },
9908
+ { key: "secondary", value: secondary.fill },
9909
+ { key: "muted", value: muted.fill }
9910
+ ], colors = keys.strict(otherColors).map((key) => ({
9911
+ key,
9912
+ value: defaultTheme.elements[key].fill
9913
+ }));
9914
+ function NodeOptions({ selectedNodeIds }) {
9915
+ const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
9916
+ if (!hasAtLeast(nodes, 1))
9917
+ return null;
9918
+ if (nodes.length !== selectedNodeIds.length)
9919
+ throw new Error("NodeOptions: nodes and props.nodes should have the same length");
9920
+ const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes, showOpacityOption = rest.length === 0 && firstNode.type === "compound", triggerChange = (style2) => {
9921
+ const targets = nodes.map((node) => node.data.element.id);
9922
+ invariant(hasAtLeast(targets, 1), "At least one target is required"), diagramApi.getState().triggerOnChange([{
9923
+ op: "change-element-style",
9924
+ style: style2,
9925
+ targets
9926
+ }]);
9927
+ };
9928
+ return /* @__PURE__ */ jsxs(Stack, { children: [
9929
+ /* @__PURE__ */ jsx(Box, { maw: 200, children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
9930
+ showShapeOption && /* @__PURE__ */ jsx(
9931
+ ShapeOption,
9932
+ {
9933
+ nodes,
9934
+ onShapeChange: (shape) => {
9935
+ triggerChange({ shape });
9936
+ }
9937
+ }
9938
+ ),
9939
+ /* @__PURE__ */ jsx(
9940
+ Colors,
9941
+ {
9942
+ nodes,
9943
+ onColorChange: (color2) => {
9944
+ triggerChange({ color: color2 });
9945
+ }
9946
+ }
9947
+ ),
9948
+ showOpacityOption && /* @__PURE__ */ jsxs(Box, { children: [
9949
+ /* @__PURE__ */ jsx(Divider, { label: "opacity and border", labelPosition: "left" }),
9950
+ /* @__PURE__ */ jsx(
9951
+ OpacityOption,
9952
+ {
9953
+ node: firstNode,
9954
+ onOpacityChange: (opacity) => {
9955
+ triggerChange({ opacity });
9956
+ }
9957
+ }
9958
+ ),
9959
+ /* @__PURE__ */ jsx(
9960
+ BorderStyleOption,
9961
+ {
9962
+ node: firstNode,
9963
+ onChange: (border) => {
9964
+ triggerChange({ border });
9965
+ }
9966
+ }
9967
+ )
9968
+ ] }, firstNode.id),
9969
+ /* @__PURE__ */ jsx(NavigateToOption, { nodes })
9970
+ ] });
9971
+ }
9972
+ function Colors({
9973
+ nodes: [firstNode, ...nodes],
9974
+ onColorChange
9975
+ }) {
9976
+ let selectedColor = firstNode.data.element.color;
9977
+ takeWhile(nodes, (node) => node.data.element.color !== selectedColor ? (selectedColor = null, !1) : !0);
9978
+ const changeColor = (color2) => () => {
9979
+ selectedColor !== color2 && onColorChange(color2);
9980
+ };
9981
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
9982
+ /* @__PURE__ */ jsx(Divider, { label: "color", labelPosition: "left" }),
9983
+ /* @__PURE__ */ jsx(Flex, { mt: "xs", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: themedColors.map(({ key, value }) => /* @__PURE__ */ jsx(
9984
+ Tooltip,
9985
+ {
9986
+ label: key,
9987
+ fz: "xs",
9988
+ color: "dark",
9989
+ offset: 2,
9990
+ transitionProps: { duration: 140, transition: "slide-up" },
9991
+ children: /* @__PURE__ */ jsx(
9992
+ ColorSwatch,
9993
+ {
9994
+ color: value,
9995
+ size: 20,
9996
+ withShadow: !0,
9997
+ onClick: changeColor(key),
9998
+ style: { color: "#fff", cursor: "pointer" },
9999
+ children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
10000
+ }
10001
+ )
10002
+ },
10003
+ key
10004
+ )) }),
10005
+ /* @__PURE__ */ jsx(Flex, { mt: "sm", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: colors.map(({ key, value }) => /* @__PURE__ */ jsx(
10006
+ Tooltip,
10007
+ {
10008
+ label: key,
10009
+ fz: "xs",
10010
+ color: "dark",
10011
+ offset: 2,
10012
+ transitionProps: { duration: 140, transition: "slide-up" },
10013
+ children: /* @__PURE__ */ jsx(
10014
+ ColorSwatch,
10015
+ {
10016
+ color: value,
10017
+ size: 20,
10018
+ onClick: changeColor(key),
10019
+ style: { color: "#fff", cursor: "pointer" },
10020
+ children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
10021
+ }
10022
+ )
10023
+ },
10024
+ key
10025
+ )) })
10026
+ ] }) });
10027
+ }
10028
+ function ShapeOption({
10029
+ nodes: [firstNode, ...nodes],
10030
+ onShapeChange
10031
+ }) {
10032
+ let selectedShape = firstNode.data.element.shape;
10033
+ return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs(Box, { children: [
10034
+ /* @__PURE__ */ jsx(Divider, { label: "shape", labelPosition: "left" }),
10035
+ /* @__PURE__ */ jsx(
10036
+ Select,
10037
+ {
10038
+ mt: "xs",
10039
+ size: "xs",
10040
+ variant: "filled",
10041
+ value: selectedShape,
10042
+ placeholder: "[ multiple ]",
10043
+ data: ElementShapes,
10044
+ allowDeselect: !1,
10045
+ checkIconPosition: "right",
10046
+ onChange: (value) => {
10047
+ !value || value === selectedShape || onShapeChange(value);
10048
+ }
10049
+ }
10050
+ )
10051
+ ] });
10052
+ }
10053
+ function NavigateToOption({
10054
+ nodes: [node, ...nodes]
10055
+ }) {
10056
+ const isMultiple = nodes.length >= 1;
10057
+ return /* @__PURE__ */ jsxs(Box, { children: [
10058
+ /* @__PURE__ */ jsx(Divider, { label: "navigate to", labelPosition: "left" }),
10059
+ /* @__PURE__ */ jsx(
10060
+ Select,
10061
+ {
10062
+ mt: "xs",
10063
+ size: "xs",
10064
+ variant: "filled",
10065
+ value: isMultiple ? null : node.data.element.navigateTo ?? null,
10066
+ disabled: isMultiple,
10067
+ placeholder: isMultiple ? "[ multiple ]" : "select",
10068
+ data: node.data.element.navigateTo ? [{ value: node.data.element.navigateTo, label: node.data.element.navigateTo }] : [],
10069
+ allowDeselect: !0,
10070
+ checkIconPosition: "right"
10071
+ }
10072
+ )
10073
+ ] });
10074
+ }
10075
+ function OpacityOption({
10076
+ node,
10077
+ onOpacityChange
10078
+ }) {
10079
+ let selectedOpacity = node.data.element.style.opacity ?? 100;
10080
+ const [value, setValue] = useState(selectedOpacity);
10081
+ return useEffect(() => {
10082
+ setValue(selectedOpacity);
10083
+ }, [selectedOpacity]), /* @__PURE__ */ jsx(
10084
+ Slider,
10085
+ {
10086
+ mt: "xs",
10087
+ size: "sm",
10088
+ color: "dark",
10089
+ value,
10090
+ onChange: setValue,
10091
+ onChangeEnd: onOpacityChange
10092
+ }
10093
+ );
10094
+ }
10095
+ function BorderStyleOption({
10096
+ node,
10097
+ onChange
10098
+ }) {
10099
+ let selecteBorderStyle = node.data.element.style.border ?? "dashed";
10100
+ const [value, setValue] = useState(selecteBorderStyle);
10101
+ return useEffect(() => {
10102
+ setValue(selecteBorderStyle);
10103
+ }, [selecteBorderStyle]), /* @__PURE__ */ jsx(Box, { mt: "md", children: /* @__PURE__ */ jsx(
10104
+ SegmentedControl,
10105
+ {
10106
+ size: "xs",
10107
+ fullWidth: !0,
10108
+ withItemsBorders: !1,
10109
+ value,
10110
+ onChange: (v) => {
10111
+ setValue(v), onChange(v);
10112
+ },
10113
+ data: [
10114
+ { label: "Solid", value: "solid" },
10115
+ { label: "Dashed", value: "dashed" },
10116
+ { label: "Dotted", value: "dotted" },
10117
+ { label: "None", value: "none" }
10118
+ ]
10119
+ }
10120
+ ) });
10121
+ }
10122
+ var panel = "_1lmzt1h0";
10123
+ function OptionsPanel() {
10124
+ const isFocusDisabled = useDiagramState((s) => isNullish(s.focusedNodeId)), [selectedNodes, setSelectedNodes] = useState([]);
10125
+ return useOnSelectionChange({
10126
+ onChange: ({ nodes }) => {
10127
+ const next = nodes.map((n) => n.id).sort();
10128
+ setSelectedNodes((prev) => shallowEqual(prev, next) ? prev : next);
10129
+ }
10130
+ }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isFocusDisabled && selectedNodes.length > 0 && /* @__PURE__ */ jsx(
10131
+ motion.div,
10132
+ {
10133
+ initial: { opacity: 0, scale: 0.85 },
10134
+ animate: { opacity: 1, scale: 1 },
10135
+ exit: {
10136
+ opacity: 0,
10137
+ scale: 0.85
10138
+ },
10139
+ transition: { duration: 0.14 },
10140
+ className: clsx("react-flow__panel", panel),
10141
+ style: {
10142
+ transformOrigin: "center right"
10143
+ },
10144
+ children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
10145
+ }
10146
+ ) });
10147
+ }
10148
+ var container = "hbkbtj0", paper = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
10149
+ const selector = (s) => ({
10150
+ id: s.view.id,
10151
+ title: s.view.title ?? "untitled",
10152
+ description: s.view.description,
10153
+ links: s.view.links
10154
+ });
10155
+ function DiagramTitlePanel() {
10156
+ const { id: id2, title: title$12, description: description$12, links } = useDiagramState(selector), [isCollapsed, setCollapsed] = useLocalStorage({
10157
+ key: "diagram-title-panel-collapsed",
10158
+ defaultValue: !1
10159
+ }), toggle = () => setCollapsed((v) => !v);
10160
+ return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
10161
+ motion.div,
10162
+ {
10163
+ initial: { opacity: 0.05, scale: 0.7 },
10164
+ animate: { opacity: 1, scale: 1 },
10165
+ exit: {
10166
+ opacity: 0.05,
10167
+ scale: 0.6
10168
+ },
10169
+ className: clsx("react-flow__panel", container),
10170
+ style: {
10171
+ transformOrigin: "left center"
10172
+ },
10173
+ children: /* @__PURE__ */ jsx(
10174
+ Paper,
10175
+ {
10176
+ radius: "sm",
10177
+ withBorder: !isCollapsed,
10178
+ className: paper,
10179
+ p: isCollapsed ? "xs" : "lg",
10180
+ onDoubleClick: (e) => e.stopPropagation(),
10181
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
10182
+ /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
10183
+ /* @__PURE__ */ jsx(
10184
+ Text,
10185
+ {
10186
+ component: "div",
10187
+ flex: "1",
10188
+ size: isCollapsed ? "sm" : "lg",
10189
+ fw: 500,
10190
+ lh: 1.1,
10191
+ className: title,
10192
+ children: title$12
10193
+ }
10194
+ ),
10195
+ /* @__PURE__ */ jsxs(
10196
+ Text,
10197
+ {
10198
+ hidden: isCollapsed,
10199
+ component: "div",
10200
+ flex: "0 0 auto",
10201
+ inline: !0,
10202
+ size: "xs",
10203
+ fz: 9,
10204
+ fw: 500,
10205
+ c: "dimmed",
10206
+ style: {
10207
+ userSelect: "all"
10208
+ },
10209
+ children: [
10210
+ /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
10211
+ "id:",
10212
+ " "
10213
+ ] }),
10214
+ id2
10215
+ ]
10216
+ }
10217
+ )
10218
+ ] }),
10219
+ !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
10220
+ description$12 && /* @__PURE__ */ jsx(
10221
+ Spoiler,
10222
+ {
10223
+ maxHeight: 42,
10224
+ showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
10225
+ hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
10226
+ children: /* @__PURE__ */ jsx(
10227
+ Text,
10228
+ {
10229
+ component: "div",
10230
+ size: "sm",
10231
+ className: description,
10232
+ children: description$12 || "no description"
10233
+ }
10234
+ )
10235
+ }
10236
+ ),
10237
+ !description$12 && /* @__PURE__ */ jsx(
10238
+ Text,
10239
+ {
10240
+ component: "div",
10241
+ size: "xs",
10242
+ c: "dimmed",
10243
+ children: "no description"
10244
+ }
10245
+ ),
10246
+ links && /* @__PURE__ */ jsx(
10247
+ Stack,
10248
+ {
10249
+ gap: 3,
10250
+ justify: "stretch",
10251
+ align: "stretch",
10252
+ children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
10253
+ /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
10254
+ Anchor,
10255
+ {
10256
+ href: link,
10257
+ target: "_blank",
10258
+ fz: "xs",
10259
+ truncate: "end",
10260
+ display: "inline-block",
10261
+ w: "100%",
10262
+ children: link
10263
+ }
10264
+ ) }),
10265
+ /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
10266
+ Button,
10267
+ {
10268
+ size: "compact-xs",
10269
+ fz: "10",
10270
+ variant: "light",
10271
+ onClick: copy,
10272
+ color: copied ? "teal" : "gray",
10273
+ children: copied ? "copied" : "copy"
10274
+ }
10275
+ ) })
10276
+ ] }, link))
10277
+ }
10278
+ )
10279
+ ] })
10280
+ ] })
10281
+ }
10282
+ )
10283
+ },
10284
+ id2
10285
+ ) });
10286
+ }
10287
+ function XYFlowInner({
10288
+ children: children2,
10289
+ background,
10290
+ controls,
10291
+ showDiagramTitle,
10292
+ enableDynamicViewWalkthrough
10293
+ }) {
10294
+ const {
10295
+ isDynamicView: isDynamicView2,
10296
+ isDynamicViewActive,
10297
+ readonly
10298
+ } = useDiagramState((s) => ({
10299
+ isDynamicView: s.isDynamicView(),
10300
+ readonly: s.readonly,
10301
+ isDynamicViewActive: isNonNull(s.activeDynamicViewStep)
10302
+ }));
10303
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
10304
+ background !== "transparent" && background !== "solid" && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
10305
+ controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
10306
+ readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel, {}),
10307
+ !isDynamicViewActive && showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {}),
10308
+ isDynamicView2 && enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {}),
10309
+ children2
10310
+ ] });
10311
+ }
8821
10312
  function LikeC4Diagram({
8822
10313
  view,
8823
10314
  className,
@@ -8829,8 +10320,10 @@ function LikeC4Diagram({
8829
10320
  nodesSelectable = !readonly,
8830
10321
  nodesDraggable = !readonly,
8831
10322
  background = "dots",
8832
- controls = !1,
10323
+ controls = !readonly,
8833
10324
  showElementLinks = !0,
10325
+ showDiagramTitle = !0,
10326
+ enableDynamicViewWalkthrough = !0,
8834
10327
  initialWidth,
8835
10328
  initialHeight,
8836
10329
  keepAspectRatio = !1,
@@ -8844,6 +10337,7 @@ function LikeC4Diagram({
8844
10337
  onNodeClick,
8845
10338
  onNodeContextMenu
8846
10339
  }) {
10340
+ console.log("LikeC4Diagram");
8847
10341
  const initialRef = useRef();
8848
10342
  if (!initialRef.current) {
8849
10343
  const initial = diagramViewToXYFlowData(view, {
@@ -8862,7 +10356,7 @@ function LikeC4Diagram({
8862
10356
  {
8863
10357
  fitView: fitView2,
8864
10358
  ...initialRef.current,
8865
- children: /* @__PURE__ */ jsxs(
10359
+ children: /* @__PURE__ */ jsx(
8866
10360
  DiagramContextProvider,
8867
10361
  {
8868
10362
  view,
@@ -8883,15 +10377,15 @@ function LikeC4Diagram({
8883
10377
  onChange,
8884
10378
  onNavigateTo,
8885
10379
  onCanvasDblClick,
8886
- children: [
8887
- /* @__PURE__ */ jsx(
8888
- KeepAspectRatioContainer,
8889
- {
8890
- className: clsx(rootClassName, className),
8891
- enabled: keepAspectRatio,
8892
- width: view.width,
8893
- height: view.height,
8894
- children: /* @__PURE__ */ jsx(
10380
+ children: /* @__PURE__ */ jsxs(
10381
+ KeepAspectRatioContainer,
10382
+ {
10383
+ className: clsx(rootClassName, className),
10384
+ enabled: keepAspectRatio,
10385
+ width: view.width,
10386
+ height: view.height,
10387
+ children: [
10388
+ /* @__PURE__ */ jsx(
8895
10389
  XYFlow,
8896
10390
  {
8897
10391
  className: clsx(
@@ -8901,20 +10395,27 @@ function LikeC4Diagram({
8901
10395
  pannable !== !0 && cssDisablePan,
8902
10396
  background === "transparent" && cssTransparentBg
8903
10397
  ),
8904
- background,
8905
- controls,
8906
10398
  defaultNodes: initialRef.current.defaultNodes,
8907
10399
  defaultEdges: initialRef.current.defaultEdges,
8908
- children: readonly !== !0 && /* @__PURE__ */ jsx(OptionsPanel2, {})
10400
+ children: /* @__PURE__ */ jsx(
10401
+ XYFlowInner,
10402
+ {
10403
+ showDiagramTitle,
10404
+ enableDynamicViewWalkthrough,
10405
+ background,
10406
+ controls
10407
+ }
10408
+ )
8909
10409
  }
8910
- )
8911
- }
8912
- ),
8913
- /* @__PURE__ */ jsxs(WhenInitialized, { children: [
8914
- /* @__PURE__ */ jsx(SyncWithDiagram, {}),
8915
- /* @__PURE__ */ jsx(FitViewOnDiagramChange, {})
8916
- ] })
8917
- ]
10410
+ ),
10411
+ /* @__PURE__ */ jsxs(WhenInitialized, { children: [
10412
+ /* @__PURE__ */ jsx(SyncWithDiagram, {}),
10413
+ fitView2 && /* @__PURE__ */ jsx(FitViewOnDiagramChange, {}),
10414
+ fitView2 && zoomable && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {})
10415
+ ] })
10416
+ ]
10417
+ }
10418
+ )
8918
10419
  }
8919
10420
  )
8920
10421
  }
@@ -8939,6 +10440,8 @@ function StaticLikeC4Diagram({
8939
10440
  controls: !1,
8940
10441
  background,
8941
10442
  showElementLinks: !0,
10443
+ showDiagramTitle: !1,
10444
+ enableDynamicViewWalkthrough: !1,
8942
10445
  nodesSelectable: !1,
8943
10446
  nodesDraggable: !1,
8944
10447
  ...rest