@skygraph/core 0.0.0-placeholder.0 → 0.4.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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/dist/calendar.cjs +404 -0
  3. package/dist/calendar.cjs.map +1 -0
  4. package/dist/calendar.d.cts +209 -0
  5. package/dist/calendar.d.ts +209 -0
  6. package/dist/calendar.js +12 -0
  7. package/dist/calendar.js.map +1 -0
  8. package/dist/chunk-5CCD5Q4B.js +36 -0
  9. package/dist/chunk-5CCD5Q4B.js.map +1 -0
  10. package/dist/chunk-AB3RLBLW.js +357 -0
  11. package/dist/chunk-AB3RLBLW.js.map +1 -0
  12. package/dist/chunk-GEMALROQ.js +258 -0
  13. package/dist/chunk-GEMALROQ.js.map +1 -0
  14. package/dist/chunk-IY6LJU3L.js +256 -0
  15. package/dist/chunk-IY6LJU3L.js.map +1 -0
  16. package/dist/chunk-KMGRNPLG.js +453 -0
  17. package/dist/chunk-KMGRNPLG.js.map +1 -0
  18. package/dist/chunk-KP75DEA4.js +1012 -0
  19. package/dist/chunk-KP75DEA4.js.map +1 -0
  20. package/dist/chunk-Y7FTBBYX.js +397 -0
  21. package/dist/chunk-Y7FTBBYX.js.map +1 -0
  22. package/dist/chunk-ZWB7JGAJ.js +488 -0
  23. package/dist/chunk-ZWB7JGAJ.js.map +1 -0
  24. package/dist/form.cjs +498 -0
  25. package/dist/form.cjs.map +1 -0
  26. package/dist/form.d.cts +130 -0
  27. package/dist/form.d.ts +130 -0
  28. package/dist/form.js +8 -0
  29. package/dist/form.js.map +1 -0
  30. package/dist/graph.cjs +1065 -0
  31. package/dist/graph.cjs.map +1 -0
  32. package/dist/graph.d.cts +542 -0
  33. package/dist/graph.d.ts +542 -0
  34. package/dist/graph.js +24 -0
  35. package/dist/graph.js.map +1 -0
  36. package/dist/index.cjs +3656 -0
  37. package/dist/index.cjs.map +1 -0
  38. package/dist/index.d.cts +144 -0
  39. package/dist/index.d.ts +144 -0
  40. package/dist/index.js +467 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/runtime-internal.cjs +339 -0
  43. package/dist/runtime-internal.cjs.map +1 -0
  44. package/dist/runtime-internal.d.cts +130 -0
  45. package/dist/runtime-internal.d.ts +130 -0
  46. package/dist/runtime-internal.js +67 -0
  47. package/dist/runtime-internal.js.map +1 -0
  48. package/dist/table.cjs +537 -0
  49. package/dist/table.cjs.map +1 -0
  50. package/dist/table.d.cts +215 -0
  51. package/dist/table.d.ts +215 -0
  52. package/dist/table.js +16 -0
  53. package/dist/table.js.map +1 -0
  54. package/dist/tree.cjs +442 -0
  55. package/dist/tree.cjs.map +1 -0
  56. package/dist/tree.d.cts +76 -0
  57. package/dist/tree.d.ts +76 -0
  58. package/dist/tree.js +8 -0
  59. package/dist/tree.js.map +1 -0
  60. package/dist/types-B-rKQJ4R.d.cts +35 -0
  61. package/dist/types-B-rKQJ4R.d.ts +35 -0
  62. package/dist/virtual.cjs +283 -0
  63. package/dist/virtual.cjs.map +1 -0
  64. package/dist/virtual.d.cts +96 -0
  65. package/dist/virtual.d.ts +96 -0
  66. package/dist/virtual.js +9 -0
  67. package/dist/virtual.js.map +1 -0
  68. package/package.json +98 -18
  69. package/README.md +0 -12
  70. package/index.js +0 -3
package/dist/graph.cjs ADDED
@@ -0,0 +1,1065 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key2 of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key2) && key2 !== except)
14
+ __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/engines/graph/index.ts
21
+ var graph_exports = {};
22
+ __export(graph_exports, {
23
+ aabbFromOBB: () => aabbFromOBB,
24
+ createGraph: () => createGraph,
25
+ getBezierPath: () => getBezierPath,
26
+ nearestSide: () => nearestSide,
27
+ obbContainsPoint: () => obbContainsPoint,
28
+ obbCorners: () => obbCorners,
29
+ pointsToPath: () => pointsToPath,
30
+ pointsToRoundedPath: () => pointsToRoundedPath,
31
+ routeOrthogonal: () => routeOrthogonal
32
+ });
33
+ module.exports = __toCommonJS(graph_exports);
34
+
35
+ // src/engines/namespaces.ts
36
+ var reserved = /* @__PURE__ */ new Map();
37
+ function reservePrefix(engine, prefix) {
38
+ if (!prefix.startsWith("$") || !prefix.endsWith(".")) {
39
+ throw new Error(
40
+ `[skygraph] engine "${engine}" tried to reserve invalid prefix "${prefix}". Engine prefixes must start with "$" and end with ".".`
41
+ );
42
+ }
43
+ const existing = reserved.get(prefix);
44
+ if (existing !== void 0 && existing !== engine) {
45
+ throw new Error(
46
+ `[skygraph] prefix "${prefix}" is already owned by engine "${existing}", cannot reserve it for "${engine}". Pick a different prefix or update the registry.`
47
+ );
48
+ }
49
+ reserved.set(prefix, engine);
50
+ return prefix;
51
+ }
52
+ var FORM_META_PREFIX = reservePrefix("form", "$meta.");
53
+ var TABLE_PREFIX = reservePrefix("table", "$table.");
54
+ var TREE_PREFIX = reservePrefix("tree", "$tree.");
55
+ var GRAPH_PREFIX = reservePrefix("graph", "$graph.");
56
+ var CALENDAR_PREFIX = reservePrefix("calendar", "$calendar.");
57
+
58
+ // src/engines/graph/history.ts
59
+ var HISTORY_LIMIT = 100;
60
+ function createHistory(limit = HISTORY_LIMIT) {
61
+ const undoStack = [];
62
+ const redoStack = [];
63
+ function trim(stack) {
64
+ while (stack.length > limit) stack.shift();
65
+ }
66
+ return {
67
+ push(entry) {
68
+ undoStack.push(entry);
69
+ trim(undoStack);
70
+ },
71
+ popUndo() {
72
+ return undoStack.pop();
73
+ },
74
+ pushRedo(entry) {
75
+ redoStack.push(entry);
76
+ trim(redoStack);
77
+ },
78
+ popRedo() {
79
+ return redoStack.pop();
80
+ },
81
+ clearRedo() {
82
+ redoStack.length = 0;
83
+ },
84
+ canUndo() {
85
+ return undoStack.length > 0;
86
+ },
87
+ canRedo() {
88
+ return redoStack.length > 0;
89
+ },
90
+ clear() {
91
+ undoStack.length = 0;
92
+ redoStack.length = 0;
93
+ },
94
+ relabelTop(label) {
95
+ const top = undoStack[undoStack.length - 1];
96
+ if (!top) return;
97
+ undoStack[undoStack.length - 1] = { snapshot: top.snapshot, label };
98
+ },
99
+ topLabel() {
100
+ return undoStack[undoStack.length - 1]?.label;
101
+ },
102
+ size() {
103
+ return { undo: undoStack.length, redo: redoStack.length };
104
+ }
105
+ };
106
+ }
107
+
108
+ // src/engines/graph/GraphEngine.ts
109
+ var engineCounter = 0;
110
+ var DEFAULT_OUTLINE = { kind: "rect", w: 100, h: 60 };
111
+ var DEFAULT_TRANSFORM = { x: 0, y: 0 };
112
+ var DEFAULT_ANCHOR_POLICY = { kind: "perEdge", k: 1 };
113
+ function createGraph(core, options) {
114
+ const engineId = `g${engineCounter++}${options?.name ? `-${options.name}` : ""}`;
115
+ const prefix = GRAPH_PREFIX;
116
+ const nodes = /* @__PURE__ */ new Map();
117
+ const edges = /* @__PURE__ */ new Map();
118
+ const edgesByNode = /* @__PURE__ */ new Map();
119
+ let nodeCounter = 0;
120
+ let edgeCounter = 0;
121
+ const localSubscribers = /* @__PURE__ */ new Set();
122
+ function publishSnapshot() {
123
+ core.set(`${prefix}snapshot.${engineId}`, {
124
+ nodes: Array.from(nodes.values()),
125
+ edges: Array.from(edges.values())
126
+ });
127
+ for (const cb of localSubscribers) cb();
128
+ }
129
+ function subscribeLocal(cb) {
130
+ localSubscribers.add(cb);
131
+ return () => {
132
+ localSubscribers.delete(cb);
133
+ };
134
+ }
135
+ publishSnapshot();
136
+ const history = createHistory(HISTORY_LIMIT);
137
+ let transactionDepth = 0;
138
+ let pendingEntry = null;
139
+ let isRestoring = false;
140
+ function _captureState() {
141
+ return {
142
+ nodes: Array.from(nodes.values()),
143
+ edges: Array.from(edges.values()),
144
+ nodeCounter,
145
+ edgeCounter
146
+ };
147
+ }
148
+ function _restoreState(snapshot) {
149
+ nodes.clear();
150
+ edges.clear();
151
+ edgesByNode.clear();
152
+ for (const n of snapshot.nodes) {
153
+ nodes.set(n.id, n);
154
+ edgesByNode.set(n.id, /* @__PURE__ */ new Set());
155
+ }
156
+ for (const e of snapshot.edges) {
157
+ edges.set(e.id, e);
158
+ ensureBucket(endpointNode(e.from)).add(e.id);
159
+ ensureBucket(endpointNode(e.to)).add(e.id);
160
+ }
161
+ nodeCounter = snapshot.nodeCounter;
162
+ edgeCounter = snapshot.edgeCounter;
163
+ }
164
+ function _withHistory(fn, label) {
165
+ if (isRestoring) return fn();
166
+ const wasOuter = transactionDepth === 0;
167
+ if (wasOuter) {
168
+ pendingEntry = { snapshot: _captureState(), label };
169
+ } else if (label !== void 0 && pendingEntry && pendingEntry.label === void 0) {
170
+ pendingEntry = { snapshot: pendingEntry.snapshot, label };
171
+ }
172
+ transactionDepth++;
173
+ try {
174
+ return fn();
175
+ } finally {
176
+ transactionDepth--;
177
+ if (transactionDepth === 0 && wasOuter) {
178
+ if (pendingEntry !== null) {
179
+ history.push(pendingEntry);
180
+ history.clearRedo();
181
+ }
182
+ pendingEntry = null;
183
+ }
184
+ }
185
+ }
186
+ function newNodeId() {
187
+ return `${engineId}-n${nodeCounter++}`;
188
+ }
189
+ function newEdgeId() {
190
+ return `${engineId}-e${edgeCounter++}`;
191
+ }
192
+ function ensureBucket(nodeId) {
193
+ let bucket = edgesByNode.get(nodeId);
194
+ if (!bucket) {
195
+ bucket = /* @__PURE__ */ new Set();
196
+ edgesByNode.set(nodeId, bucket);
197
+ }
198
+ return bucket;
199
+ }
200
+ function endpointNode(ep) {
201
+ return ep.node;
202
+ }
203
+ function bumpRevision(node) {
204
+ return { ...node, geomRevision: node.geomRevision + 1 };
205
+ }
206
+ function _addNodeImpl(init = {}) {
207
+ const id = init.id ?? newNodeId();
208
+ if (nodes.has(id)) {
209
+ throw new Error(`[skygraph/graph] node id "${id}" already exists`);
210
+ }
211
+ const node = {
212
+ id,
213
+ parentId: init.parentId ?? null,
214
+ transform: init.transform ?? { ...DEFAULT_TRANSFORM },
215
+ outline: init.outline ?? DEFAULT_OUTLINE,
216
+ anchorPolicy: init.anchorPolicy ?? DEFAULT_ANCHOR_POLICY,
217
+ data: init.data,
218
+ geomRevision: 0
219
+ };
220
+ nodes.set(id, node);
221
+ edgesByNode.set(id, /* @__PURE__ */ new Set());
222
+ publishSnapshot();
223
+ return id;
224
+ }
225
+ function addNode(init = {}) {
226
+ return _withHistory(() => _addNodeImpl(init));
227
+ }
228
+ function _removeNodeImpl(id) {
229
+ if (!nodes.has(id)) return;
230
+ const incident = edgesByNode.get(id);
231
+ if (incident) {
232
+ for (const eid of incident) removeEdge(eid);
233
+ }
234
+ for (const [otherId, n] of nodes) {
235
+ if (n.parentId === id) {
236
+ nodes.set(otherId, { ...n, parentId: null });
237
+ }
238
+ }
239
+ nodes.delete(id);
240
+ edgesByNode.delete(id);
241
+ publishSnapshot();
242
+ }
243
+ function removeNode(id) {
244
+ _withHistory(() => _removeNodeImpl(id));
245
+ }
246
+ function _updateNodeImpl(id, patch) {
247
+ const node = nodes.get(id);
248
+ if (!node) {
249
+ throw new Error(`[skygraph/graph] node "${id}" not found`);
250
+ }
251
+ const next = {
252
+ ...node,
253
+ transform: patch.transform ? { ...node.transform, ...patch.transform } : node.transform,
254
+ outline: patch.outline ?? node.outline,
255
+ anchorPolicy: patch.anchorPolicy ?? node.anchorPolicy,
256
+ data: patch.data === void 0 ? node.data : patch.data
257
+ };
258
+ const geomChanged = patch.transform !== void 0 || patch.outline !== void 0 || patch.anchorPolicy !== void 0;
259
+ nodes.set(id, geomChanged ? bumpRevision(next) : next);
260
+ publishSnapshot();
261
+ }
262
+ function updateNode(id, patch) {
263
+ _withHistory(() => _updateNodeImpl(id, patch));
264
+ }
265
+ function moveNode(id, x, y) {
266
+ _withHistory(() => _updateNodeImpl(id, { transform: { x, y } }));
267
+ }
268
+ function _setParentImpl(id, parentId) {
269
+ const node = nodes.get(id);
270
+ if (!node) {
271
+ throw new Error(`[skygraph/graph] node "${id}" not found`);
272
+ }
273
+ if (parentId !== null && !nodes.has(parentId)) {
274
+ throw new Error(`[skygraph/graph] parent node "${parentId}" not found`);
275
+ }
276
+ if (parentId === id) {
277
+ throw new Error(`[skygraph/graph] node cannot be its own parent ("${id}")`);
278
+ }
279
+ let cursor = parentId;
280
+ while (cursor !== null) {
281
+ if (cursor === id) {
282
+ throw new Error(`[skygraph/graph] setParent would create a cycle ("${id}" \u2192 "${parentId}")`);
283
+ }
284
+ cursor = nodes.get(cursor)?.parentId ?? null;
285
+ }
286
+ nodes.set(id, { ...node, parentId });
287
+ publishSnapshot();
288
+ }
289
+ function setParent(id, parentId) {
290
+ _withHistory(() => _setParentImpl(id, parentId));
291
+ }
292
+ function _addEdgeImpl(init) {
293
+ const id = init.id ?? newEdgeId();
294
+ if (edges.has(id)) {
295
+ throw new Error(`[skygraph/graph] edge id "${id}" already exists`);
296
+ }
297
+ const fromId = endpointNode(init.from);
298
+ const toId = endpointNode(init.to);
299
+ if (!nodes.has(fromId)) {
300
+ throw new Error(`[skygraph/graph] addEdge: from-node "${fromId}" not found`);
301
+ }
302
+ if (!nodes.has(toId)) {
303
+ throw new Error(`[skygraph/graph] addEdge: to-node "${toId}" not found`);
304
+ }
305
+ const edge = {
306
+ id,
307
+ from: init.from,
308
+ to: init.to,
309
+ routing: init.routing ?? "straight",
310
+ waypoints: init.waypoints,
311
+ data: init.data
312
+ };
313
+ edges.set(id, edge);
314
+ ensureBucket(fromId).add(id);
315
+ ensureBucket(toId).add(id);
316
+ publishSnapshot();
317
+ return id;
318
+ }
319
+ function addEdge(init) {
320
+ return _withHistory(() => _addEdgeImpl(init));
321
+ }
322
+ function _removeEdgeImpl(id) {
323
+ const edge = edges.get(id);
324
+ if (!edge) return;
325
+ edgesByNode.get(endpointNode(edge.from))?.delete(id);
326
+ edgesByNode.get(endpointNode(edge.to))?.delete(id);
327
+ edges.delete(id);
328
+ publishSnapshot();
329
+ }
330
+ function removeEdge(id) {
331
+ _withHistory(() => _removeEdgeImpl(id));
332
+ }
333
+ function getNode(id) {
334
+ return nodes.get(id);
335
+ }
336
+ function getEdge(id) {
337
+ return edges.get(id);
338
+ }
339
+ function getState() {
340
+ const byNode = /* @__PURE__ */ new Map();
341
+ for (const [nid, set] of edgesByNode) byNode.set(nid, Array.from(set));
342
+ return {
343
+ nodes: new Map(nodes),
344
+ edges: new Map(edges),
345
+ edgesByNode: byNode
346
+ };
347
+ }
348
+ function childrenOf(id) {
349
+ const out = [];
350
+ for (const n of nodes.values()) {
351
+ if (n.parentId === id) out.push(n.id);
352
+ }
353
+ return out;
354
+ }
355
+ function edgesOf(id) {
356
+ return Array.from(edgesByNode.get(id) ?? []);
357
+ }
358
+ function rectCornerId(corner) {
359
+ return corner;
360
+ }
361
+ function rectAnchors(w, h, policy) {
362
+ const corners = [
363
+ { id: rectCornerId("nw"), s: 0, point: [0, 0] },
364
+ { id: rectCornerId("ne"), s: 0.25, point: [w, 0] },
365
+ { id: rectCornerId("se"), s: 0.5, point: [w, h] },
366
+ { id: rectCornerId("sw"), s: 0.75, point: [0, h] }
367
+ ];
368
+ if (policy.kind === "manual") {
369
+ return policy.anchors.map((a) => ({
370
+ id: a.id,
371
+ s: a.s,
372
+ point: pointOnRectPerimeter(w, h, a.s)
373
+ }));
374
+ }
375
+ const k = policy.kind === "perEdge" ? Math.max(0, Math.floor(policy.k)) : null;
376
+ const density = policy.kind === "byLength" ? policy.density : null;
377
+ const out = [...corners];
378
+ const edgesGeom = [
379
+ { start: 0, end: 0.25 },
380
+ // top
381
+ { start: 0.25, end: 0.5 },
382
+ // right
383
+ { start: 0.5, end: 0.75 },
384
+ // bottom
385
+ { start: 0.75, end: 1 }
386
+ // left
387
+ ];
388
+ edgesGeom.forEach((edge, edgeIdx) => {
389
+ let count = 0;
390
+ if (k !== null) count = k;
391
+ if (density !== null) {
392
+ const len = edgeIdx % 2 === 0 ? w : h;
393
+ count = Math.max(0, Math.floor(len / density) - 1);
394
+ }
395
+ for (let i = 1; i <= count; i++) {
396
+ const t = i / (count + 1);
397
+ const s = edge.start + (edge.end - edge.start) * t;
398
+ out.push({
399
+ id: `edge${edgeIdx}-${i}of${count}`,
400
+ s,
401
+ point: pointOnRectPerimeter(w, h, s)
402
+ });
403
+ }
404
+ });
405
+ out.sort((a, b) => a.s - b.s);
406
+ return out;
407
+ }
408
+ function pointOnRectPerimeter(w, h, s) {
409
+ const ss = (s % 1 + 1) % 1;
410
+ if (ss < 0.25) return [w * (ss / 0.25), 0];
411
+ if (ss < 0.5) return [w, h * ((ss - 0.25) / 0.25)];
412
+ if (ss < 0.75) return [w * (1 - (ss - 0.5) / 0.25), h];
413
+ return [0, h * (1 - (ss - 0.75) / 0.25)];
414
+ }
415
+ function polygonAnchors(verts, policy) {
416
+ if (verts.length === 0) return [];
417
+ const segLengths = [];
418
+ let total = 0;
419
+ for (let i = 0; i < verts.length; i++) {
420
+ const a = verts[i];
421
+ const b = verts[(i + 1) % verts.length];
422
+ const dx = b[0] - a[0];
423
+ const dy = b[1] - a[1];
424
+ const len = Math.hypot(dx, dy);
425
+ segLengths.push(len);
426
+ total += len;
427
+ }
428
+ const cumS = [0];
429
+ for (let i = 0; i < segLengths.length; i++) {
430
+ cumS.push(cumS[i] + segLengths[i] / total);
431
+ }
432
+ function pointAt(s) {
433
+ const ss = (s % 1 + 1) % 1;
434
+ let i = 0;
435
+ while (i < cumS.length - 1 && cumS[i + 1] <= ss) i++;
436
+ const a = verts[i % verts.length];
437
+ const b = verts[(i + 1) % verts.length];
438
+ const segS0 = cumS[i];
439
+ const segS1 = cumS[i + 1];
440
+ const t = segS1 === segS0 ? 0 : (ss - segS0) / (segS1 - segS0);
441
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
442
+ }
443
+ if (policy.kind === "manual") {
444
+ return policy.anchors.map((a) => ({ id: a.id, s: a.s, point: pointAt(a.s) }));
445
+ }
446
+ const out = [];
447
+ for (let i = 0; i < verts.length; i++) {
448
+ out.push({
449
+ id: `v${i}`,
450
+ s: cumS[i],
451
+ point: [verts[i][0], verts[i][1]]
452
+ });
453
+ }
454
+ const k = policy.kind === "perEdge" ? Math.max(0, Math.floor(policy.k)) : null;
455
+ const density = policy.kind === "byLength" ? policy.density : null;
456
+ for (let i = 0; i < verts.length; i++) {
457
+ const segLen = segLengths[i];
458
+ let count = 0;
459
+ if (k !== null) count = k;
460
+ if (density !== null) count = Math.max(0, Math.floor(segLen / density) - 1);
461
+ const s0 = cumS[i];
462
+ const s1 = cumS[i + 1];
463
+ for (let j = 1; j <= count; j++) {
464
+ const t = j / (count + 1);
465
+ const s = s0 + (s1 - s0) * t;
466
+ out.push({ id: `v${i}-${j}of${count}`, s, point: pointAt(s) });
467
+ }
468
+ }
469
+ out.sort((a, b) => a.s - b.s);
470
+ return out;
471
+ }
472
+ function ellipseAnchors(rx, ry, policy) {
473
+ function pointAt(s) {
474
+ const angle = (s % 1 + 1) % 1 * Math.PI * 2;
475
+ return [rx * Math.cos(angle), ry * Math.sin(angle)];
476
+ }
477
+ if (policy.kind === "manual") {
478
+ return policy.anchors.map((a) => ({ id: a.id, s: a.s, point: pointAt(a.s) }));
479
+ }
480
+ const k = policy.kind === "perEdge" ? Math.max(1, Math.floor(policy.k)) : null;
481
+ const totalSamples = k !== null ? Math.max(4, k * 4) : Math.max(4, Math.floor(2 * Math.PI * Math.max(rx, ry) / policy.density));
482
+ const out = [];
483
+ for (let i = 0; i < totalSamples; i++) {
484
+ const s = i / totalSamples;
485
+ out.push({ id: `el${i}of${totalSamples}`, s, point: pointAt(s) });
486
+ }
487
+ return out;
488
+ }
489
+ function anchorsOf(id) {
490
+ const node = nodes.get(id);
491
+ if (!node) return [];
492
+ const o = node.outline;
493
+ if (o.kind === "rect") return rectAnchors(o.w, o.h, node.anchorPolicy);
494
+ if (o.kind === "polygon") return polygonAnchors(o.verts, node.anchorPolicy);
495
+ if (o.kind === "ellipse") return ellipseAnchors(o.rx, o.ry, node.anchorPolicy);
496
+ if (o.kind === "path") return polygonAnchors(o.flatten, node.anchorPolicy);
497
+ return [];
498
+ }
499
+ function localBounds(node) {
500
+ const o = node.outline;
501
+ if (o.kind === "rect") return { x0: 0, y0: 0, x1: o.w, y1: o.h };
502
+ if (o.kind === "ellipse") return { x0: -o.rx, y0: -o.ry, x1: o.rx, y1: o.ry };
503
+ const verts = o.kind === "polygon" ? o.verts : o.flatten;
504
+ if (verts.length === 0) return { x0: 0, y0: 0, x1: 0, y1: 0 };
505
+ let x0 = verts[0][0];
506
+ let x1 = verts[0][0];
507
+ let y0 = verts[0][1];
508
+ let y1 = verts[0][1];
509
+ for (const [x, y] of verts) {
510
+ if (x < x0) x0 = x;
511
+ if (x > x1) x1 = x;
512
+ if (y < y0) y0 = y;
513
+ if (y > y1) y1 = y;
514
+ }
515
+ return { x0, y0, x1, y1 };
516
+ }
517
+ function worldOriginOf(id) {
518
+ let cursor = id;
519
+ let x = 0;
520
+ let y = 0;
521
+ let scale = 1;
522
+ while (cursor !== null) {
523
+ const n = nodes.get(cursor);
524
+ if (!n) break;
525
+ const s = n.transform.scale ?? 1;
526
+ x = n.transform.x + x * s;
527
+ y = n.transform.y + y * s;
528
+ scale *= s;
529
+ cursor = n.parentId;
530
+ }
531
+ return { x, y, scale };
532
+ }
533
+ function boundsOf(id) {
534
+ const node = nodes.get(id);
535
+ if (!node) return { x: 0, y: 0, w: 0, h: 0 };
536
+ const lb = localBounds(node);
537
+ const origin = worldOriginOf(id);
538
+ const w = (lb.x1 - lb.x0) * origin.scale;
539
+ const h = (lb.y1 - lb.y0) * origin.scale;
540
+ return {
541
+ x: origin.x + lb.x0 * origin.scale,
542
+ y: origin.y + lb.y0 * origin.scale,
543
+ w,
544
+ h
545
+ };
546
+ }
547
+ function getNodeOBB(id) {
548
+ const node = nodes.get(id);
549
+ if (!node) return { center: [0, 0], halfWidth: 0, halfHeight: 0, angle: 0 };
550
+ const lb = localBounds(node);
551
+ const origin = worldOriginOf(id);
552
+ const localCx = (lb.x0 + lb.x1) / 2;
553
+ const localCy = (lb.y0 + lb.y1) / 2;
554
+ const halfWidth = Math.abs((lb.x1 - lb.x0) / 2 * origin.scale);
555
+ const halfHeight = Math.abs((lb.y1 - lb.y0) / 2 * origin.scale);
556
+ let angle = 0;
557
+ let cursor = id;
558
+ while (cursor !== null) {
559
+ const n = nodes.get(cursor);
560
+ if (!n) break;
561
+ angle += n.transform.rot ?? 0;
562
+ cursor = n.parentId;
563
+ }
564
+ const center = [
565
+ origin.x + localCx * origin.scale,
566
+ origin.y + localCy * origin.scale
567
+ ];
568
+ return { center, halfWidth, halfHeight, angle };
569
+ }
570
+ function clear() {
571
+ nodes.clear();
572
+ edges.clear();
573
+ edgesByNode.clear();
574
+ nodeCounter = 0;
575
+ edgeCounter = 0;
576
+ history.clear();
577
+ pendingEntry = null;
578
+ transactionDepth = 0;
579
+ isRestoring = false;
580
+ publishSnapshot();
581
+ }
582
+ function transaction(fn, label) {
583
+ _withHistory(fn, label);
584
+ }
585
+ function pushHistory(label) {
586
+ if (transactionDepth > 0) {
587
+ if (pendingEntry !== null) {
588
+ history.push({ snapshot: pendingEntry.snapshot, label: pendingEntry.label ?? label });
589
+ history.clearRedo();
590
+ }
591
+ pendingEntry = { snapshot: _captureState(), label: void 0 };
592
+ return;
593
+ }
594
+ history.relabelTop(label);
595
+ }
596
+ function undo() {
597
+ if (!history.canUndo()) return false;
598
+ const entry = history.popUndo();
599
+ history.pushRedo({ snapshot: _captureState(), label: entry.label });
600
+ isRestoring = true;
601
+ try {
602
+ _restoreState(entry.snapshot);
603
+ } finally {
604
+ isRestoring = false;
605
+ }
606
+ publishSnapshot();
607
+ return true;
608
+ }
609
+ function redo() {
610
+ if (!history.canRedo()) return false;
611
+ const entry = history.popRedo();
612
+ history.push({ snapshot: _captureState(), label: entry.label });
613
+ isRestoring = true;
614
+ try {
615
+ _restoreState(entry.snapshot);
616
+ } finally {
617
+ isRestoring = false;
618
+ }
619
+ publishSnapshot();
620
+ return true;
621
+ }
622
+ function canUndo() {
623
+ return history.canUndo();
624
+ }
625
+ function canRedo() {
626
+ return history.canRedo();
627
+ }
628
+ function clearHistory() {
629
+ history.clear();
630
+ }
631
+ return {
632
+ addNode,
633
+ removeNode,
634
+ updateNode,
635
+ moveNode,
636
+ setParent,
637
+ addEdge,
638
+ removeEdge,
639
+ getNode,
640
+ getEdge,
641
+ getState,
642
+ childrenOf,
643
+ edgesOf,
644
+ anchorsOf,
645
+ boundsOf,
646
+ getNodeOBB,
647
+ subscribe: subscribeLocal,
648
+ transaction,
649
+ pushHistory,
650
+ undo,
651
+ redo,
652
+ canUndo,
653
+ canRedo,
654
+ clearHistory,
655
+ clear
656
+ };
657
+ }
658
+
659
+ // src/engines/graph/router.ts
660
+ function routeOrthogonal(start, end, options) {
661
+ const opts = typeof options === "string" ? { preferred: options } : options ?? {};
662
+ const gridSize = opts.gridSize ?? 10;
663
+ const stubLength = opts.stubLength ?? Math.max(8, gridSize);
664
+ let sExit = null;
665
+ let sStub = null;
666
+ let sCorner = null;
667
+ if (opts.sourceBounds) {
668
+ const exitInfo = exitOnNearestSide(opts.sourceBounds, end);
669
+ sExit = exitInfo.point;
670
+ sStub = extrudePoint(exitInfo.point, exitInfo.side, stubLength);
671
+ sCorner = orthoBridge(start, sExit, exitInfo.side);
672
+ }
673
+ let tExit = null;
674
+ let tStub = null;
675
+ let tCorner = null;
676
+ if (opts.targetBounds) {
677
+ const enterInfo = exitOnNearestSide(opts.targetBounds, start);
678
+ tExit = enterInfo.point;
679
+ tStub = extrudePoint(enterInfo.point, enterInfo.side, stubLength);
680
+ tCorner = orthoBridge(end, tExit, enterInfo.side);
681
+ }
682
+ const coreStart = sStub ?? start;
683
+ const coreEnd = tStub ?? end;
684
+ const obstacles = opts.obstacles ?? [];
685
+ const filteredObstacles = obstacles.length > 0 && (opts.sourceBounds || opts.targetBounds) ? obstacles.filter((o) => o !== opts.sourceBounds && o !== opts.targetBounds) : obstacles;
686
+ let core;
687
+ if (filteredObstacles.length === 0) {
688
+ const snap2 = opts.snap ?? gridSize;
689
+ core = lRoute(coreStart, coreEnd, opts.preferred ?? "auto", snap2);
690
+ } else {
691
+ const inflate = opts.inflate ?? 0;
692
+ const maxNodes = opts.maxNodes ?? 5e3;
693
+ const aStar = aStarRoute(coreStart, coreEnd, filteredObstacles, gridSize, inflate, maxNodes);
694
+ core = aStar ?? lRoute(coreStart, coreEnd, opts.preferred ?? "auto", opts.snap ?? gridSize);
695
+ }
696
+ const points = [];
697
+ pushIfDistinct(points, start);
698
+ if (sCorner && !pointsEqual(sCorner, start)) pushIfDistinct(points, sCorner);
699
+ if (sExit && !pointsEqual(sExit, points[points.length - 1])) pushIfDistinct(points, sExit);
700
+ if (sStub && !pointsEqual(sStub, points[points.length - 1])) pushIfDistinct(points, sStub);
701
+ for (let i = 0; i < core.length; i++) {
702
+ const p = core[i];
703
+ if (i === 0 && sStub && pointsEqual(p, sStub)) continue;
704
+ if (i === core.length - 1 && tStub && pointsEqual(p, tStub)) continue;
705
+ pushIfDistinct(points, p);
706
+ }
707
+ if (tStub && !pointsEqual(tStub, points[points.length - 1])) pushIfDistinct(points, tStub);
708
+ if (tExit && !pointsEqual(tExit, points[points.length - 1])) pushIfDistinct(points, tExit);
709
+ if (tCorner && !pointsEqual(tCorner, points[points.length - 1])) pushIfDistinct(points, tCorner);
710
+ if (!pointsEqual(end, points[points.length - 1])) pushIfDistinct(points, end);
711
+ return compressCollinear(points);
712
+ }
713
+ function pointsToPath(points) {
714
+ if (points.length === 0) return "";
715
+ const [head, ...rest] = points;
716
+ return `M ${head[0]} ${head[1]} ${rest.map((p) => `L ${p[0]} ${p[1]}`).join(" ")}`;
717
+ }
718
+ function pointsToRoundedPath(points, radius) {
719
+ if (points.length === 0) return "";
720
+ if (points.length < 3 || radius <= 0) return pointsToPath(points);
721
+ let d = `M ${points[0][0]} ${points[0][1]}`;
722
+ for (let i = 1; i < points.length - 1; i++) {
723
+ const a = points[i - 1];
724
+ const b = points[i];
725
+ const c = points[i + 1];
726
+ const lenAB = Math.hypot(b[0] - a[0], b[1] - a[1]);
727
+ const lenBC = Math.hypot(c[0] - b[0], c[1] - b[1]);
728
+ const r = Math.min(radius, lenAB / 2, lenBC / 2);
729
+ const ux = (b[0] - a[0]) / (lenAB || 1);
730
+ const uy = (b[1] - a[1]) / (lenAB || 1);
731
+ const vx = (c[0] - b[0]) / (lenBC || 1);
732
+ const vy = (c[1] - b[1]) / (lenBC || 1);
733
+ const cross = ux * vy - uy * vx;
734
+ if (r < 0.5 || Math.abs(cross) < 1e-9) {
735
+ d += ` L ${b[0]} ${b[1]}`;
736
+ continue;
737
+ }
738
+ const p1x = b[0] - ux * r;
739
+ const p1y = b[1] - uy * r;
740
+ const p2x = b[0] + vx * r;
741
+ const p2y = b[1] + vy * r;
742
+ d += ` L ${p1x} ${p1y} Q ${b[0]} ${b[1]} ${p2x} ${p2y}`;
743
+ }
744
+ const tail = points[points.length - 1];
745
+ d += ` L ${tail[0]} ${tail[1]}`;
746
+ return d;
747
+ }
748
+ function controlOffset(distance, curvature) {
749
+ if (distance >= 0) return 0.5 * distance;
750
+ return curvature * 25 * Math.sqrt(-distance);
751
+ }
752
+ function controlPoint(side, x1, y1, x2, y2, curvature) {
753
+ switch (side) {
754
+ case "left":
755
+ return [x1 - controlOffset(x1 - x2, curvature), y1];
756
+ case "right":
757
+ return [x1 + controlOffset(x2 - x1, curvature), y1];
758
+ case "top":
759
+ return [x1, y1 - controlOffset(y1 - y2, curvature)];
760
+ case "bottom":
761
+ return [x1, y1 + controlOffset(y2 - y1, curvature)];
762
+ }
763
+ }
764
+ function getBezierPath(opts) {
765
+ const curvature = opts.curvature ?? 0.25;
766
+ const [sx, sy] = opts.source;
767
+ const [tx, ty] = opts.target;
768
+ const [c1x, c1y] = controlPoint(opts.sourceSide, sx, sy, tx, ty, curvature);
769
+ const [c2x, c2y] = controlPoint(opts.targetSide, tx, ty, sx, sy, curvature);
770
+ return `M ${sx} ${sy} C ${c1x} ${c1y} ${c2x} ${c2y} ${tx} ${ty}`;
771
+ }
772
+ function nearestSide(box, target) {
773
+ const cx = box.x + box.w / 2;
774
+ const cy = box.y + box.h / 2;
775
+ const dx = target[0] - cx;
776
+ const dy = target[1] - cy;
777
+ if (Math.abs(dx) >= Math.abs(dy)) return dx >= 0 ? "right" : "left";
778
+ return dy >= 0 ? "bottom" : "top";
779
+ }
780
+ function exitOnNearestSide(box, target) {
781
+ const cx = box.x + box.w / 2;
782
+ const cy = box.y + box.h / 2;
783
+ const dx = target[0] - cx;
784
+ const dy = target[1] - cy;
785
+ if (Math.abs(dx) >= Math.abs(dy)) {
786
+ if (dx >= 0) return { point: [box.x + box.w, cy], side: "right" };
787
+ return { point: [box.x, cy], side: "left" };
788
+ }
789
+ if (dy >= 0) return { point: [cx, box.y + box.h], side: "bottom" };
790
+ return { point: [cx, box.y], side: "top" };
791
+ }
792
+ function extrudePoint(point, side, distance) {
793
+ switch (side) {
794
+ case "top":
795
+ return [point[0], point[1] - distance];
796
+ case "right":
797
+ return [point[0] + distance, point[1]];
798
+ case "bottom":
799
+ return [point[0], point[1] + distance];
800
+ case "left":
801
+ return [point[0] - distance, point[1]];
802
+ }
803
+ }
804
+ function orthoBridge(start, exit, side) {
805
+ switch (side) {
806
+ case "right":
807
+ case "left":
808
+ return [exit[0], start[1]];
809
+ case "top":
810
+ case "bottom":
811
+ return [start[0], exit[1]];
812
+ }
813
+ }
814
+ function pointsEqual(a, b) {
815
+ return a[0] === b[0] && a[1] === b[1];
816
+ }
817
+ function pushIfDistinct(arr, p) {
818
+ if (arr.length === 0) {
819
+ arr.push(p);
820
+ return;
821
+ }
822
+ const last = arr[arr.length - 1];
823
+ if (!pointsEqual(last, p)) arr.push(p);
824
+ }
825
+ function compressCollinear(points) {
826
+ if (points.length <= 2) return points.slice();
827
+ const out = [points[0], points[1]];
828
+ for (let i = 2; i < points.length; i++) {
829
+ const cur = points[i];
830
+ const a = out[out.length - 2];
831
+ const b = out[out.length - 1];
832
+ const dx1 = b[0] - a[0];
833
+ const dy1 = b[1] - a[1];
834
+ const dx2 = cur[0] - b[0];
835
+ const dy2 = cur[1] - b[1];
836
+ const cross = dx1 * dy2 - dy1 * dx2;
837
+ if (cross === 0 && Math.sign(dx1) === Math.sign(dx2) && Math.sign(dy1) === Math.sign(dy2)) {
838
+ out[out.length - 1] = cur;
839
+ } else {
840
+ out.push(cur);
841
+ }
842
+ }
843
+ return out;
844
+ }
845
+ function lRoute(start, end, preferred, _snapStep) {
846
+ const [sx, sy] = start;
847
+ const [ex, ey] = end;
848
+ if (sx === ex || sy === ey) return [start, end];
849
+ const dx = Math.abs(ex - sx);
850
+ const dy = Math.abs(ey - sy);
851
+ const useHV = preferred === "hv" ? true : preferred === "vh" ? false : dx >= dy;
852
+ if (useHV) return [start, [ex, sy], end];
853
+ return [start, [sx, ey], end];
854
+ }
855
+ function inflateObstacles(obstacles, pad) {
856
+ return obstacles.map((o) => ({
857
+ x0: o.x - pad,
858
+ y0: o.y - pad,
859
+ x1: o.x + o.w + pad,
860
+ y1: o.y + o.h + pad
861
+ }));
862
+ }
863
+ function pointBlocked(x, y, rects) {
864
+ for (const r of rects) {
865
+ if (x > r.x0 && x < r.x1 && y > r.y0 && y < r.y1) return true;
866
+ }
867
+ return false;
868
+ }
869
+ function snap(value, step) {
870
+ return Math.round(value / step) * step;
871
+ }
872
+ function key(x, y) {
873
+ return `${x},${y}`;
874
+ }
875
+ function manhattan(ax, ay, bx, by) {
876
+ return Math.abs(ax - bx) + Math.abs(ay - by);
877
+ }
878
+ function reconstruct(cameFrom, endKey) {
879
+ const reversed = [];
880
+ let cursor = endKey;
881
+ while (cursor !== void 0) {
882
+ const [xs, ys] = cursor.split(",");
883
+ reversed.push([Number(xs), Number(ys)]);
884
+ cursor = cameFrom.get(cursor);
885
+ }
886
+ reversed.reverse();
887
+ const out = [];
888
+ for (let i = 0; i < reversed.length; i++) {
889
+ const cur = reversed[i];
890
+ if (out.length < 2) {
891
+ out.push(cur);
892
+ continue;
893
+ }
894
+ const a = out[out.length - 2];
895
+ const b = out[out.length - 1];
896
+ const dx1 = b[0] - a[0];
897
+ const dy1 = b[1] - a[1];
898
+ const dx2 = cur[0] - b[0];
899
+ const dy2 = cur[1] - b[1];
900
+ if (Math.sign(dx1) === Math.sign(dx2) && Math.sign(dy1) === Math.sign(dy2)) {
901
+ out[out.length - 1] = cur;
902
+ } else {
903
+ out.push(cur);
904
+ }
905
+ }
906
+ return out;
907
+ }
908
+ var MinHeap = class {
909
+ data = [];
910
+ get size() {
911
+ return this.data.length;
912
+ }
913
+ push(entry) {
914
+ this.data.push(entry);
915
+ this.bubbleUp(this.data.length - 1);
916
+ }
917
+ pop() {
918
+ if (this.data.length === 0) return void 0;
919
+ const head = this.data[0];
920
+ const tail = this.data.pop();
921
+ if (this.data.length > 0) {
922
+ this.data[0] = tail;
923
+ this.bubbleDown(0);
924
+ }
925
+ return head;
926
+ }
927
+ bubbleUp(i) {
928
+ while (i > 0) {
929
+ const parent = i - 1 >> 1;
930
+ if (this.data[i].f < this.data[parent].f) {
931
+ const tmp = this.data[i];
932
+ this.data[i] = this.data[parent];
933
+ this.data[parent] = tmp;
934
+ i = parent;
935
+ } else {
936
+ return;
937
+ }
938
+ }
939
+ }
940
+ bubbleDown(i) {
941
+ const n = this.data.length;
942
+ while (true) {
943
+ const l = i * 2 + 1;
944
+ const r = l + 1;
945
+ let smallest = i;
946
+ if (l < n && this.data[l].f < this.data[smallest].f) smallest = l;
947
+ if (r < n && this.data[r].f < this.data[smallest].f) smallest = r;
948
+ if (smallest === i) return;
949
+ const tmp = this.data[i];
950
+ this.data[i] = this.data[smallest];
951
+ this.data[smallest] = tmp;
952
+ i = smallest;
953
+ }
954
+ }
955
+ };
956
+ function aStarRoute(start, end, obstacles, gridSize, inflate, maxNodes) {
957
+ const rects = inflateObstacles(obstacles, inflate);
958
+ const sx = snap(start[0], gridSize);
959
+ const sy = snap(start[1], gridSize);
960
+ const ex = snap(end[0], gridSize);
961
+ const ey = snap(end[1], gridSize);
962
+ if (pointBlocked(sx, sy, rects) || pointBlocked(ex, ey, rects)) return null;
963
+ const startKey = key(sx, sy);
964
+ const endKey = key(ex, ey);
965
+ const gScore = /* @__PURE__ */ new Map([[startKey, 0]]);
966
+ const cameFrom = /* @__PURE__ */ new Map();
967
+ const cameDir = /* @__PURE__ */ new Map([[startKey, null]]);
968
+ const open = new MinHeap();
969
+ open.push({ k: startKey, x: sx, y: sy, f: manhattan(sx, sy, ex, ey) });
970
+ const TURN_PENALTY = gridSize;
971
+ let expansions = 0;
972
+ while (open.size > 0) {
973
+ if (expansions++ > maxNodes) return null;
974
+ const current = open.pop();
975
+ const bestG = gScore.get(current.k) ?? Infinity;
976
+ const expectedF = bestG + manhattan(current.x, current.y, ex, ey);
977
+ if (current.f > expectedF) continue;
978
+ if (current.k === endKey) {
979
+ const path = reconstruct(cameFrom, endKey);
980
+ if (path.length > 0) {
981
+ path[0] = start;
982
+ path[path.length - 1] = end;
983
+ }
984
+ return path;
985
+ }
986
+ const incomingDir = cameDir.get(current.k) ?? null;
987
+ const neighbours = [
988
+ [gridSize, 0, "h"],
989
+ [-gridSize, 0, "h"],
990
+ [0, gridSize, "v"],
991
+ [0, -gridSize, "v"]
992
+ ];
993
+ for (const [dx, dy, dir] of neighbours) {
994
+ const nx = current.x + dx;
995
+ const ny = current.y + dy;
996
+ if (pointBlocked(nx, ny, rects)) continue;
997
+ const turn = incomingDir !== null && incomingDir !== dir;
998
+ const tentativeG = bestG + gridSize + (turn ? TURN_PENALTY : 0);
999
+ const nk = key(nx, ny);
1000
+ const prevG = gScore.get(nk) ?? Infinity;
1001
+ if (tentativeG < prevG) {
1002
+ cameFrom.set(nk, current.k);
1003
+ cameDir.set(nk, dir);
1004
+ gScore.set(nk, tentativeG);
1005
+ const f = tentativeG + manhattan(nx, ny, ex, ey);
1006
+ open.push({ k: nk, x: nx, y: ny, f });
1007
+ }
1008
+ }
1009
+ }
1010
+ return null;
1011
+ }
1012
+
1013
+ // src/engines/graph/obb.ts
1014
+ function obbCorners(obb) {
1015
+ const cos = Math.cos(obb.angle);
1016
+ const sin = Math.sin(obb.angle);
1017
+ const { halfWidth: hw, halfHeight: hh } = obb;
1018
+ const [cx, cy] = obb.center;
1019
+ const lx = [-hw, hw, hw, -hw];
1020
+ const ly = [-hh, -hh, hh, hh];
1021
+ const out = [];
1022
+ for (let i = 0; i < 4; i++) {
1023
+ const x = lx[i];
1024
+ const y = ly[i];
1025
+ out.push([cx + x * cos - y * sin, cy + x * sin + y * cos]);
1026
+ }
1027
+ return out;
1028
+ }
1029
+ function aabbFromOBB(obb) {
1030
+ const corners = obbCorners(obb);
1031
+ let x0 = corners[0][0];
1032
+ let x1 = corners[0][0];
1033
+ let y0 = corners[0][1];
1034
+ let y1 = corners[0][1];
1035
+ for (let i = 1; i < 4; i++) {
1036
+ const [x, y] = corners[i];
1037
+ if (x < x0) x0 = x;
1038
+ if (x > x1) x1 = x;
1039
+ if (y < y0) y0 = y;
1040
+ if (y > y1) y1 = y;
1041
+ }
1042
+ return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };
1043
+ }
1044
+ function obbContainsPoint(obb, p) {
1045
+ const cos = Math.cos(-obb.angle);
1046
+ const sin = Math.sin(-obb.angle);
1047
+ const dx = p[0] - obb.center[0];
1048
+ const dy = p[1] - obb.center[1];
1049
+ const lx = dx * cos - dy * sin;
1050
+ const ly = dx * sin + dy * cos;
1051
+ return Math.abs(lx) <= obb.halfWidth && Math.abs(ly) <= obb.halfHeight;
1052
+ }
1053
+ // Annotate the CommonJS export names for ESM import in node:
1054
+ 0 && (module.exports = {
1055
+ aabbFromOBB,
1056
+ createGraph,
1057
+ getBezierPath,
1058
+ nearestSide,
1059
+ obbContainsPoint,
1060
+ obbCorners,
1061
+ pointsToPath,
1062
+ pointsToRoundedPath,
1063
+ routeOrthogonal
1064
+ });
1065
+ //# sourceMappingURL=graph.cjs.map