@realflow/core 0.1.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 (57) hide show
  1. package/dist/algorithms.d.ts +25 -0
  2. package/dist/algorithms.d.ts.map +1 -0
  3. package/dist/algorithms.js +158 -0
  4. package/dist/algorithms.js.map +1 -0
  5. package/dist/collab.d.ts +105 -0
  6. package/dist/collab.d.ts.map +1 -0
  7. package/dist/collab.js +182 -0
  8. package/dist/collab.js.map +1 -0
  9. package/dist/geometry.d.ts +33 -0
  10. package/dist/geometry.d.ts.map +1 -0
  11. package/dist/geometry.js +113 -0
  12. package/dist/geometry.js.map +1 -0
  13. package/dist/guides.d.ts +14 -0
  14. package/dist/guides.d.ts.map +1 -0
  15. package/dist/guides.js +52 -0
  16. package/dist/guides.js.map +1 -0
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +14 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/layout-worker.d.ts +53 -0
  22. package/dist/layout-worker.d.ts.map +1 -0
  23. package/dist/layout-worker.js +65 -0
  24. package/dist/layout-worker.js.map +1 -0
  25. package/dist/layout.d.ts +97 -0
  26. package/dist/layout.d.ts.map +1 -0
  27. package/dist/layout.js +644 -0
  28. package/dist/layout.js.map +1 -0
  29. package/dist/ops.d.ts +142 -0
  30. package/dist/ops.d.ts.map +1 -0
  31. package/dist/ops.js +351 -0
  32. package/dist/ops.js.map +1 -0
  33. package/dist/paths.d.ts +41 -0
  34. package/dist/paths.d.ts.map +1 -0
  35. package/dist/paths.js +179 -0
  36. package/dist/paths.js.map +1 -0
  37. package/dist/routing.d.ts +36 -0
  38. package/dist/routing.d.ts.map +1 -0
  39. package/dist/routing.js +185 -0
  40. package/dist/routing.js.map +1 -0
  41. package/dist/spatial.d.ts +43 -0
  42. package/dist/spatial.d.ts.map +1 -0
  43. package/dist/spatial.js +175 -0
  44. package/dist/spatial.js.map +1 -0
  45. package/dist/store.d.ts +274 -0
  46. package/dist/store.d.ts.map +1 -0
  47. package/dist/store.js +1610 -0
  48. package/dist/store.js.map +1 -0
  49. package/dist/types.d.ts +207 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +2 -0
  52. package/dist/types.js.map +1 -0
  53. package/dist/utils.d.ts +6 -0
  54. package/dist/utils.d.ts.map +1 -0
  55. package/dist/utils.js +25 -0
  56. package/dist/utils.js.map +1 -0
  57. package/package.json +40 -0
package/dist/paths.js ADDED
@@ -0,0 +1,179 @@
1
+ import { sideDir } from './geometry.js';
2
+ const f = (v) => {
3
+ const r = Math.round(v * 100) / 100;
4
+ return Object.is(r, -0) ? '0' : String(r);
5
+ };
6
+ export const straightPath = (s) => ({
7
+ d: `M ${f(s.source.x)},${f(s.source.y)} L ${f(s.target.x)},${f(s.target.y)}`,
8
+ label: { x: (s.source.x + s.target.x) / 2, y: (s.source.y + s.target.y) / 2 },
9
+ });
10
+ const controlOffset = (dist, curvature) => dist >= 0 ? 0.5 * dist : curvature * 25 * Math.sqrt(-dist);
11
+ const controlPoint = (side, from, to, c) => {
12
+ switch (side) {
13
+ case 'left':
14
+ return { x: from.x - controlOffset(from.x - to.x, c), y: from.y };
15
+ case 'right':
16
+ return { x: from.x + controlOffset(to.x - from.x, c), y: from.y };
17
+ case 'top':
18
+ return { x: from.x, y: from.y - controlOffset(from.y - to.y, c) };
19
+ default:
20
+ return { x: from.x, y: from.y + controlOffset(to.y - from.y, c) };
21
+ }
22
+ };
23
+ const cubicAt = (t, p0, p1, p2, p3) => {
24
+ const u = 1 - t;
25
+ return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
26
+ };
27
+ /** Cubic bezier whose control points extend outward from each handle side. */
28
+ export const bezierPath = (s) => {
29
+ const c = s.curvature ?? 0.25;
30
+ const c1 = controlPoint(s.sourceSide, s.source, s.target, c);
31
+ const c2 = controlPoint(s.targetSide, s.target, s.source, c);
32
+ return {
33
+ d: `M ${f(s.source.x)},${f(s.source.y)} ` +
34
+ `C ${f(c1.x)},${f(c1.y)} ${f(c2.x)},${f(c2.y)} ${f(s.target.x)},${f(s.target.y)}`,
35
+ label: {
36
+ x: cubicAt(0.5, s.source.x, c1.x, c2.x, s.target.x),
37
+ y: cubicAt(0.5, s.source.y, c1.y, c2.y, s.target.y),
38
+ },
39
+ };
40
+ };
41
+ const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
42
+ const dedupe = (pts) => {
43
+ const out = [pts[0]];
44
+ for (let i = 1; i < pts.length; i++) {
45
+ const last = out[out.length - 1];
46
+ if (Math.abs(pts[i].x - last.x) > 1e-9 || Math.abs(pts[i].y - last.y) > 1e-9) {
47
+ out.push(pts[i]);
48
+ }
49
+ }
50
+ return out;
51
+ };
52
+ /**
53
+ * Waypoints for an orthogonal edge, including source and target endpoints.
54
+ * Exported for routing-aware consumers (e.g. custom edges, hit testing).
55
+ */
56
+ export const stepWaypoints = (source, sourceSide, target, targetSide, offset) => {
57
+ const sd = sideDir(sourceSide);
58
+ const td = sideDir(targetSide);
59
+ const sg = { x: source.x + sd.x * offset, y: source.y + sd.y * offset };
60
+ const tg = { x: target.x + td.x * offset, y: target.y + td.y * offset };
61
+ const cx = (sg.x + tg.x) / 2;
62
+ const cy = (sg.y + tg.y) / 2;
63
+ let mid;
64
+ const bothHorizontal = sd.x !== 0 && td.x !== 0;
65
+ const bothVertical = sd.y !== 0 && td.y !== 0;
66
+ if (bothHorizontal && sd.x === -td.x) {
67
+ // Opposing horizontal handles (e.g. right -> left).
68
+ mid =
69
+ sd.x * (tg.x - sg.x) >= 0
70
+ ? [
71
+ { x: cx, y: sg.y },
72
+ { x: cx, y: tg.y },
73
+ ]
74
+ : [
75
+ { x: sg.x, y: cy },
76
+ { x: tg.x, y: cy },
77
+ ];
78
+ }
79
+ else if (bothVertical && sd.y === -td.y) {
80
+ mid =
81
+ sd.y * (tg.y - sg.y) >= 0
82
+ ? [
83
+ { x: sg.x, y: cy },
84
+ { x: tg.x, y: cy },
85
+ ]
86
+ : [
87
+ { x: cx, y: sg.y },
88
+ { x: cx, y: tg.y },
89
+ ];
90
+ }
91
+ else if (bothHorizontal) {
92
+ // Same-side horizontal handles: route via the outermost x.
93
+ const x = sd.x > 0 ? Math.max(sg.x, tg.x) : Math.min(sg.x, tg.x);
94
+ mid = [
95
+ { x, y: sg.y },
96
+ { x, y: tg.y },
97
+ ];
98
+ }
99
+ else if (bothVertical) {
100
+ const y = sd.y > 0 ? Math.max(sg.y, tg.y) : Math.min(sg.y, tg.y);
101
+ mid = [
102
+ { x: sg.x, y },
103
+ { x: tg.x, y },
104
+ ];
105
+ }
106
+ else if (sd.x !== 0) {
107
+ // Perpendicular: horizontal source, vertical target.
108
+ mid = [{ x: tg.x, y: sg.y }];
109
+ }
110
+ else {
111
+ mid = [{ x: sg.x, y: tg.y }];
112
+ }
113
+ return dedupe([source, sg, ...mid, tg, target]);
114
+ };
115
+ const polylineMidpoint = (pts) => {
116
+ let total = 0;
117
+ for (let i = 1; i < pts.length; i++)
118
+ total += dist(pts[i - 1], pts[i]);
119
+ if (total === 0)
120
+ return pts[0];
121
+ let half = total / 2;
122
+ for (let i = 1; i < pts.length; i++) {
123
+ const seg = dist(pts[i - 1], pts[i]);
124
+ if (half <= seg) {
125
+ const t = half / seg;
126
+ return {
127
+ x: pts[i - 1].x + (pts[i].x - pts[i - 1].x) * t,
128
+ y: pts[i - 1].y + (pts[i].y - pts[i - 1].y) * t,
129
+ };
130
+ }
131
+ half -= seg;
132
+ }
133
+ return pts[pts.length - 1];
134
+ };
135
+ /**
136
+ * Turn an orthogonal polyline (e.g. from `routeOrthogonal`) into a smooth
137
+ * SVG path with rounded corners, plus a label anchor at its midpoint.
138
+ */
139
+ export const roundedPath = (pts, radius = 8) => renderRounded(pts, radius);
140
+ const renderRounded = (pts, radius) => {
141
+ let d = `M ${f(pts[0].x)},${f(pts[0].y)}`;
142
+ for (let i = 1; i < pts.length - 1; i++) {
143
+ const prev = pts[i - 1];
144
+ const cur = pts[i];
145
+ const next = pts[i + 1];
146
+ const r = Math.min(radius, dist(prev, cur) / 2, dist(cur, next) / 2);
147
+ if (r <= 0.01) {
148
+ d += ` L ${f(cur.x)},${f(cur.y)}`;
149
+ continue;
150
+ }
151
+ const lin = dist(prev, cur);
152
+ const lout = dist(cur, next);
153
+ const inPt = {
154
+ x: cur.x - ((cur.x - prev.x) / lin) * r,
155
+ y: cur.y - ((cur.y - prev.y) / lin) * r,
156
+ };
157
+ const outPt = {
158
+ x: cur.x + ((next.x - cur.x) / lout) * r,
159
+ y: cur.y + ((next.y - cur.y) / lout) * r,
160
+ };
161
+ d += ` L ${f(inPt.x)},${f(inPt.y)} Q ${f(cur.x)},${f(cur.y)} ${f(outPt.x)},${f(outPt.y)}`;
162
+ }
163
+ const last = pts[pts.length - 1];
164
+ d += ` L ${f(last.x)},${f(last.y)}`;
165
+ return { d, label: polylineMidpoint(pts) };
166
+ };
167
+ /** Orthogonal path with rounded corners. */
168
+ export const smoothStepPath = (s) => renderRounded(stepWaypoints(s.source, s.sourceSide, s.target, s.targetSide, s.offset ?? 20), s.borderRadius ?? 8);
169
+ /** Orthogonal path with square corners. */
170
+ export const stepPath = (s) => renderRounded(stepWaypoints(s.source, s.sourceSide, s.target, s.targetSide, s.offset ?? 20), 0);
171
+ export const pathFns = {
172
+ bezier: bezierPath,
173
+ straight: straightPath,
174
+ smoothstep: smoothStepPath,
175
+ step: stepPath,
176
+ };
177
+ /** Build a path for the given edge type, falling back to bezier. */
178
+ export const edgePath = (type, s) => (pathFns[type ?? 'bezier'] ?? bezierPath)(s);
179
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAsBrC,MAAM,CAAC,GAAG,CAAC,CAAS,EAAU,EAAE;IAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACpC,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAe,EAAY,EAAE,CAAC,CAAC;IAC1D,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;IAC5E,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;CAC9E,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAU,EAAE,CAChE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAE7D,MAAM,YAAY,GAAG,CAAC,IAAU,EAAE,IAAQ,EAAE,EAAM,EAAE,CAAS,EAAM,EAAE;IACnE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACpE,KAAK,OAAO;YACV,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACpE,KAAK,KAAK;YACR,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACpE;YACE,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACtE,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAU,EAAE;IACpF,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;AACnF,CAAC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAe,EAAY,EAAE;IACtD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC;IAC9B,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO;QACL,CAAC,EACC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACtC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACnF,KAAK,EAAE;YACL,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;SACpD;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,CAAK,EAAE,CAAK,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAExE,MAAM,MAAM,GAAG,CAAC,GAAS,EAAQ,EAAE;IACjC,MAAM,GAAG,GAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YAC7E,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAU,EACV,UAAgB,EAChB,MAAU,EACV,UAAgB,EAChB,MAAc,EACR,EAAE;IACR,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC;IACxE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC;IACxE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,GAAS,CAAC;IACd,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrC,oDAAoD;QACpD,GAAG;YACD,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvB,CAAC,CAAC;oBACE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;oBAClB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;iBACnB;gBACH,CAAC,CAAC;oBACE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;oBAClB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;iBACnB,CAAC;IACV,CAAC;SAAM,IAAI,YAAY,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG;YACD,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvB,CAAC,CAAC;oBACE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;oBAClB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;iBACnB;gBACH,CAAC,CAAC;oBACE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;oBAClB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;iBACnB,CAAC;IACV,CAAC;SAAM,IAAI,cAAc,EAAE,CAAC;QAC1B,2DAA2D;QAC3D,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,GAAG,GAAG;YACJ,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;YACd,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;SACf,CAAC;IACJ,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,GAAG,GAAG;YACJ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;YACd,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE;SACf,CAAC;IACJ,CAAC;SAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,qDAAqD;QACrD,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,GAAS,EAAM,EAAE;IACzC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;YACrB,OAAO;gBACL,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC/C,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;aAChD,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,GAAG,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAS,EAAE,MAAM,GAAG,CAAC,EAAY,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAE3F,MAAM,aAAa,GAAG,CAAC,GAAS,EAAE,MAAc,EAAY,EAAE;IAC5D,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YACd,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG;YACX,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;YACvC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC;SACxC,CAAC;QACF,MAAM,KAAK,GAAG;YACZ,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;YACxC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;SACzC,CAAC;QACF,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7C,CAAC,CAAC;AAEF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAe,EAAY,EAAE,CAC1D,aAAa,CACX,aAAa,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAC7E,CAAC,CAAC,YAAY,IAAI,CAAC,CACpB,CAAC;AAEJ,2CAA2C;AAC3C,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAe,EAAY,EAAE,CACpD,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAIlG,MAAM,CAAC,MAAM,OAAO,GAA2B;IAC7C,MAAM,EAAE,UAAU;IAClB,QAAQ,EAAE,YAAY;IACtB,UAAU,EAAE,cAAc;IAC1B,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAwB,EAAE,CAAe,EAAY,EAAE,CAC9E,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { Rect, Side, XY } from './types.js';
2
+ /**
3
+ * Orthogonal edge routing with obstacle avoidance — the feature neither
4
+ * React Flow nor ReFlow shipped before. Edges route around nodes instead of
5
+ * cutting straight through them.
6
+ *
7
+ * The algorithm is an A* search over a **Hanan grid**: the lattice formed by
8
+ * the horizontal and vertical lines through every obstacle edge (plus the
9
+ * endpoints and their stubs). That keeps the search space O(obstacles²)
10
+ * rather than a dense uniform grid, so routing stays fast even with many
11
+ * nodes, while producing clean paths that hug obstacle boundaries.
12
+ */
13
+ export interface RouteSpec {
14
+ source: XY;
15
+ sourceSide: Side;
16
+ target: XY;
17
+ targetSide: Side;
18
+ /** Rectangles to route around (node bounds). */
19
+ obstacles: Rect[];
20
+ /** Clearance kept from obstacles (flow px). Default 10. */
21
+ padding?: number;
22
+ /** Minimum stub length leaving each handle. Default 20. */
23
+ stub?: number;
24
+ /** Extra cost per 90° turn — higher = straighter paths. Default 12. */
25
+ bendPenalty?: number;
26
+ /** Safety cap on lattice size; above it, fall back to a simple L-route. */
27
+ maxLatticePoints?: number;
28
+ }
29
+ /** Drop collinear intermediate points from an orthogonal polyline. */
30
+ export declare const simplifyOrthogonal: (pts: XY[]) => XY[];
31
+ /**
32
+ * Route an orthogonal path from source to target avoiding obstacles.
33
+ * Returns waypoints including the source and target endpoints.
34
+ */
35
+ export declare const routeOrthogonal: (spec: RouteSpec) => XY[];
36
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAG9C;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,EAAE,CAAC;IACX,UAAU,EAAE,IAAI,CAAC;IACjB,MAAM,EAAE,EAAE,CAAC;IACX,UAAU,EAAE,IAAI,CAAC;IACjB,gDAAgD;IAChD,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAuCD,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,GAAI,KAAK,EAAE,EAAE,KAAG,EAAE,EAchD,CAAC;AAmBF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,SAAS,KAAG,EAAE,EAwInD,CAAC"}
@@ -0,0 +1,185 @@
1
+ import { sideDir } from './geometry.js';
2
+ const uniqSorted = (nums) => {
3
+ const out = [...new Set(nums.map((n) => Math.round(n * 100) / 100))];
4
+ out.sort((a, b) => a - b);
5
+ return out;
6
+ };
7
+ const segmentBlocked = (a, b, obstacles, pad) => {
8
+ // Axis-aligned segment vs inflated obstacle interiors.
9
+ const x0 = Math.min(a.x, b.x);
10
+ const x1 = Math.max(a.x, b.x);
11
+ const y0 = Math.min(a.y, b.y);
12
+ const y1 = Math.max(a.y, b.y);
13
+ for (const o of obstacles) {
14
+ const ox0 = o.x - pad;
15
+ const oy0 = o.y - pad;
16
+ const ox1 = o.x + o.width + pad;
17
+ const oy1 = o.y + o.height + pad;
18
+ // Overlap of the (thin) segment box with the obstacle's open interior.
19
+ if (x0 < ox1 && x1 > ox0 && y0 < oy1 && y1 > oy0)
20
+ return true;
21
+ }
22
+ return false;
23
+ };
24
+ const pointInside = (p, obstacles, pad) => {
25
+ for (const o of obstacles) {
26
+ if (p.x > o.x - pad && p.x < o.x + o.width + pad && p.y > o.y - pad && p.y < o.y + o.height + pad) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ };
32
+ /** Drop collinear intermediate points from an orthogonal polyline. */
33
+ export const simplifyOrthogonal = (pts) => {
34
+ if (pts.length <= 2)
35
+ return pts;
36
+ const out = [pts[0]];
37
+ for (let i = 1; i < pts.length - 1; i++) {
38
+ const prev = out[out.length - 1];
39
+ const cur = pts[i];
40
+ const next = pts[i + 1];
41
+ const collinear = (Math.abs(prev.x - cur.x) < 1e-6 && Math.abs(cur.x - next.x) < 1e-6) ||
42
+ (Math.abs(prev.y - cur.y) < 1e-6 && Math.abs(cur.y - next.y) < 1e-6);
43
+ if (!collinear)
44
+ out.push(cur);
45
+ }
46
+ out.push(pts[pts.length - 1]);
47
+ return out;
48
+ };
49
+ /** A simple 3-segment L/Z route used as a fallback (no obstacle avoidance). */
50
+ const simpleRoute = (s, sd, t, td, stub) => {
51
+ const sg = { x: s.x + sd.x * stub, y: s.y + sd.y * stub };
52
+ const tg = { x: t.x + td.x * stub, y: t.y + td.y * stub };
53
+ const mid = sd.x !== 0
54
+ ? [
55
+ { x: (sg.x + tg.x) / 2, y: sg.y },
56
+ { x: (sg.x + tg.x) / 2, y: tg.y },
57
+ ]
58
+ : [
59
+ { x: sg.x, y: (sg.y + tg.y) / 2 },
60
+ { x: tg.x, y: (sg.y + tg.y) / 2 },
61
+ ];
62
+ return simplifyOrthogonal([s, sg, ...mid, tg, t]);
63
+ };
64
+ /**
65
+ * Route an orthogonal path from source to target avoiding obstacles.
66
+ * Returns waypoints including the source and target endpoints.
67
+ */
68
+ export const routeOrthogonal = (spec) => {
69
+ const pad = spec.padding ?? 10;
70
+ const stub = spec.stub ?? 20;
71
+ const bendPenalty = spec.bendPenalty ?? 12;
72
+ const maxPts = spec.maxLatticePoints ?? 4000;
73
+ const sd = sideDir(spec.sourceSide);
74
+ const td = sideDir(spec.targetSide);
75
+ const source = spec.source;
76
+ const target = spec.target;
77
+ const sStub = { x: source.x + sd.x * stub, y: source.y + sd.y * stub };
78
+ const tStub = { x: target.x + td.x * stub, y: target.y + td.y * stub };
79
+ // Only obstacles that could lie between the endpoints matter. Also drop the
80
+ // obstacles that contain the endpoints themselves (the node we exit/enter),
81
+ // so the stubs aren't considered blocked by their own node.
82
+ const bboxX0 = Math.min(source.x, target.x) - 200;
83
+ const bboxY0 = Math.min(source.y, target.y) - 200;
84
+ const bboxX1 = Math.max(source.x, target.x) + 200;
85
+ const bboxY1 = Math.max(source.y, target.y) + 200;
86
+ const obstacles = spec.obstacles.filter((o) => {
87
+ const intersectsBox = o.x <= bboxX1 && o.x + o.width >= bboxX0 && o.y <= bboxY1 && o.y + o.height >= bboxY0;
88
+ if (!intersectsBox)
89
+ return false;
90
+ // Exclude obstacles that contain either endpoint (own node).
91
+ const containsSource = source.x >= o.x - 1 && source.x <= o.x + o.width + 1 && source.y >= o.y - 1 && source.y <= o.y + o.height + 1;
92
+ const containsTarget = target.x >= o.x - 1 && target.x <= o.x + o.width + 1 && target.y >= o.y - 1 && target.y <= o.y + o.height + 1;
93
+ return !containsSource && !containsTarget;
94
+ });
95
+ // Build the Hanan lattice coordinates.
96
+ const xs = uniqSorted([
97
+ source.x, target.x, sStub.x, tStub.x,
98
+ ...obstacles.flatMap((o) => [o.x - pad, o.x + o.width + pad, o.x + o.width / 2]),
99
+ ]);
100
+ const ys = uniqSorted([
101
+ source.y, target.y, sStub.y, tStub.y,
102
+ ...obstacles.flatMap((o) => [o.y - pad, o.y + o.height + pad, o.y + o.height / 2]),
103
+ ]);
104
+ if (xs.length * ys.length > maxPts) {
105
+ return simpleRoute(source, sd, target, td, stub);
106
+ }
107
+ const xi = new Map(xs.map((v, i) => [v, i]));
108
+ const yi = new Map(ys.map((v, i) => [v, i]));
109
+ const key = (ix, iy) => iy * xs.length + ix;
110
+ const startIx = xi.get(Math.round(sStub.x * 100) / 100);
111
+ const startIy = yi.get(Math.round(sStub.y * 100) / 100);
112
+ const goalIx = xi.get(Math.round(tStub.x * 100) / 100);
113
+ const goalIy = yi.get(Math.round(tStub.y * 100) / 100);
114
+ if (startIx == null || goalIx == null)
115
+ return simpleRoute(source, sd, target, td, stub);
116
+ const pt = (ix, iy) => ({ x: xs[ix], y: ys[iy] });
117
+ const goalKey = key(goalIx, goalIy);
118
+ const stateKey = (ix, iy, dir) => `${ix}:${iy}:${dir}`;
119
+ const startState = stateKey(startIx, startIy, 0);
120
+ const open = [
121
+ { ix: startIx, iy: startIy, dir: 0, g: 0, f: 0, state: startState },
122
+ ];
123
+ const best = new Map();
124
+ const cameFrom = new Map();
125
+ const heuristic = (ix, iy) => Math.abs(xs[ix] - tStub.x) + Math.abs(ys[iy] - tStub.y);
126
+ const popMin = () => {
127
+ let mi = 0;
128
+ for (let i = 1; i < open.length; i++)
129
+ if (open[i].f < open[mi].f)
130
+ mi = i;
131
+ return open.splice(mi, 1)[0];
132
+ };
133
+ let goalState = null;
134
+ while (open.length > 0) {
135
+ const cur = popMin();
136
+ if (best.has(cur.state) && best.get(cur.state) < cur.g)
137
+ continue;
138
+ if (key(cur.ix, cur.iy) === goalKey) {
139
+ goalState = cur.state;
140
+ break;
141
+ }
142
+ const neighbors = [
143
+ [cur.ix + 1, cur.iy, 1],
144
+ [cur.ix - 1, cur.iy, 1],
145
+ [cur.ix, cur.iy + 1, 2],
146
+ [cur.ix, cur.iy - 1, 2],
147
+ ];
148
+ for (const [nx, ny, dir] of neighbors) {
149
+ if (nx < 0 || nx >= xs.length || ny < 0 || ny >= ys.length)
150
+ continue;
151
+ const a = pt(cur.ix, cur.iy);
152
+ const b = pt(nx, ny);
153
+ if (segmentBlocked(a, b, obstacles, pad - 0.5))
154
+ continue;
155
+ const stepCost = Math.abs(b.x - a.x) + Math.abs(b.y - a.y);
156
+ const turn = cur.dir !== 0 && cur.dir !== dir ? bendPenalty : 0;
157
+ const g = cur.g + stepCost + turn;
158
+ const sk = stateKey(nx, ny, dir);
159
+ if (best.has(sk) && best.get(sk) <= g)
160
+ continue;
161
+ best.set(sk, g);
162
+ cameFrom.set(sk, cur.state);
163
+ open.push({ ix: nx, iy: ny, dir, g, f: g + heuristic(nx, ny), state: sk });
164
+ }
165
+ }
166
+ if (goalState == null)
167
+ return simpleRoute(source, sd, target, td, stub);
168
+ // Reconstruct lattice path from the winning goal state.
169
+ const path = [];
170
+ let cur = goalState;
171
+ const guard = new Set();
172
+ while (cur != null && !guard.has(cur)) {
173
+ guard.add(cur);
174
+ const [ixs, iys] = cur.split(':');
175
+ path.unshift(pt(Number(ixs), Number(iys)));
176
+ cur = cameFrom.get(cur);
177
+ }
178
+ // Attach the real endpoints (handle border) to the stubs.
179
+ const full = [source, ...path, target];
180
+ return simplifyOrthogonal(full).filter(
181
+ // Drop any interior point that ended up inside an obstacle (rare, from
182
+ // rounding); endpoints are always kept.
183
+ (p, i, arr) => i === 0 || i === arr.length - 1 || !pointInside(p, obstacles, pad - 2));
184
+ };
185
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { Rect } from './types.js';
2
+ /**
3
+ * A uniform-grid spatial hash for fast viewport culling and hit testing.
4
+ *
5
+ * Nodes are bucketed by the grid cells their bounds overlap. Queries visit
6
+ * only the cells intersecting the query rect, so lookups stay O(result)
7
+ * instead of O(total nodes) — the key to keeping 10k+ node flows smooth.
8
+ */
9
+ export declare class SpatialIndex {
10
+ private cellSize;
11
+ private cells;
12
+ private bounds;
13
+ /**
14
+ * Rects too large (or non-finite) to bucket sanely. Iterating the grid
15
+ * cells of, say, a 1e308-wide rect would loop ~1e305 times and hang — a
16
+ * real DoS vector when an agent/LLM emits a degenerate node size. Such
17
+ * rects are kept here and always considered by queries/hits instead.
18
+ */
19
+ private oversized;
20
+ /** Max grid cells a single rect may span before it's treated as oversized. */
21
+ private static readonly MAX_CELLS;
22
+ constructor(cellSize?: number);
23
+ get size(): number;
24
+ /**
25
+ * Largest cell index magnitude we bucket. Beyond ~2^40, floating-point
26
+ * `index++` stops advancing (1 is lost past 2^53), so a `for` loop over
27
+ * cell keys would never terminate. Cap well below that.
28
+ */
29
+ private static readonly MAX_CELL_INDEX;
30
+ /** True when a rect can't be bucketed sanely (too big, too far out, or non-finite). */
31
+ private isOversized;
32
+ private cellKeys;
33
+ set(id: string, rect: Rect): void;
34
+ delete(id: string): void;
35
+ private removeFromCells;
36
+ getBounds(id: string): Rect | undefined;
37
+ /** Ids whose bounds intersect the query rect. */
38
+ query(rect: Rect): Set<string>;
39
+ /** Ids whose bounds contain the point. */
40
+ hit(x: number, y: number): string[];
41
+ clear(): void;
42
+ }
43
+ //# sourceMappingURL=spatial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial.d.ts","sourceRoot":"","sources":["../src/spatial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAGpC;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,MAAM,CAA2B;IACzC;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAqB;IAEtC,8EAA8E;IAC9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAE7B,QAAQ,SAAM;IAI1B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAW;IAEjD,uFAAuF;IACvF,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAE,QAAQ;IAajB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI;IA4BjC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQxB,OAAO,CAAC,eAAe;IAYvB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIvC,iDAAiD;IACjD,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;IAwB9B,0CAA0C;IAC1C,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAiBnC,KAAK,IAAI,IAAI;CAKd"}