@floegence/floe-webapp-core 0.86.4 → 0.86.7

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.
@@ -1,5 +1,6 @@
1
- import { applyGraphPositions as b, routeGraphGeometry as G } from "./positions.js";
2
- async function O(d, n, k) {
1
+ import { applyGraphPositions as b } from "./positions.js";
2
+ import { routeGraphGeometry as G } from "./routing.js";
3
+ async function N(d, n, k) {
3
4
  const a = new Map(d.nodes.map((e) => [e.id, { ...e, x: 0, y: 0 }])), r = /* @__PURE__ */ new Map();
4
5
  for (const e of a.values()) {
5
6
  const i = r.get(e.parentId) ?? [];
@@ -14,22 +15,22 @@ async function O(d, n, k) {
14
15
  const g = n.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 }, p = (e, i, o) => {
15
16
  e.x += i, e.y += o;
16
17
  for (const c of r.get(e.id) ?? []) p(c, i, o);
17
- }, y = (e, i) => {
18
+ }, m = (e, i) => {
18
19
  let o = a.get(e);
19
20
  for (; o && o.parentId !== i; )
20
21
  o = o.parentId ? a.get(o.parentId) : void 0;
21
22
  return o;
22
- }, m = async (e) => {
23
+ }, y = async (e) => {
23
24
  const i = r.get(e) ?? [];
24
25
  for (const t of i) {
25
26
  if (!r.has(t.id)) continue;
26
- const s = await m(t.id);
27
+ const s = await y(t.id);
27
28
  t.width = Math.max(t.width, s.width), t.height = Math.max(t.height, s.height);
28
29
  }
29
30
  if (!i.length) return { width: 0, height: 0 };
30
31
  const o = /* @__PURE__ */ new Map();
31
32
  for (const t of d.edges) {
32
- const s = y(t.source, e), h = y(t.target, e);
33
+ const s = m(t.source, e), h = m(t.target, e);
33
34
  if (!s || !h || s.id === h.id) continue;
34
35
  const w = JSON.stringify([s.id, h.id]);
35
36
  o.has(w) || o.set(w, { id: t.id, sources: [s.id], targets: [h.id] });
@@ -57,7 +58,7 @@ async function O(d, n, k) {
57
58
  p(s, (t.x ?? 0) - s.x, (t.y ?? 0) - s.y);
58
59
  }
59
60
  return { width: c.width ?? 0, height: c.height ?? 0 };
60
- }, S = await m(), f = !n.positions?.length && n.anchor && a.get(n.anchor.nodeId);
61
+ }, S = await y(), f = !n.positions?.length && n.anchor && a.get(n.anchor.nodeId);
61
62
  if (f) {
62
63
  const e = n.anchor.position.x - f.x, i = n.anchor.position.y - f.y;
63
64
  for (const o of r.get(void 0) ?? []) p(o, e, i);
@@ -70,5 +71,5 @@ async function O(d, n, k) {
70
71
  return n.positions?.length ? b(u, n, d.nodes) : G(u);
71
72
  }
72
73
  export {
73
- O as computePackedGraphLayout
74
+ N as computePackedGraphLayout
74
75
  };
@@ -1,5 +1,4 @@
1
1
  import type { GraphLayout, GraphLayoutOptions, GraphNode } from './types';
2
+ export { routeGraphGeometry } from './routing';
2
3
  /** Apply explicit fixed or preferred positions, then route the resulting geometry once. */
3
- export declare function applyGraphPositions(layout: GraphLayout, options: GraphLayoutOptions, input: readonly GraphNode[]): GraphLayout;
4
- /** Shared routing and bounds for explicit positions and packed compound geometry. */
5
- export declare function routeGraphGeometry(layout: GraphLayout): GraphLayout;
4
+ export declare function applyGraphPositions(layout: GraphLayout, options: GraphLayoutOptions, input: readonly GraphNode[]): GraphLayout | Promise<GraphLayout>;
@@ -1,174 +1,75 @@
1
- const T = (r, a = 0) => ({
2
- left: r.x - a,
3
- top: r.y - a,
4
- right: r.x + r.width + a,
5
- bottom: r.y + r.height + a
6
- }), S = (r, a) => r.x > a.left && r.x < a.right && r.y > a.top && r.y < a.bottom, O = (r, a, w) => !w.some(
7
- (c) => r.x === a.x ? r.x > c.left && r.x < c.right && Math.max(r.y, a.y) > c.top && Math.min(r.y, a.y) < c.bottom : r.y > c.top && r.y < c.bottom && Math.max(r.x, a.x) > c.left && Math.min(r.x, a.x) < c.right
8
- );
9
- function P(r, a, w) {
10
- if (w.some((e) => S(r, e) || S(a, e)))
11
- throw new Error("Pinned graph positions obstruct an edge endpoint");
12
- const c = [
13
- .../* @__PURE__ */ new Set([r.x, a.x, ...w.flatMap((e) => [e.left, e.right])])
14
- ].sort((e, i) => e - i), m = [
15
- .../* @__PURE__ */ new Set([r.y, a.y, ...w.flatMap((e) => [e.top, e.bottom])])
16
- ].sort((e, i) => e - i), l = (e) => ({ x: c[e % c.length], y: m[Math.floor(e / c.length)] }), g = m.indexOf(r.y) * c.length + c.indexOf(r.x), n = m.indexOf(a.y) * c.length + c.indexOf(a.x), M = /* @__PURE__ */ new Map([[g, 0]]), d = /* @__PURE__ */ new Map(), t = [], u = (e) => {
17
- let i = t.length;
18
- for (t.push(e); i > 0; ) {
19
- const x = i - 1 >> 1;
20
- if (t[x].score <= e.score) break;
21
- t[i] = t[x], i = x;
22
- }
23
- t[i] = e;
24
- }, I = () => {
25
- const e = t[0], i = t.pop();
26
- if (t.length) {
27
- let x = 0;
28
- for (; x * 2 + 1 < t.length; ) {
29
- let h = x * 2 + 1;
30
- if (h + 1 < t.length && t[h + 1].score < t[h].score && h++, t[h].score >= i.score) break;
31
- t[x] = t[h], x = h;
32
- }
33
- t[x] = i;
34
- }
35
- return e;
36
- };
37
- u({ id: g, score: 0, cost: 0 });
38
- let v = 0;
39
- for (; t.length && v++ < 5e4; ) {
40
- const e = I();
41
- if (e.cost !== M.get(e.id)) continue;
42
- if (e.id === n) {
43
- const y = [l(n)];
44
- let o = n;
45
- for (; o !== g; )
46
- o = d.get(o), y.push(l(o));
47
- return y.reverse(), y.filter((p, f) => {
48
- const E = y[f - 1], b = y[f + 1];
49
- return !E || !b || !(E.x === p.x && p.x === b.x || E.y === p.y && p.y === b.y);
50
- });
51
- }
52
- const i = l(e.id), x = e.id % c.length, h = Math.floor(e.id / c.length), s = [
53
- x ? e.id - 1 : -1,
54
- x + 1 < c.length ? e.id + 1 : -1,
55
- h ? e.id - c.length : -1,
56
- h + 1 < m.length ? e.id + c.length : -1
57
- ];
58
- for (const y of s) {
59
- if (y < 0) continue;
60
- const o = l(y), p = e.cost + Math.abs(i.x - o.x) + Math.abs(i.y - o.y);
61
- p >= (M.get(y) ?? 1 / 0) || !O(i, o, w) || (M.set(y, p), d.set(y, e.id), u({ id: y, cost: p, score: p + Math.abs(o.x - a.x) + Math.abs(o.y - a.y) }));
62
- }
63
- }
64
- throw new Error("Pinned graph positions cannot be routed within the layout budget");
65
- }
66
- function k(r, a, w) {
67
- if (!a.positions?.length) return r;
68
- const c = new Map(r.nodes.map((t) => [t.id, { ...t }])), m = /* @__PURE__ */ new Map();
69
- for (const t of a.positions) {
70
- if (!c.has(t.nodeId) || m.has(t.nodeId) || !Number.isFinite(t.x) || !Number.isFinite(t.y))
1
+ import { routeGraphGeometry as G } from "./routing.js";
2
+ function E(d, c, v) {
3
+ if (!c.positions?.length) return d;
4
+ const f = new Map(d.nodes.map((t) => [t.id, { ...t }])), l = /* @__PURE__ */ new Map();
5
+ for (const t of c.positions) {
6
+ if (!f.has(t.nodeId) || l.has(t.nodeId) || !Number.isFinite(t.x) || !Number.isFinite(t.y))
71
7
  throw new Error(`Invalid graph position: ${t.nodeId}`);
72
- m.set(t.nodeId, t);
8
+ l.set(t.nodeId, t);
73
9
  }
74
- const l = /* @__PURE__ */ new Map();
75
- for (const t of c.values())
10
+ const y = /* @__PURE__ */ new Map();
11
+ for (const t of f.values())
76
12
  if (t.parentId) {
77
- const u = l.get(t.parentId) ?? [];
78
- u.push(t), l.set(t.parentId, u);
13
+ const m = y.get(t.parentId) ?? [];
14
+ m.push(t), y.set(t.parentId, m);
79
15
  }
80
- const g = a.groupPadding ?? { top: 64, left: 28, right: 28, bottom: 28 }, n = a.positionMode === "preferred", M = new Map(w.map((t) => [t.id, t])), d = (t, u, I) => {
81
- const v = { x: t.x, y: t.y }, e = m.get(t.id);
82
- t.x = e?.x ?? t.x + u, t.y = e?.y ?? t.y + I;
83
- const i = l.get(t.id) ?? [];
84
- for (const o of i) d(o, t.x - v.x, t.y - v.y);
85
- if (!i.length || n) return;
86
- const x = Math.min(...i.map((o) => o.x)) - g.left, h = Math.min(...i.map((o) => o.y)) - g.top;
87
- if (e && (x < t.x || h < t.y))
16
+ const x = c.groupPadding ?? { top: 64, left: 28, right: 28, bottom: 28 }, u = c.positionMode === "preferred", I = new Map(v.map((t) => [t.id, t])), b = (t, m, M) => {
17
+ const g = { x: t.x, y: t.y }, p = l.get(t.id);
18
+ t.x = p?.x ?? t.x + m, t.y = p?.y ?? t.y + M;
19
+ const i = y.get(t.id) ?? [];
20
+ for (const a of i) b(a, t.x - g.x, t.y - g.y);
21
+ if (!i.length || u) return;
22
+ const o = Math.min(...i.map((a) => a.x)) - x.left, h = Math.min(...i.map((a) => a.y)) - x.top;
23
+ if (p && (o < t.x || h < t.y))
88
24
  throw new Error(`Pinned child lies outside group content: ${t.id}`);
89
25
  const s = Math.max(
90
26
  t.x + t.width,
91
- ...i.map((o) => o.x + o.width + g.right)
92
- ), y = Math.max(
27
+ ...i.map((a) => a.x + a.width + x.right)
28
+ ), n = Math.max(
93
29
  t.y + t.height,
94
- ...i.map((o) => o.y + o.height + g.bottom)
30
+ ...i.map((a) => a.y + a.height + x.bottom)
95
31
  );
96
- e || (t.x = Math.min(t.x, x), t.y = Math.min(t.y, h)), t.width = s - t.x, t.height = y - t.y;
32
+ p || (t.x = Math.min(t.x, o), t.y = Math.min(t.y, h)), t.width = s - t.x, t.height = n - t.y;
97
33
  };
98
- for (const t of c.values()) t.parentId || d(t, 0, 0);
99
- if (n) {
100
- const t = Math.max(16, a.spacing ?? 64), u = (i, x, h) => {
101
- i.x += x, i.y += h;
102
- for (const s of l.get(i.id) ?? []) u(s, x, h);
103
- }, I = (i) => {
104
- const x = [];
34
+ for (const t of f.values()) t.parentId || b(t, 0, 0);
35
+ if (u) {
36
+ const t = Math.max(16, c.spacing ?? 64), m = (i, o, h) => {
37
+ i.x += o, i.y += h;
38
+ for (const s of y.get(i.id) ?? []) m(s, o, h);
39
+ }, M = (i) => {
40
+ const o = [];
105
41
  for (const h of [...i].sort(
106
- (s, y) => s.y - y.y || s.x - y.x || s.id.localeCompare(y.id)
42
+ (s, n) => s.y - n.y || s.x - n.x || s.id.localeCompare(n.id)
107
43
  )) {
108
44
  const s = { x: h.x, y: h.y };
109
- for (const p of [...x].sort((f, E) => f.x - E.x))
110
- h.y < p.y + p.height + t && h.y + h.height + t > p.y && s.x < p.x + p.width + t && s.x + h.width + t > p.x && (s.x = p.x + p.width + t);
111
- const y = { x: h.x, y: h.y };
112
- for (const p of [...x].sort((f, E) => f.y - E.y))
113
- h.x < p.x + p.width + t && h.x + h.width + t > p.x && y.y < p.y + p.height + t && y.y + h.height + t > p.y && (y.y = p.y + p.height + t);
114
- const o = s.x - h.x < y.y - h.y ? s : y;
115
- u(h, o.x - h.x, o.y - h.y), x.push(h);
45
+ for (const r of [...o].sort((e, w) => e.x - w.x))
46
+ h.y < r.y + r.height + t && h.y + h.height + t > r.y && s.x < r.x + r.width + t && s.x + h.width + t > r.x && (s.x = r.x + r.width + t);
47
+ const n = { x: h.x, y: h.y };
48
+ for (const r of [...o].sort((e, w) => e.y - w.y))
49
+ h.x < r.x + r.width + t && h.x + h.width + t > r.x && n.y < r.y + r.height + t && n.y + h.height + t > r.y && (n.y = r.y + r.height + t);
50
+ const a = s.x - h.x < n.y - h.y ? s : n;
51
+ m(h, a.x - h.x, a.y - h.y), o.push(h);
116
52
  }
117
- }, v = (i) => {
118
- const x = l.get(i.id) ?? [];
119
- if (!x.length) return;
120
- for (const f of x) v(f);
121
- I(x);
122
- const h = Math.max(12, g.left), s = Math.max(12, g.top), y = Math.max(12, g.right), o = Math.max(12, g.bottom), p = m.get(i.id);
123
- i.x = Math.min(p?.x ?? 1 / 0, Math.min(...x.map((f) => f.x)) - h), i.y = Math.min(p?.y ?? 1 / 0, Math.min(...x.map((f) => f.y)) - s), i.width = Math.max(
124
- M.get(i.id).width,
125
- Math.max(...x.map((f) => f.x + f.width)) + y - i.x
53
+ }, g = (i) => {
54
+ const o = y.get(i.id) ?? [];
55
+ if (!o.length) return;
56
+ for (const e of o) g(e);
57
+ M(o);
58
+ const h = Math.max(12, x.left), s = Math.max(12, x.top), n = Math.max(12, x.right), a = Math.max(12, x.bottom), r = l.get(i.id);
59
+ i.x = Math.min(r?.x ?? 1 / 0, Math.min(...o.map((e) => e.x)) - h), i.y = Math.min(r?.y ?? 1 / 0, Math.min(...o.map((e) => e.y)) - s), i.width = Math.max(
60
+ I.get(i.id).width,
61
+ Math.max(...o.map((e) => e.x + e.width)) + n - i.x
126
62
  ), i.height = Math.max(
127
- M.get(i.id).height,
128
- Math.max(...x.map((f) => f.y + f.height)) + o - i.y
63
+ I.get(i.id).height,
64
+ Math.max(...o.map((e) => e.y + e.height)) + a - i.y
129
65
  );
130
- }, e = [...c.values()].filter((i) => !i.parentId);
131
- for (const i of e) v(i);
132
- I(e);
66
+ }, p = [...f.values()].filter((i) => !i.parentId);
67
+ for (const i of p) g(i);
68
+ M(p);
133
69
  }
134
- return N({ ...r, nodes: [...c.values()] });
135
- }
136
- function N(r) {
137
- if (!r.nodes.length) return r;
138
- const a = new Map(r.nodes.map((n) => [n.id, n])), w = r.edges.map((n) => {
139
- const M = a.get(n.source), d = a.get(n.target), t = (s, y, o) => s.ports?.find((p) => p.id === y)?.side ?? o, u = M.x + M.width / 2 <= d.x + d.width / 2, I = (s, y) => {
140
- const o = { x: s.x + s.width / 2, y: s.y + s.height / 2 };
141
- return y === "NORTH" ? [
142
- { x: o.x, y: s.y },
143
- { x: o.x, y: s.y - 8 }
144
- ] : y === "SOUTH" ? [
145
- { x: o.x, y: s.y + s.height },
146
- { x: o.x, y: s.y + s.height + 8 }
147
- ] : y === "WEST" ? [
148
- { x: s.x, y: o.y },
149
- { x: s.x - 8, y: o.y }
150
- ] : [
151
- { x: s.x + s.width, y: o.y },
152
- { x: s.x + s.width + 8, y: o.y }
153
- ];
154
- }, [v, e] = I(M, t(M, n.sourcePort, u ? "EAST" : "WEST")), [i, x] = I(
155
- d,
156
- t(d, n.targetPort, M === d ? "NORTH" : u ? "WEST" : "EAST")
157
- ), h = [...a.values()].filter((s) => s.kind !== "group").map((s) => T(s, 4));
158
- return { ...n, sections: [[v, ...P(e, x, h), i]] };
159
- }), c = [...a.values()], m = w.flatMap((n) => n.sections.flat()), l = Math.min(...c.map((n) => n.x), ...m.map((n) => n.x)), g = Math.min(...c.map((n) => n.y), ...m.map((n) => n.y));
160
- return {
161
- nodes: c,
162
- edges: w,
163
- bounds: {
164
- x: l,
165
- y: g,
166
- width: Math.max(...c.map((n) => n.x + n.width), ...m.map((n) => n.x)) - l,
167
- height: Math.max(...c.map((n) => n.y + n.height), ...m.map((n) => n.y)) - g
168
- }
169
- };
70
+ return G({ ...d, nodes: [...f.values()] });
170
71
  }
171
72
  export {
172
- k as applyGraphPositions,
173
- N as routeGraphGeometry
73
+ E as applyGraphPositions,
74
+ G as routeGraphGeometry
174
75
  };
@@ -0,0 +1,3 @@
1
+ import type { GraphLayout } from './types';
2
+ /** Joint orthogonal routing through the final rectangular geometry. */
3
+ export declare function routeGraphGeometry(layout: GraphLayout): Promise<GraphLayout>;
@@ -0,0 +1,165 @@
1
+ import { AvoidLib as H } from "../../node_modules/.pnpm/libavoid-js@0.5.0-beta.5/node_modules/libavoid-js/dist/index.js";
2
+ import _ from "../../node_modules/.pnpm/libavoid-js@0.5.0-beta.5/node_modules/libavoid-js/dist/libavoid.wasm.js";
3
+ let U;
4
+ const F = { NORTH: 1, SOUTH: 2, WEST: 4, EAST: 8 }, v = ["NORTH", "EAST", "SOUTH", "WEST"], m = (s) => s.delete();
5
+ async function L(s) {
6
+ if (!s.nodes.length) return s;
7
+ if (!s.edges.length) return W(s);
8
+ await (U ??= H.load(_).catch((g) => {
9
+ throw U = void 0, g;
10
+ }));
11
+ const n = H.getInstance(), x = new Map(s.nodes.map((g) => [g.id, g])), S = (g) => {
12
+ const y = [];
13
+ for (let a = x.get(g).parentId; a; a = x.get(a).parentId)
14
+ y.push(a);
15
+ return y;
16
+ }, i = /* @__PURE__ */ new Map();
17
+ for (const g of s.edges) {
18
+ const y = /* @__PURE__ */ new Set([...S(g.source), ...S(g.target)]), a = JSON.stringify([...y].sort()), O = i.get(a) ?? { open: y, edges: [] };
19
+ O.edges.push(g), i.set(a, O);
20
+ }
21
+ const k = /* @__PURE__ */ new Map();
22
+ for (const { open: g, edges: y } of i.values()) {
23
+ const a = new n.Router(2);
24
+ try {
25
+ a.setRoutingParameter(n.RoutingParameter.shapeBufferDistance, 4), a.setRoutingParameter(n.RoutingParameter.idealNudgingDistance, 8), a.setRoutingParameter(n.RoutingParameter.crossingPenalty, 80), a.setRoutingParameter(n.RoutingParameter.fixedSharedPathPenalty, 120), a.setRoutingParameter(n.RoutingParameter.portDirectionPenalty, 0), a.setRoutingOption(n.RoutingOption.nudgeOrthogonalSegmentsConnectedToShapes, !1), a.setRoutingOption(n.RoutingOption.nudgeSharedPathsWithCommonEndPoint, !0);
26
+ const O = new Map(
27
+ s.nodes.filter((t) => !g.has(t.id) && S(t.id).every((r) => g.has(r))).map((t) => {
28
+ const r = new n.Point(t.x, t.y), c = new n.Point(t.x + t.width, t.y + t.height), h = new n.Rectangle(r, c), o = new n.ShapeRef(a, h);
29
+ return m(r), m(c), m(h), [t.id, o];
30
+ })
31
+ );
32
+ for (const t of s.nodes) {
33
+ const r = O.get(t.id);
34
+ if (!r) continue;
35
+ const c = y.flatMap(
36
+ (e) => e.source === t.id ? [x.get(e.target)] : e.target === t.id ? [x.get(e.source)] : []
37
+ );
38
+ if (!c.length) continue;
39
+ const h = (e, f, p, M) => {
40
+ const T = Math.max(e, p), R = Math.min(e + f, p + M), A = Math.min(8, f / 4);
41
+ return T < R ? (T + R) / 2 : Math.max(e + A, Math.min(e + f - A, p + M / 2));
42
+ }, o = (e, f) => {
43
+ const p = Math.min(8, e / 4);
44
+ return [
45
+ .../* @__PURE__ */ new Set([
46
+ e / 2,
47
+ p,
48
+ e - p,
49
+ ...f.flatMap(
50
+ (M) => Array.from(
51
+ { length: c.length + 1 },
52
+ (T, R) => Math.max(p, Math.min(e - p, M + (R - c.length / 2) * 8))
53
+ )
54
+ )
55
+ ])
56
+ ];
57
+ }, u = o(
58
+ t.width,
59
+ c.map((e) => h(t.x, t.width, e.x, e.width) - t.x)
60
+ ), w = o(
61
+ t.height,
62
+ c.map((e) => h(t.y, t.height, e.y, e.height) - t.y)
63
+ ), l = (t.ports ?? []).map((e) => E(t, e.side)), P = y.some((e) => e.source === t.id && e.target === t.id), C = [
64
+ ...l,
65
+ ...P ? [
66
+ { x: t.x + t.width, y: t.y + t.height / 3 },
67
+ { x: t.x + t.width, y: t.y + t.height * 2 / 3 }
68
+ ] : []
69
+ ], b = (e, f, p, M, T) => {
70
+ const R = new n.ShapeConnectionPin(
71
+ r,
72
+ e,
73
+ f / t.width,
74
+ p / t.height,
75
+ !0,
76
+ 0,
77
+ M
78
+ );
79
+ R.setExclusive(T), R.setConnectionCost(
80
+ t.width / 2 + t.height / 2 - Math.abs(f - t.width / 2) - Math.abs(p - t.height / 2)
81
+ );
82
+ }, d = (e, f, p) => {
83
+ C.some((M) => M.x === t.x + e && M.y === t.y + f) || b(1, e, f, p, !0);
84
+ };
85
+ for (const e of u)
86
+ d(e, 0, 1), d(e, t.height, 2);
87
+ for (const e of w)
88
+ d(0, e, 4), d(t.width, e, 8);
89
+ for (const e of new Set(t.ports?.map((f) => f.side))) {
90
+ const { x: f, y: p } = E(t, e);
91
+ b(v.indexOf(e) + 2, f - t.x, p - t.y, F[e], !1);
92
+ }
93
+ P && (b(6, t.width, t.height / 3, 8, !1), b(7, t.width, t.height * 2 / 3, 8, !1));
94
+ }
95
+ const N = (t, r, c, h) => {
96
+ const o = x.get(t), u = O.get(t);
97
+ if (u)
98
+ return new n.ConnEnd(
99
+ u,
100
+ r ? v.indexOf(o.ports.find((d) => d.id === r).side) + 2 : t === c ? h ? 7 : 6 : 1
101
+ );
102
+ const w = x.get(c), l = v.map((d) => E(o, d));
103
+ l.sort((d, e) => B(d, w) - B(e, w));
104
+ const P = r ? E(o, o.ports.find((d) => d.id === r).side) : l[0], C = new n.Point(P.x, P.y), b = new n.ConnEnd(C);
105
+ return m(C), b;
106
+ }, G = y.map((t) => {
107
+ const r = N(t.source, t.sourcePort, t.target, !1), c = N(t.target, t.targetPort, t.source, !0), h = new n.ConnRef(a, r, c);
108
+ if (m(r), m(c), t.source === t.target) {
109
+ const o = x.get(t.source), u = new n.CheckpointVector();
110
+ for (const w of [o.y + o.height / 3, o.y + o.height * 2 / 3]) {
111
+ const l = new n.Point(o.x + o.width + 24, w), P = new n.Checkpoint(l);
112
+ u.push_back(P), m(l), m(P);
113
+ }
114
+ h.setRoutingCheckpoints(u), m(u);
115
+ }
116
+ return { edge: t, connection: h };
117
+ });
118
+ a.processTransaction();
119
+ for (const { edge: t, connection: r } of G) {
120
+ const c = r.displayRoute(), h = Array.from({ length: c.size() }, (o, u) => {
121
+ const w = c.at(u), l = { x: w.x, y: w.y };
122
+ return m(w), l;
123
+ });
124
+ if (m(c), !r.hasValidRoute() || h.length < 2 || h.some((o) => !Number.isFinite(o.x) || !Number.isFinite(o.y)) || h.some((o, u) => u > 0 && o.x !== h[u - 1].x && o.y !== h[u - 1].y))
125
+ throw new Error(`Graph edge cannot be routed: ${t.id}`);
126
+ k.set(t.id, h);
127
+ }
128
+ } finally {
129
+ a.delete();
130
+ }
131
+ }
132
+ const D = s.edges.map((g) => ({ ...g, sections: [k.get(g.id)] }));
133
+ return W({ nodes: s.nodes, edges: D, bounds: s.bounds });
134
+ }
135
+ function W(s) {
136
+ const n = [
137
+ ...s.nodes.flatMap((i) => [
138
+ { x: i.x, y: i.y },
139
+ { x: i.x + i.width, y: i.y + i.height }
140
+ ]),
141
+ ...s.edges.flatMap((i) => i.sections.flat())
142
+ ], x = Math.min(...n.map((i) => i.x)), S = Math.min(...n.map((i) => i.y));
143
+ return {
144
+ nodes: s.nodes,
145
+ edges: s.edges,
146
+ bounds: {
147
+ x,
148
+ y: S,
149
+ width: Math.max(...n.map((i) => i.x)) - x,
150
+ height: Math.max(...n.map((i) => i.y)) - S
151
+ }
152
+ };
153
+ }
154
+ function E(s, n) {
155
+ return {
156
+ x: n === "WEST" ? s.x : n === "EAST" ? s.x + s.width : s.x + s.width / 2,
157
+ y: n === "NORTH" ? s.y : n === "SOUTH" ? s.y + s.height : s.y + s.height / 2
158
+ };
159
+ }
160
+ function B(s, n) {
161
+ return Math.max(n.x - s.x, 0, s.x - n.x - n.width) + Math.max(n.y - s.y, 0, s.y - n.y - n.height);
162
+ }
163
+ export {
164
+ L as routeGraphGeometry
165
+ };
@@ -1,4 +1,4 @@
1
- import { type JSX } from 'solid-js';
1
+ import { type Accessor, type JSX } from 'solid-js';
2
2
  export interface DropdownItem {
3
3
  id: string;
4
4
  label: string;
@@ -20,7 +20,7 @@ export interface DropdownProps {
20
20
  triggerAriaLabel?: string;
21
21
  /** Treat the existing trigger boundary as a field (used by Select). */
22
22
  triggerInputSurface?: boolean;
23
- items: DropdownItem[];
23
+ items: DropdownItem[] | Accessor<DropdownItem[]>;
24
24
  value?: string;
25
25
  onSelect: (id: string) => void;
26
26
  align?: 'start' | 'center' | 'end';