@vibecook/ice 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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/chunk-5S7GSXJG.js +6003 -0
  4. package/dist/chunk-5S7GSXJG.js.map +1 -0
  5. package/dist/chunk-BCJ47SX7.js +550 -0
  6. package/dist/chunk-BCJ47SX7.js.map +1 -0
  7. package/dist/chunk-FIAXPNNY.js +1446 -0
  8. package/dist/chunk-FIAXPNNY.js.map +1 -0
  9. package/dist/devtools.js +417 -0
  10. package/dist/devtools.js.map +1 -0
  11. package/dist/dom.js +41 -0
  12. package/dist/dom.js.map +1 -0
  13. package/dist/index.js +450 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/kernel.js +63 -0
  16. package/dist/kernel.js.map +1 -0
  17. package/dist/r3f.js +1101 -0
  18. package/dist/r3f.js.map +1 -0
  19. package/dist/react.js +440 -0
  20. package/dist/react.js.map +1 -0
  21. package/dist/types/packages/core/src/boot/hmr.d.ts +12 -0
  22. package/dist/types/packages/core/src/catalog/camera-derived.d.ts +144 -0
  23. package/dist/types/packages/core/src/catalog/gesture.d.ts +254 -0
  24. package/dist/types/packages/core/src/catalog/graph.d.ts +55 -0
  25. package/dist/types/packages/core/src/catalog/index.d.ts +32 -0
  26. package/dist/types/packages/core/src/catalog/pointer.d.ts +111 -0
  27. package/dist/types/packages/core/src/catalog/scene.d.ts +34 -0
  28. package/dist/types/packages/core/src/catalog/selection-presence.d.ts +53 -0
  29. package/dist/types/packages/core/src/catalog/settings-resources.d.ts +46 -0
  30. package/dist/types/packages/core/src/doc/autosave.d.ts +69 -0
  31. package/dist/types/packages/core/src/doc/bootstrap.d.ts +74 -0
  32. package/dist/types/packages/core/src/doc/broadcast-relay.d.ts +52 -0
  33. package/dist/types/packages/core/src/doc/channels.d.ts +49 -0
  34. package/dist/types/packages/core/src/doc/doc-commit-sink.d.ts +22 -0
  35. package/dist/types/packages/core/src/doc/doc-kit.d.ts +50 -0
  36. package/dist/types/packages/core/src/doc/envelope.d.ts +36 -0
  37. package/dist/types/packages/core/src/doc/migrate.d.ts +69 -0
  38. package/dist/types/packages/core/src/doc/version-gate.d.ts +49 -0
  39. package/dist/types/packages/core/src/engine/commit-sink.d.ts +61 -0
  40. package/dist/types/packages/core/src/engine/engine.d.ts +62 -0
  41. package/dist/types/packages/core/src/engine/frame-info.d.ts +16 -0
  42. package/dist/types/packages/core/src/engine/instantiate.d.ts +45 -0
  43. package/dist/types/packages/core/src/engine/pipeline.d.ts +17 -0
  44. package/dist/types/packages/core/src/engine/reflectors.d.ts +56 -0
  45. package/dist/types/packages/core/src/facade/create-canvas-engine.d.ts +120 -0
  46. package/dist/types/packages/core/src/guards/dev.d.ts +2 -0
  47. package/dist/types/packages/core/src/guards/guarded-tx.d.ts +51 -0
  48. package/dist/types/packages/core/src/guards/live-writer.d.ts +33 -0
  49. package/dist/types/packages/core/src/guards/resource-writer.d.ts +17 -0
  50. package/dist/types/packages/core/src/helpers/phase-set.d.ts +70 -0
  51. package/dist/types/packages/core/src/helpers/version-stamps.d.ts +55 -0
  52. package/dist/types/packages/core/src/index.d.ts +63 -0
  53. package/dist/types/packages/core/src/input/measure-queue.d.ts +30 -0
  54. package/dist/types/packages/core/src/input/queue.d.ts +60 -0
  55. package/dist/types/packages/core/src/interaction/install.d.ts +58 -0
  56. package/dist/types/packages/core/src/nav/nested-canvas.d.ts +62 -0
  57. package/dist/types/packages/core/src/ops/cascade.d.ts +18 -0
  58. package/dist/types/packages/core/src/ops/claims.d.ts +15 -0
  59. package/dist/types/packages/core/src/ops/gestures.d.ts +10 -0
  60. package/dist/types/packages/core/src/ops/point-pick.d.ts +42 -0
  61. package/dist/types/packages/core/src/ops/port-geometry.d.ts +17 -0
  62. package/dist/types/packages/core/src/ops/selection.d.ts +14 -0
  63. package/dist/types/packages/core/src/presence/index.d.ts +7 -0
  64. package/dist/types/packages/core/src/presence/presence-kit.d.ts +39 -0
  65. package/dist/types/packages/core/src/presence/publish.d.ts +14 -0
  66. package/dist/types/packages/core/src/presence/remote-cursors.d.ts +18 -0
  67. package/dist/types/packages/core/src/schema/meta.d.ts +43 -0
  68. package/dist/types/packages/core/src/schema/prefab.d.ts +69 -0
  69. package/dist/types/packages/core/src/settings/defaults.d.ts +56 -0
  70. package/dist/types/packages/core/src/systems/camera-sim.d.ts +19 -0
  71. package/dist/types/packages/core/src/systems/chrome.d.ts +48 -0
  72. package/dist/types/packages/core/src/systems/cleanup.d.ts +19 -0
  73. package/dist/types/packages/core/src/systems/l0-input.d.ts +31 -0
  74. package/dist/types/packages/core/src/systems/l1-pick.d.ts +44 -0
  75. package/dist/types/packages/core/src/systems/l1-wires.d.ts +30 -0
  76. package/dist/types/packages/core/src/systems/l2-arbitrate.d.ts +40 -0
  77. package/dist/types/packages/core/src/systems/l2-recognize.d.ts +45 -0
  78. package/dist/types/packages/core/src/systems/l3-behave.d.ts +24 -0
  79. package/dist/types/packages/core/src/systems/l3-claim.d.ts +26 -0
  80. package/dist/types/packages/core/src/systems/l3-connect.d.ts +57 -0
  81. package/dist/types/packages/core/src/systems/l3-draw.d.ts +21 -0
  82. package/dist/types/packages/core/src/systems/l3-drop.d.ts +21 -0
  83. package/dist/types/packages/core/src/systems/l3-marquee.d.ts +35 -0
  84. package/dist/types/packages/core/src/systems/l3-ports.d.ts +30 -0
  85. package/dist/types/packages/core/src/systems/l3-resize.d.ts +17 -0
  86. package/dist/types/packages/core/src/systems/l3-snap.d.ts +19 -0
  87. package/dist/types/packages/core/src/systems/l4-cursor.d.ts +24 -0
  88. package/dist/types/packages/core/src/systems/measure-ingest.d.ts +26 -0
  89. package/dist/types/packages/core/src/tools/define-tool.d.ts +79 -0
  90. package/dist/types/packages/core/src/widget/define-widget.d.ts +124 -0
  91. package/dist/types/packages/core/src/widget/equip.d.ts +14 -0
  92. package/dist/types/packages/core/src/widget/mount-store.d.ts +47 -0
  93. package/dist/types/packages/core/src/widget/props.d.ts +98 -0
  94. package/dist/types/packages/core/src/widget/spawn.d.ts +30 -0
  95. package/dist/types/packages/devtools/src/index.d.ts +8 -0
  96. package/dist/types/packages/devtools/src/panel.d.ts +48 -0
  97. package/dist/types/packages/dom/src/host.d.ts +24 -0
  98. package/dist/types/packages/dom/src/index.d.ts +19 -0
  99. package/dist/types/packages/dom/src/loop.d.ts +11 -0
  100. package/dist/types/packages/dom/src/measure-adapter.d.ts +31 -0
  101. package/dist/types/packages/dom/src/measure-wiring.d.ts +49 -0
  102. package/dist/types/packages/dom/src/planes.d.ts +33 -0
  103. package/dist/types/packages/dom/src/pointer-adapter.d.ts +48 -0
  104. package/dist/types/packages/dom/src/reflectors/chrome.d.ts +33 -0
  105. package/dist/types/packages/dom/src/reflectors/cursor.d.ts +21 -0
  106. package/dist/types/packages/dom/src/reflectors/dom-widgets.d.ts +54 -0
  107. package/dist/types/packages/dom/src/reflectors/graybox.d.ts +31 -0
  108. package/dist/types/packages/dom/src/reflectors/grid.d.ts +63 -0
  109. package/dist/types/packages/dom/src/reflectors/plane-transform.d.ts +38 -0
  110. package/dist/types/packages/dom/src/reflectors/remote-cursors.d.ts +20 -0
  111. package/dist/types/packages/dom/src/reflectors/wires.d.ts +88 -0
  112. package/dist/types/packages/ice/src/devtools.d.ts +1 -0
  113. package/dist/types/packages/ice/src/dom.d.ts +1 -0
  114. package/dist/types/packages/ice/src/index.d.ts +1 -0
  115. package/dist/types/packages/ice/src/kernel.d.ts +1 -0
  116. package/dist/types/packages/ice/src/r3f.d.ts +1 -0
  117. package/dist/types/packages/ice/src/react.d.ts +1 -0
  118. package/dist/types/packages/kernel/src/anchors.d.ts +18 -0
  119. package/dist/types/packages/kernel/src/bezier.d.ts +38 -0
  120. package/dist/types/packages/kernel/src/coords.d.ts +67 -0
  121. package/dist/types/packages/kernel/src/eviction.d.ts +23 -0
  122. package/dist/types/packages/kernel/src/index.d.ts +13 -0
  123. package/dist/types/packages/kernel/src/shapes.d.ts +22 -0
  124. package/dist/types/packages/kernel/src/snap.d.ts +44 -0
  125. package/dist/types/packages/kernel/src/spatial-index.d.ts +16 -0
  126. package/dist/types/packages/kernel/src/zoom-bands.d.ts +19 -0
  127. package/dist/types/packages/r3f/src/bridge.d.ts +68 -0
  128. package/dist/types/packages/r3f/src/composite-material.d.ts +17 -0
  129. package/dist/types/packages/r3f/src/compositor-pass.d.ts +83 -0
  130. package/dist/types/packages/r3f/src/dev-write-trap.d.ts +30 -0
  131. package/dist/types/packages/r3f/src/gl-root.d.ts +21 -0
  132. package/dist/types/packages/r3f/src/gl-router.d.ts +60 -0
  133. package/dist/types/packages/r3f/src/index.d.ts +16 -0
  134. package/dist/types/packages/r3f/src/island-state.d.ts +68 -0
  135. package/dist/types/packages/r3f/src/island.d.ts +13 -0
  136. package/dist/types/packages/r3f/src/pool.d.ts +56 -0
  137. package/dist/types/packages/r3f/src/resource-registry.d.ts +30 -0
  138. package/dist/types/packages/r3f/src/use-island-frame.d.ts +24 -0
  139. package/dist/types/packages/react/src/engine-context.d.ts +31 -0
  140. package/dist/types/packages/react/src/hooks.d.ts +40 -0
  141. package/dist/types/packages/react/src/index.d.ts +14 -0
  142. package/dist/types/packages/react/src/infinite-canvas.d.ts +71 -0
  143. package/dist/types/packages/react/src/keymap.d.ts +42 -0
  144. package/dist/types/packages/react/src/use-commit.d.ts +35 -0
  145. package/dist/types/packages/react/src/use-presence.d.ts +23 -0
  146. package/dist/types/packages/react/src/use-tool.d.ts +4 -0
  147. package/dist/types/packages/react/src/widget-root.d.ts +33 -0
  148. package/package.json +112 -0
@@ -0,0 +1,550 @@
1
+ // ../kernel/src/shapes.ts
2
+ function rectToAABB(r) {
3
+ return { minX: r.x, minY: r.y, maxX: r.x + r.width, maxY: r.y + r.height };
4
+ }
5
+ function aabbToRect(a) {
6
+ return { x: a.minX, y: a.minY, width: a.maxX - a.minX, height: a.maxY - a.minY };
7
+ }
8
+ function intersectsAABB(a, b) {
9
+ return a.maxX >= b.minX && a.minX <= b.maxX && a.maxY >= b.minY && a.minY <= b.maxY;
10
+ }
11
+ function pointInAABB(px, py, a) {
12
+ return px >= a.minX && px <= a.maxX && py >= a.minY && py <= a.maxY;
13
+ }
14
+ function clamp(value, min, max) {
15
+ return Math.max(min, Math.min(max, value));
16
+ }
17
+
18
+ // ../kernel/src/coords.ts
19
+ function screenToWorld(screenX, screenY, camera) {
20
+ return {
21
+ x: screenX / camera.zoom + camera.x,
22
+ y: screenY / camera.zoom + camera.y
23
+ };
24
+ }
25
+ function worldToScreen(worldX, worldY, camera) {
26
+ return {
27
+ x: (worldX - camera.x) * camera.zoom,
28
+ y: (worldY - camera.y) * camera.zoom
29
+ };
30
+ }
31
+ function zoomAtPoint(camera, screenX, screenY, newZoom) {
32
+ const anchor = screenToWorld(screenX, screenY, camera);
33
+ return {
34
+ x: anchor.x - screenX / newZoom,
35
+ y: anchor.y - screenY / newZoom,
36
+ zoom: newZoom
37
+ };
38
+ }
39
+ function planeCssTransform(camera) {
40
+ return {
41
+ tx: -camera.x * camera.zoom,
42
+ ty: -camera.y * camera.zoom,
43
+ scale: camera.zoom
44
+ };
45
+ }
46
+ function worldToIsland(worldX, worldY, widget) {
47
+ return {
48
+ x: worldX - (widget.x + widget.width / 2),
49
+ y: -(worldY - (widget.y + widget.height / 2))
50
+ };
51
+ }
52
+ function islandToWorld(islandX, islandY, widget) {
53
+ return {
54
+ x: widget.x + widget.width / 2 + islandX,
55
+ y: widget.y + widget.height / 2 - islandY
56
+ };
57
+ }
58
+ function compositeCameraFrustum(camera, viewportW, viewportH) {
59
+ return {
60
+ left: 0,
61
+ right: viewportW / camera.zoom,
62
+ top: 0,
63
+ bottom: -(viewportH / camera.zoom),
64
+ x: camera.x,
65
+ y: -camera.y
66
+ };
67
+ }
68
+ function worldRectToComposite(rect) {
69
+ return {
70
+ x: rect.x + rect.width / 2,
71
+ y: -(rect.y + rect.height / 2),
72
+ sx: rect.width,
73
+ sy: rect.height
74
+ };
75
+ }
76
+
77
+ // ../kernel/src/snap.ts
78
+ function computeSnapGuides(dragged, references, threshold) {
79
+ const guides = [];
80
+ const spacings = [];
81
+ let snapDx = 0;
82
+ let snapDy = 0;
83
+ const dLeft = dragged.x;
84
+ const dRight = dragged.x + dragged.width;
85
+ const dCenterX = dragged.x + dragged.width / 2;
86
+ const dTop = dragged.y;
87
+ const dBottom = dragged.y + dragged.height;
88
+ const dCenterY = dragged.y + dragged.height / 2;
89
+ let bestSnapX = Number.POSITIVE_INFINITY;
90
+ let bestSnapY = Number.POSITIVE_INFINITY;
91
+ let bestDx = 0;
92
+ let bestDy = 0;
93
+ const xGuides = [];
94
+ const yGuides = [];
95
+ for (const ref of references) {
96
+ const rLeft = ref.x;
97
+ const rRight = ref.x + ref.width;
98
+ const rCenterX = ref.x + ref.width / 2;
99
+ const rTop = ref.y;
100
+ const rBottom = ref.y + ref.height;
101
+ const rCenterY = ref.y + ref.height / 2;
102
+ const xPairs = [
103
+ [dLeft, rLeft, "edge"],
104
+ [dLeft, rRight, "edge"],
105
+ [dRight, rLeft, "edge"],
106
+ [dRight, rRight, "edge"],
107
+ [dCenterX, rCenterX, "center"],
108
+ [dLeft, rCenterX, "edge"],
109
+ [dRight, rCenterX, "edge"]
110
+ ];
111
+ for (const [dVal, rVal, type] of xPairs) {
112
+ const dist = Math.abs(dVal - rVal);
113
+ if (dist <= threshold) {
114
+ const dx = rVal - dVal;
115
+ if (dist < bestSnapX) {
116
+ bestSnapX = dist;
117
+ bestDx = dx;
118
+ xGuides.length = 0;
119
+ }
120
+ if (dist <= bestSnapX + 0.01) {
121
+ xGuides.push({ axis: "x", position: rVal, type });
122
+ }
123
+ }
124
+ }
125
+ const yPairs = [
126
+ [dTop, rTop, "edge"],
127
+ [dTop, rBottom, "edge"],
128
+ [dBottom, rTop, "edge"],
129
+ [dBottom, rBottom, "edge"],
130
+ [dCenterY, rCenterY, "center"],
131
+ [dTop, rCenterY, "edge"],
132
+ [dBottom, rCenterY, "edge"]
133
+ ];
134
+ for (const [dVal, rVal, type] of yPairs) {
135
+ const dist = Math.abs(dVal - rVal);
136
+ if (dist <= threshold) {
137
+ const dy = rVal - dVal;
138
+ if (dist < bestSnapY) {
139
+ bestSnapY = dist;
140
+ bestDy = dy;
141
+ yGuides.length = 0;
142
+ }
143
+ if (dist <= bestSnapY + 0.01) {
144
+ yGuides.push({ axis: "y", position: rVal, type });
145
+ }
146
+ }
147
+ }
148
+ }
149
+ const eqResult = computeEqualSpacing(dragged, references, threshold);
150
+ if (bestSnapX <= threshold) {
151
+ snapDx = bestDx;
152
+ } else if (eqResult.snapDx !== void 0) {
153
+ snapDx = eqResult.snapDx;
154
+ }
155
+ if (bestSnapY <= threshold) {
156
+ snapDy = bestDy;
157
+ } else if (eqResult.snapDy !== void 0) {
158
+ snapDy = eqResult.snapDy;
159
+ }
160
+ if (bestSnapX <= threshold) {
161
+ const seen = /* @__PURE__ */ new Set();
162
+ for (const g of xGuides) {
163
+ if (!seen.has(g.position)) {
164
+ seen.add(g.position);
165
+ guides.push(g);
166
+ }
167
+ }
168
+ }
169
+ if (bestSnapY <= threshold) {
170
+ const seen = /* @__PURE__ */ new Set();
171
+ for (const g of yGuides) {
172
+ if (!seen.has(g.position)) {
173
+ seen.add(g.position);
174
+ guides.push(g);
175
+ }
176
+ }
177
+ }
178
+ const snappedBounds = {
179
+ x: dragged.x + snapDx,
180
+ y: dragged.y + snapDy,
181
+ width: dragged.width,
182
+ height: dragged.height
183
+ };
184
+ const eqFinal = computeEqualSpacing(snappedBounds, references, threshold * 0.5);
185
+ spacings.push(...eqFinal.indicators);
186
+ return { snapDx, snapDy, guides, spacings };
187
+ }
188
+ function computeEqualSpacing(dragged, references, threshold) {
189
+ const indicators = [];
190
+ let snapDx;
191
+ let snapDy;
192
+ const xResult = checkAxisSpacing(dragged, references, threshold, "x");
193
+ if (xResult) {
194
+ snapDx = xResult.snap;
195
+ indicators.push(...xResult.indicators);
196
+ }
197
+ const yResult = checkAxisSpacing(dragged, references, threshold, "y");
198
+ if (yResult) {
199
+ snapDy = yResult.snap;
200
+ indicators.push(...yResult.indicators);
201
+ }
202
+ return { snapDx, snapDy, indicators };
203
+ }
204
+ function checkAxisSpacing(dragged, references, threshold, axis) {
205
+ const isX = axis === "x";
206
+ const pos = (b) => isX ? b.x : b.y;
207
+ const size = (b) => isX ? b.width : b.height;
208
+ const perpPos = (b) => isX ? b.y : b.x;
209
+ const perpSize = (b) => isX ? b.height : b.width;
210
+ const end = (b) => pos(b) + size(b);
211
+ const neighbors = references.filter(
212
+ (ref) => perpPos(ref) < perpPos(dragged) + perpSize(dragged) && perpPos(ref) + perpSize(ref) > perpPos(dragged)
213
+ );
214
+ if (neighbors.length < 1) return null;
215
+ const sorted = [...neighbors].sort((a, b) => pos(a) - pos(b));
216
+ const refGaps = [];
217
+ for (let i = 0; i < sorted.length - 1; i++) {
218
+ const a = sorted[i];
219
+ const b = sorted[i + 1];
220
+ if (a === void 0 || b === void 0) continue;
221
+ const gap = pos(b) - end(a);
222
+ if (gap > 0.1) refGaps.push({ from: a, to: b, gap });
223
+ }
224
+ let bestSnap = null;
225
+ let bestIndicators = [];
226
+ let bestDiff = Number.POSITIVE_INFINITY;
227
+ let leftN = null;
228
+ let rightN = null;
229
+ for (const ref of sorted) {
230
+ if (end(ref) <= pos(dragged) + threshold) {
231
+ if (!leftN || end(ref) > end(leftN)) leftN = ref;
232
+ }
233
+ if (pos(ref) >= end(dragged) - threshold) {
234
+ if (!rightN || pos(ref) < pos(rightN)) rightN = ref;
235
+ }
236
+ }
237
+ if (leftN && rightN) {
238
+ const lGap = pos(dragged) - end(leftN);
239
+ const rGap = pos(rightN) - end(dragged);
240
+ const diff = Math.abs(lGap - rGap);
241
+ if (diff <= threshold && diff < bestDiff) {
242
+ const idealPos = (end(leftN) + pos(rightN) - size(dragged)) / 2;
243
+ const snap = idealPos - pos(dragged);
244
+ const equalGap = (pos(rightN) - end(leftN) - size(dragged)) / 2;
245
+ if (equalGap > 0.1) {
246
+ const perpY = computePerpCenter(dragged, [leftN, rightN], isX);
247
+ bestSnap = snap;
248
+ bestDiff = diff;
249
+ bestIndicators = [
250
+ {
251
+ axis,
252
+ gap: equalGap,
253
+ segments: [
254
+ { from: end(leftN), to: idealPos },
255
+ { from: idealPos + size(dragged), to: pos(rightN) }
256
+ ],
257
+ perpPosition: perpY
258
+ }
259
+ ];
260
+ }
261
+ }
262
+ }
263
+ for (const refGap of refGaps) {
264
+ const patternGap = refGap.gap;
265
+ if (rightN === null || pos(refGap.to) >= end(dragged) - threshold * 2) {
266
+ const chainEnd = refGap.to;
267
+ const dragGap = pos(dragged) - end(chainEnd);
268
+ const diff = Math.abs(dragGap - patternGap);
269
+ if (diff <= threshold && diff < bestDiff) {
270
+ const idealPos = end(chainEnd) + patternGap;
271
+ const snap = idealPos - pos(dragged);
272
+ const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);
273
+ bestSnap = snap;
274
+ bestDiff = diff;
275
+ bestIndicators = [
276
+ {
277
+ axis,
278
+ gap: patternGap,
279
+ segments: [
280
+ { from: end(refGap.from), to: pos(refGap.to) },
281
+ { from: end(chainEnd), to: idealPos }
282
+ ],
283
+ perpPosition: perpY
284
+ }
285
+ ];
286
+ }
287
+ }
288
+ if (leftN === null || end(refGap.from) <= pos(dragged) + threshold * 2) {
289
+ const chainStart = refGap.from;
290
+ const dragGap = pos(chainStart) - end(dragged);
291
+ const diff = Math.abs(dragGap - patternGap);
292
+ if (diff <= threshold && diff < bestDiff) {
293
+ const idealPos = pos(chainStart) - patternGap - size(dragged);
294
+ const snap = idealPos - pos(dragged);
295
+ const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);
296
+ bestSnap = snap;
297
+ bestDiff = diff;
298
+ bestIndicators = [
299
+ {
300
+ axis,
301
+ gap: patternGap,
302
+ segments: [
303
+ { from: idealPos + size(dragged), to: pos(chainStart) },
304
+ { from: end(refGap.from), to: pos(refGap.to) }
305
+ ],
306
+ perpPosition: perpY
307
+ }
308
+ ];
309
+ }
310
+ }
311
+ }
312
+ if (bestSnap !== null) return { snap: bestSnap, indicators: bestIndicators };
313
+ return null;
314
+ }
315
+ function computePerpCenter(dragged, refs, isX) {
316
+ const perpPos = (b) => isX ? b.y : b.x;
317
+ const perpSize = (b) => isX ? b.height : b.width;
318
+ const allBounds = [dragged, ...refs];
319
+ const maxStart = Math.max(...allBounds.map(perpPos));
320
+ const minEnd = Math.min(...allBounds.map((b) => perpPos(b) + perpSize(b)));
321
+ if (minEnd < maxStart) {
322
+ return perpPos(dragged) + perpSize(dragged) / 2;
323
+ }
324
+ return maxStart + (minEnd - maxStart) / 2;
325
+ }
326
+
327
+ // ../kernel/src/spatial-index.ts
328
+ import RBushImport from "rbush";
329
+ var rbushModule = RBushImport;
330
+ var RBush = typeof rbushModule.default === "function" ? rbushModule.default : RBushImport;
331
+ var SpatialIndex = class {
332
+ tree = new RBush();
333
+ entries = /* @__PURE__ */ new Map();
334
+ upsert(id, bounds) {
335
+ const existing = this.entries.get(id);
336
+ if (existing) this.tree.remove(existing);
337
+ const entry = { ...bounds, id };
338
+ this.entries.set(id, entry);
339
+ this.tree.insert(entry);
340
+ }
341
+ remove(id) {
342
+ const existing = this.entries.get(id);
343
+ if (existing) {
344
+ this.tree.remove(existing);
345
+ this.entries.delete(id);
346
+ }
347
+ }
348
+ /** All entries intersecting the given AABB. */
349
+ search(bounds) {
350
+ return this.tree.search(bounds);
351
+ }
352
+ /** Entries within `tolerance` of a point (z-priority is the caller's job). */
353
+ searchPoint(x, y, tolerance = 0) {
354
+ return this.tree.search({
355
+ minX: x - tolerance,
356
+ minY: y - tolerance,
357
+ maxX: x + tolerance,
358
+ maxY: y + tolerance
359
+ });
360
+ }
361
+ clear() {
362
+ this.tree.clear();
363
+ this.entries.clear();
364
+ }
365
+ get size() {
366
+ return this.entries.size;
367
+ }
368
+ };
369
+
370
+ // ../kernel/src/zoom-bands.ts
371
+ var ZOOM_BANDS = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16];
372
+ var MIN_BAND = 0.0625;
373
+ var MAX_BAND = 16;
374
+ function selectBand(zoom) {
375
+ if (zoom <= MIN_BAND) return MIN_BAND;
376
+ if (zoom >= MAX_BAND) return MAX_BAND;
377
+ for (const b of ZOOM_BANDS) {
378
+ if (zoom <= b) return b;
379
+ }
380
+ return MAX_BAND;
381
+ }
382
+ function isOutOfBand(currentZoom, paintedBand) {
383
+ if (paintedBand <= 0) return false;
384
+ const ratio = currentZoom / paintedBand;
385
+ return ratio > 2 || ratio < 0.5;
386
+ }
387
+ function fboPixelSize(worldWidth, worldHeight, dpr, band) {
388
+ return {
389
+ width: Math.max(1, Math.round(worldWidth * dpr * band)),
390
+ height: Math.max(1, Math.round(worldHeight * dpr * band))
391
+ };
392
+ }
393
+
394
+ // ../kernel/src/eviction.ts
395
+ var PHASE_PRIORITY = {
396
+ Cold: 0,
397
+ Warm: 1,
398
+ Dormant: 2,
399
+ Waking: Number.POSITIVE_INFINITY,
400
+ Hot: Number.POSITIVE_INFINITY
401
+ };
402
+ function computeIslandPhase(active, visible, animating, hasFbo) {
403
+ if (!active) return "Dormant";
404
+ if (visible) {
405
+ if (animating) return "Hot";
406
+ return hasFbo ? "Warm" : "Waking";
407
+ }
408
+ return "Cold";
409
+ }
410
+ function selectEvictions(candidates, totalBytes, maxBytes) {
411
+ if (totalBytes <= maxBytes) return [];
412
+ const eligible = candidates.filter((c) => Number.isFinite(PHASE_PRIORITY[c.phase]));
413
+ eligible.sort((a, b) => {
414
+ const p = PHASE_PRIORITY[a.phase] - PHASE_PRIORITY[b.phase];
415
+ if (p !== 0) return p;
416
+ return a.lastUsedMs - b.lastUsedMs;
417
+ });
418
+ const toEvict = [];
419
+ let remaining = totalBytes;
420
+ for (const c of eligible) {
421
+ if (remaining <= maxBytes) break;
422
+ toEvict.push(c.id);
423
+ remaining -= c.bytes;
424
+ }
425
+ return toEvict;
426
+ }
427
+
428
+ // ../kernel/src/anchors.ts
429
+ function portAnchor(widget, slot) {
430
+ const f = (slot.index + 1) / (slot.count + 1);
431
+ switch (slot.side) {
432
+ case "n":
433
+ return { x: widget.x + widget.width * f, y: widget.y };
434
+ case "s":
435
+ return { x: widget.x + widget.width * f, y: widget.y + widget.height };
436
+ case "w":
437
+ return { x: widget.x, y: widget.y + widget.height * f };
438
+ case "e":
439
+ return { x: widget.x + widget.width, y: widget.y + widget.height * f };
440
+ }
441
+ }
442
+ function sideDirection(side) {
443
+ switch (side) {
444
+ case "n":
445
+ return { x: 0, y: -1 };
446
+ case "s":
447
+ return { x: 0, y: 1 };
448
+ case "w":
449
+ return { x: -1, y: 0 };
450
+ case "e":
451
+ return { x: 1, y: 0 };
452
+ }
453
+ }
454
+
455
+ // ../kernel/src/bezier.ts
456
+ function wireCubic(from, fromSide, to, toSide, stubScale = 0.4, minStub = 24) {
457
+ const dist = Math.hypot(to.x - from.x, to.y - from.y);
458
+ const stub = Math.max(minStub, dist * stubScale);
459
+ const df = sideDirection(fromSide);
460
+ const dt = sideDirection(toSide);
461
+ return {
462
+ x0: from.x,
463
+ y0: from.y,
464
+ x1: from.x + df.x * stub,
465
+ y1: from.y + df.y * stub,
466
+ x2: to.x + dt.x * stub,
467
+ y2: to.y + dt.y * stub,
468
+ x3: to.x,
469
+ y3: to.y
470
+ };
471
+ }
472
+ function cubicPoint(c, t) {
473
+ const u = 1 - t;
474
+ const b0 = u * u * u;
475
+ const b1 = 3 * u * u * t;
476
+ const b2 = 3 * u * t * t;
477
+ const b3 = t * t * t;
478
+ return {
479
+ x: b0 * c.x0 + b1 * c.x1 + b2 * c.x2 + b3 * c.x3,
480
+ y: b0 * c.y0 + b1 * c.y1 + b2 * c.y2 + b3 * c.y3
481
+ };
482
+ }
483
+ function cubicAABB(c) {
484
+ return {
485
+ minX: Math.min(c.x0, c.x1, c.x2, c.x3),
486
+ minY: Math.min(c.y0, c.y1, c.y2, c.y3),
487
+ maxX: Math.max(c.x0, c.x1, c.x2, c.x3),
488
+ maxY: Math.max(c.y0, c.y1, c.y2, c.y3)
489
+ };
490
+ }
491
+ function distanceToSegment(px, py, ax, ay, bx, by) {
492
+ const dx = bx - ax;
493
+ const dy = by - ay;
494
+ const lenSq = dx * dx + dy * dy;
495
+ let t = 0;
496
+ if (lenSq > 0) {
497
+ t = ((px - ax) * dx + (py - ay) * dy) / lenSq;
498
+ t = Math.max(0, Math.min(1, t));
499
+ }
500
+ const cx = ax + t * dx;
501
+ const cy = ay + t * dy;
502
+ return Math.hypot(px - cx, py - cy);
503
+ }
504
+ function distanceToCubic(px, py, c, samples = 32) {
505
+ let best = Number.POSITIVE_INFINITY;
506
+ let prev = cubicPoint(c, 0);
507
+ for (let i = 1; i <= samples; i++) {
508
+ const cur = cubicPoint(c, i / samples);
509
+ const d = distanceToSegment(px, py, prev.x, prev.y, cur.x, cur.y);
510
+ if (d < best) best = d;
511
+ prev = cur;
512
+ }
513
+ return best;
514
+ }
515
+
516
+ // ../kernel/src/index.ts
517
+ var KERNEL_VERSION = "0.0.0";
518
+
519
+ export {
520
+ rectToAABB,
521
+ aabbToRect,
522
+ intersectsAABB,
523
+ pointInAABB,
524
+ clamp,
525
+ screenToWorld,
526
+ worldToScreen,
527
+ zoomAtPoint,
528
+ planeCssTransform,
529
+ worldToIsland,
530
+ islandToWorld,
531
+ compositeCameraFrustum,
532
+ worldRectToComposite,
533
+ computeSnapGuides,
534
+ SpatialIndex,
535
+ ZOOM_BANDS,
536
+ selectBand,
537
+ isOutOfBand,
538
+ fboPixelSize,
539
+ computeIslandPhase,
540
+ selectEvictions,
541
+ portAnchor,
542
+ sideDirection,
543
+ wireCubic,
544
+ cubicPoint,
545
+ cubicAABB,
546
+ distanceToSegment,
547
+ distanceToCubic,
548
+ KERNEL_VERSION
549
+ };
550
+ //# sourceMappingURL=chunk-BCJ47SX7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../kernel/src/shapes.ts","../../kernel/src/coords.ts","../../kernel/src/snap.ts","../../kernel/src/spatial-index.ts","../../kernel/src/zoom-bands.ts","../../kernel/src/eviction.ts","../../kernel/src/anchors.ts","../../kernel/src/bezier.ts","../../kernel/src/index.ts"],"sourcesContent":["/** Plain geometric structs shared across the kernel. Ported from v1 `ecs/math.ts`. */\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport function rectToAABB(r: Rect): AABB {\n return { minX: r.x, minY: r.y, maxX: r.x + r.width, maxY: r.y + r.height };\n}\n\nexport function aabbToRect(a: AABB): Rect {\n return { x: a.minX, y: a.minY, width: a.maxX - a.minX, height: a.maxY - a.minY };\n}\n\nexport function intersectsAABB(a: AABB, b: AABB): boolean {\n return a.maxX >= b.minX && a.minX <= b.maxX && a.maxY >= b.minY && a.minY <= b.maxY;\n}\n\nexport function pointInAABB(px: number, py: number, a: AABB): boolean {\n return px >= a.minX && px <= a.maxX && py >= a.minY && py <= a.maxY;\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","/**\n * THE coordinate seam (Law 13): every conversion between screen, world, and\n * island (widget-local GL) space lives here — including the ONE Y-flip.\n * v1 duplicated this math in three places; nothing outside this module may\n * re-derive it.\n *\n * Conventions:\n * - screen: CSS px, canvas-container-relative, Y-down. DPR never enters world\n * math (it exists only in GL uniforms / FBO sizing — see zoom-bands).\n * - world: world units, Y-down. `Camera.{x,y}` is the WORLD point at the\n * viewport's top-left; `zoom` is screen px per world unit.\n * - island: widget-local GL space — CENTER origin, Y-UP, world-unit scale.\n * (v1 VirtualWidget convention; the only Y-flip in the codebase.)\n */\nimport type { Rect, Vec2 } from \"./shapes\";\n\nexport interface CameraState {\n x: number;\n y: number;\n zoom: number;\n}\n\nexport function screenToWorld(screenX: number, screenY: number, camera: CameraState): Vec2 {\n return {\n x: screenX / camera.zoom + camera.x,\n y: screenY / camera.zoom + camera.y,\n };\n}\n\nexport function worldToScreen(worldX: number, worldY: number, camera: CameraState): Vec2 {\n return {\n x: (worldX - camera.x) * camera.zoom,\n y: (worldY - camera.y) * camera.zoom,\n };\n}\n\n/**\n * Zoom about a fixed screen point (v1 `zoomAtPoint`): the world point under\n * `(screenX, screenY)` stays under it after the zoom change.\n * Returns the new camera (does not mutate). Clamping is the caller's policy.\n */\nexport function zoomAtPoint(\n camera: CameraState,\n screenX: number,\n screenY: number,\n newZoom: number,\n): CameraState {\n const anchor = screenToWorld(screenX, screenY, camera);\n return {\n x: anchor.x - screenX / newZoom,\n y: anchor.y - screenY / newZoom,\n zoom: newZoom,\n };\n}\n\n/**\n * Camera → the ONE per-plane CSS transform (design-002 §5 `planeTransform`).\n * Children are laid out in WORLD units inside the plane (left/top = world x/y),\n * the plane carries `transform: translate(tx px, ty px) scale(scale)` with\n * `transform-origin: 0 0` — so a child at world point p lands at\n * `p·zoom + t = (p − camera)·zoom`, i.e. exactly `worldToScreen(p)`.\n */\nexport function planeCssTransform(camera: CameraState): { tx: number; ty: number; scale: number } {\n return {\n tx: -camera.x * camera.zoom,\n ty: -camera.y * camera.zoom,\n scale: camera.zoom,\n };\n}\n\n/** World → island (center-origin, Y-up). THE Y-flip, direction one. */\nexport function worldToIsland(worldX: number, worldY: number, widget: Rect): Vec2 {\n return {\n x: worldX - (widget.x + widget.width / 2),\n y: -(worldY - (widget.y + widget.height / 2)),\n };\n}\n\n/** Island → world. THE Y-flip, direction two. */\nexport function islandToWorld(islandX: number, islandY: number, widget: Rect): Vec2 {\n return {\n x: widget.x + widget.width / 2 + islandX,\n y: widget.y + widget.height / 2 - islandY,\n };\n}\n\n// --- P2 composite scene (design-004 §1/§3) -------------------------------\n// The GL-views plane composites island quads in a Three scene whose axes are\n// world-unit X-right / Y-UP (Three convention). Same flip as island space,\n// applied at WORLD scale — these two helpers are the only place it exists.\n\n/**\n * Camera → the P2 composite ortho frustum + camera position (world units,\n * Y-up scene). `left/top` pin the viewport's top-left to `Camera.{x,y}`\n * exactly like `planeCssTransform` does for the DOM planes: the frustum spans\n * `viewport / zoom` world units and the camera sits at the world origin\n * offset, so a quad at `worldRectToComposite(rect)` lands on the same screen\n * pixels as a DOM host at `rect` under the plane transform.\n */\nexport function compositeCameraFrustum(\n camera: CameraState,\n viewportW: number,\n viewportH: number,\n): { left: number; right: number; top: number; bottom: number; x: number; y: number } {\n return {\n left: 0,\n right: viewportW / camera.zoom,\n top: 0,\n bottom: -(viewportH / camera.zoom),\n x: camera.x,\n y: -camera.y,\n };\n}\n\n/** World rect → composite-quad center + scale in the Y-up P2 scene. */\nexport function worldRectToComposite(rect: Rect): { x: number; y: number; sx: number; sy: number } {\n return {\n x: rect.x + rect.width / 2,\n y: -(rect.y + rect.height / 2),\n sx: rect.width,\n sy: rect.height,\n };\n}\n","/**\n * Snap guide computation (Figma-style), ported verbatim from v1\n * `ecs/spatial/snap.ts` (audited CLEAN-PORT):\n * Phase 1 — edge/center alignment (7 X + 7 Y candidate pairs per reference,\n * per-axis nearest-wins, ties within 0.01 accumulate guides)\n * Phase 2 — equal spacing (between-two-neighbors midpoint; extend-a-pattern),\n * same-perpendicular-band filter\n * Merge — alignment takes priority per axis; equal spacing fills the other;\n * indicators recomputed post-snap at threshold × 0.5.\n * Pure function over plain bounds. Candidate GATHERING (spatial index, tags,\n * Active scoping) is the caller's job — design-003 §5.2/§6.\n */\n\nexport interface SnapGuide {\n axis: \"x\" | \"y\";\n /** World-space coordinate of the alignment line */\n position: number;\n type: \"edge\" | \"center\";\n}\n\nexport interface EqualSpacingIndicator {\n axis: \"x\" | \"y\";\n /** The equal gap value (world units) */\n gap: number;\n /** Pairs of (from, to) marking each equal gap segment */\n segments: { from: number; to: number }[];\n /** Position on the perpendicular axis (for rendering) */\n perpPosition: number;\n}\n\nexport interface SnapResult {\n /** Snap-corrected delta (world units). Apply to entity position. */\n snapDx: number;\n snapDy: number;\n guides: SnapGuide[];\n spacings: EqualSpacingIndicator[];\n}\n\nexport interface EntityBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport function computeSnapGuides(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n): SnapResult {\n const guides: SnapGuide[] = [];\n const spacings: EqualSpacingIndicator[] = [];\n let snapDx = 0;\n let snapDy = 0;\n\n const dLeft = dragged.x;\n const dRight = dragged.x + dragged.width;\n const dCenterX = dragged.x + dragged.width / 2;\n const dTop = dragged.y;\n const dBottom = dragged.y + dragged.height;\n const dCenterY = dragged.y + dragged.height / 2;\n\n let bestSnapX = Number.POSITIVE_INFINITY;\n let bestSnapY = Number.POSITIVE_INFINITY;\n let bestDx = 0;\n let bestDy = 0;\n const xGuides: SnapGuide[] = [];\n const yGuides: SnapGuide[] = [];\n\n // --- Phase 1: edge/center alignment ---\n for (const ref of references) {\n const rLeft = ref.x;\n const rRight = ref.x + ref.width;\n const rCenterX = ref.x + ref.width / 2;\n const rTop = ref.y;\n const rBottom = ref.y + ref.height;\n const rCenterY = ref.y + ref.height / 2;\n\n const xPairs: [number, number, \"edge\" | \"center\"][] = [\n [dLeft, rLeft, \"edge\"],\n [dLeft, rRight, \"edge\"],\n [dRight, rLeft, \"edge\"],\n [dRight, rRight, \"edge\"],\n [dCenterX, rCenterX, \"center\"],\n [dLeft, rCenterX, \"edge\"],\n [dRight, rCenterX, \"edge\"],\n ];\n for (const [dVal, rVal, type] of xPairs) {\n const dist = Math.abs(dVal - rVal);\n if (dist <= threshold) {\n const dx = rVal - dVal;\n if (dist < bestSnapX) {\n bestSnapX = dist;\n bestDx = dx;\n xGuides.length = 0;\n }\n if (dist <= bestSnapX + 0.01) {\n xGuides.push({ axis: \"x\", position: rVal, type });\n }\n }\n }\n\n const yPairs: [number, number, \"edge\" | \"center\"][] = [\n [dTop, rTop, \"edge\"],\n [dTop, rBottom, \"edge\"],\n [dBottom, rTop, \"edge\"],\n [dBottom, rBottom, \"edge\"],\n [dCenterY, rCenterY, \"center\"],\n [dTop, rCenterY, \"edge\"],\n [dBottom, rCenterY, \"edge\"],\n ];\n for (const [dVal, rVal, type] of yPairs) {\n const dist = Math.abs(dVal - rVal);\n if (dist <= threshold) {\n const dy = rVal - dVal;\n if (dist < bestSnapY) {\n bestSnapY = dist;\n bestDy = dy;\n yGuides.length = 0;\n }\n if (dist <= bestSnapY + 0.01) {\n yGuides.push({ axis: \"y\", position: rVal, type });\n }\n }\n }\n }\n\n // --- Phase 2: equal spacing ---\n const eqResult = computeEqualSpacing(dragged, references, threshold);\n\n // Merge: alignment snap takes priority; equal spacing fills the other axis.\n if (bestSnapX <= threshold) {\n snapDx = bestDx;\n } else if (eqResult.snapDx !== undefined) {\n snapDx = eqResult.snapDx;\n }\n if (bestSnapY <= threshold) {\n snapDy = bestDy;\n } else if (eqResult.snapDy !== undefined) {\n snapDy = eqResult.snapDy;\n }\n\n if (bestSnapX <= threshold) {\n const seen = new Set<number>();\n for (const g of xGuides) {\n if (!seen.has(g.position)) {\n seen.add(g.position);\n guides.push(g);\n }\n }\n }\n if (bestSnapY <= threshold) {\n const seen = new Set<number>();\n for (const g of yGuides) {\n if (!seen.has(g.position)) {\n seen.add(g.position);\n guides.push(g);\n }\n }\n }\n\n // Indicators recomputed against the SNAPPED bounds at half threshold.\n const snappedBounds: EntityBounds = {\n x: dragged.x + snapDx,\n y: dragged.y + snapDy,\n width: dragged.width,\n height: dragged.height,\n };\n const eqFinal = computeEqualSpacing(snappedBounds, references, threshold * 0.5);\n spacings.push(...eqFinal.indicators);\n\n return { snapDx, snapDy, guides, spacings };\n}\n\ninterface EqualSpacingResult {\n snapDx: number | undefined;\n snapDy: number | undefined;\n indicators: EqualSpacingIndicator[];\n}\n\nfunction computeEqualSpacing(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n): EqualSpacingResult {\n const indicators: EqualSpacingIndicator[] = [];\n let snapDx: number | undefined;\n let snapDy: number | undefined;\n\n const xResult = checkAxisSpacing(dragged, references, threshold, \"x\");\n if (xResult) {\n snapDx = xResult.snap;\n indicators.push(...xResult.indicators);\n }\n const yResult = checkAxisSpacing(dragged, references, threshold, \"y\");\n if (yResult) {\n snapDy = yResult.snap;\n indicators.push(...yResult.indicators);\n }\n return { snapDx, snapDy, indicators };\n}\n\nfunction checkAxisSpacing(\n dragged: EntityBounds,\n references: EntityBounds[],\n threshold: number,\n axis: \"x\" | \"y\",\n): { snap: number; indicators: EqualSpacingIndicator[] } | null {\n const isX = axis === \"x\";\n const pos = (b: EntityBounds) => (isX ? b.x : b.y);\n const size = (b: EntityBounds) => (isX ? b.width : b.height);\n const perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n const perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n const end = (b: EntityBounds) => pos(b) + size(b);\n\n // Same-perpendicular-band filter.\n const neighbors = references.filter(\n (ref) =>\n perpPos(ref) < perpPos(dragged) + perpSize(dragged) &&\n perpPos(ref) + perpSize(ref) > perpPos(dragged),\n );\n if (neighbors.length < 1) return null;\n\n const sorted = [...neighbors].sort((a, b) => pos(a) - pos(b));\n\n // Existing gaps between consecutive references.\n const refGaps: { from: EntityBounds; to: EntityBounds; gap: number }[] = [];\n for (let i = 0; i < sorted.length - 1; i++) {\n const a = sorted[i];\n const b = sorted[i + 1];\n if (a === undefined || b === undefined) continue;\n const gap = pos(b) - end(a);\n if (gap > 0.1) refGaps.push({ from: a, to: b, gap });\n }\n\n let bestSnap: number | null = null;\n let bestIndicators: EqualSpacingIndicator[] = [];\n let bestDiff = Number.POSITIVE_INFINITY;\n\n // Case 1: between two neighbors — equalize left/right gaps.\n let leftN: EntityBounds | null = null;\n let rightN: EntityBounds | null = null;\n for (const ref of sorted) {\n if (end(ref) <= pos(dragged) + threshold) {\n if (!leftN || end(ref) > end(leftN)) leftN = ref;\n }\n if (pos(ref) >= end(dragged) - threshold) {\n if (!rightN || pos(ref) < pos(rightN)) rightN = ref;\n }\n }\n if (leftN && rightN) {\n const lGap = pos(dragged) - end(leftN);\n const rGap = pos(rightN) - end(dragged);\n const diff = Math.abs(lGap - rGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = (end(leftN) + pos(rightN) - size(dragged)) / 2;\n const snap = idealPos - pos(dragged);\n const equalGap = (pos(rightN) - end(leftN) - size(dragged)) / 2;\n if (equalGap > 0.1) {\n const perpY = computePerpCenter(dragged, [leftN, rightN], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: equalGap,\n segments: [\n { from: end(leftN), to: idealPos },\n { from: idealPos + size(dragged), to: pos(rightN) },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n }\n\n // Case 2: extend an existing gap pattern (append right / prepend left).\n for (const refGap of refGaps) {\n const patternGap = refGap.gap;\n\n if (rightN === null || pos(refGap.to) >= end(dragged) - threshold * 2) {\n const chainEnd = refGap.to;\n const dragGap = pos(dragged) - end(chainEnd);\n const diff = Math.abs(dragGap - patternGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = end(chainEnd) + patternGap;\n const snap = idealPos - pos(dragged);\n const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: patternGap,\n segments: [\n { from: end(refGap.from), to: pos(refGap.to) },\n { from: end(chainEnd), to: idealPos },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n\n if (leftN === null || end(refGap.from) <= pos(dragged) + threshold * 2) {\n const chainStart = refGap.from;\n const dragGap = pos(chainStart) - end(dragged);\n const diff = Math.abs(dragGap - patternGap);\n if (diff <= threshold && diff < bestDiff) {\n const idealPos = pos(chainStart) - patternGap - size(dragged);\n const snap = idealPos - pos(dragged);\n const perpY = computePerpCenter(dragged, [refGap.from, refGap.to], isX);\n bestSnap = snap;\n bestDiff = diff;\n bestIndicators = [\n {\n axis,\n gap: patternGap,\n segments: [\n { from: idealPos + size(dragged), to: pos(chainStart) },\n { from: end(refGap.from), to: pos(refGap.to) },\n ],\n perpPosition: perpY,\n },\n ];\n }\n }\n }\n\n if (bestSnap !== null) return { snap: bestSnap, indicators: bestIndicators };\n return null;\n}\n\nfunction computePerpCenter(dragged: EntityBounds, refs: EntityBounds[], isX: boolean): number {\n const perpPos = (b: EntityBounds) => (isX ? b.y : b.x);\n const perpSize = (b: EntityBounds) => (isX ? b.height : b.width);\n const allBounds = [dragged, ...refs];\n const maxStart = Math.max(...allBounds.map(perpPos));\n const minEnd = Math.min(...allBounds.map((b) => perpPos(b) + perpSize(b)));\n if (minEnd < maxStart) {\n return perpPos(dragged) + perpSize(dragged) / 2;\n }\n return maxStart + (minEnd - maxStart) / 2;\n}\n","/**\n * Spatial index backed by an R-tree (rbush) — ported from v1 (audited CLEAN-PORT).\n * World-space AABBs for culling, hit-testing, and snap-candidate gathering\n * (Law 15: the ONLY hit path). The id↔entry map gives O(log n) removal by\n * passing rbush the exact stored reference (v1 \"Fix #8\").\n *\n * `rbush` is the kernel's single, named dependency exception: a zero-dep pure\n * data structure (see .dependency-cruiser.cjs).\n */\nimport RBushImport from \"rbush\";\nimport type { AABB } from \"./shapes\";\n\n// CJS/ESM interop — rbush exports differently depending on context (kept from v1).\ntype RBushModule = typeof RBushImport & { default?: typeof RBushImport };\nconst rbushModule = RBushImport as RBushModule;\nconst RBush = (\n typeof rbushModule.default === \"function\" ? rbushModule.default : RBushImport\n) as typeof RBushImport;\n\nexport interface SpatialEntry<Id> extends AABB {\n id: Id;\n}\n\nexport class SpatialIndex<Id> {\n private tree = new RBush<SpatialEntry<Id>>();\n private entries = new Map<Id, SpatialEntry<Id>>();\n\n upsert(id: Id, bounds: AABB): void {\n const existing = this.entries.get(id);\n if (existing) this.tree.remove(existing);\n const entry: SpatialEntry<Id> = { ...bounds, id };\n this.entries.set(id, entry);\n this.tree.insert(entry);\n }\n\n remove(id: Id): void {\n const existing = this.entries.get(id);\n if (existing) {\n this.tree.remove(existing);\n this.entries.delete(id);\n }\n }\n\n /** All entries intersecting the given AABB. */\n search(bounds: AABB): SpatialEntry<Id>[] {\n return this.tree.search(bounds);\n }\n\n /** Entries within `tolerance` of a point (z-priority is the caller's job). */\n searchPoint(x: number, y: number, tolerance = 0): SpatialEntry<Id>[] {\n return this.tree.search({\n minX: x - tolerance,\n minY: y - tolerance,\n maxX: x + tolerance,\n maxY: y + tolerance,\n });\n }\n\n clear(): void {\n this.tree.clear();\n this.entries.clear();\n }\n\n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * Hysteresis-banded zoom-resolution policy — ported from v1 `ZoomBands.ts`\n * (RFC-002). An island FBO is allocated at `widget bounds × dpr × band(zoom)`;\n * while zoom stays within `[band × 0.5, band × 2]` no repaint is needed.\n * Bands are powers of 2 (each covers a 4× display range).\n */\nexport const ZOOM_BANDS = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16] as const;\nconst MIN_BAND = 0.0625;\nconst MAX_BAND = 16;\n\n/** Smallest band ≥ zoom (clamped to the ladder). */\nexport function selectBand(zoom: number): number {\n if (zoom <= MIN_BAND) return MIN_BAND;\n if (zoom >= MAX_BAND) return MAX_BAND;\n for (const b of ZOOM_BANDS) {\n if (zoom <= b) return b;\n }\n return MAX_BAND;\n}\n\n/**\n * True when zoom left the `[band × 0.5, band × 2]` window of the band the\n * island was painted at. `paintedBand ≤ 0` = never painted (handled elsewhere).\n */\nexport function isOutOfBand(currentZoom: number, paintedBand: number): boolean {\n if (paintedBand <= 0) return false;\n const ratio = currentZoom / paintedBand;\n return ratio > 2 || ratio < 0.5;\n}\n\n/** FBO pixel size for a widget at a band (v1: `bounds × dpr × band`, min 1px). */\nexport function fboPixelSize(\n worldWidth: number,\n worldHeight: number,\n dpr: number,\n band: number,\n): { width: number; height: number } {\n return {\n width: Math.max(1, Math.round(worldWidth * dpr * band)),\n height: Math.max(1, Math.round(worldHeight * dpr * band)),\n };\n}\n","/**\n * FBO-pool eviction policy — ported from v1 `eviction.ts` (pure part of the\n * pool). Priority: Cold(0) < Warm(1) < Dormant(2); LRU within a phase;\n * Hot/Waking are never evicted even under an impossible budget.\n */\nexport type IslandPhase = \"Hot\" | \"Warm\" | \"Waking\" | \"Cold\" | \"Dormant\";\n\nexport interface EvictionCandidate<Id> {\n id: Id;\n phase: IslandPhase;\n bytes: number;\n lastUsedMs: number;\n}\n\nconst PHASE_PRIORITY: Record<IslandPhase, number> = {\n Cold: 0,\n Warm: 1,\n Dormant: 2,\n Waking: Number.POSITIVE_INFINITY,\n Hot: Number.POSITIVE_INFINITY,\n};\n\n/**\n * The island phase truth table (design-004 §3; v1 `computePhase` verbatim —\n * RFC-002 pinned it with tests). `active` is the nested-canvas membership\n * signal (always true until M8); `hasFbo` splits Warm (retained texture,\n * composite-ready) from Waking (must paint before compositing) — after an\n * eviction a re-entering island comes back as Waking, after a plain cull\n * round-trip it comes back Warm from the retained texture.\n */\nexport function computeIslandPhase(\n active: boolean,\n visible: boolean,\n animating: boolean,\n hasFbo: boolean,\n): IslandPhase {\n if (!active) return \"Dormant\";\n if (visible) {\n if (animating) return \"Hot\";\n return hasFbo ? \"Warm\" : \"Waking\";\n }\n // Culled OR not yet culled-classified: treat as Cold — never paint a widget\n // the engine hasn't placed in the viewport yet (v1 rule, kept).\n return \"Cold\";\n}\n\n/** Ordered ids to release so total bytes ≤ budget. Pure. */\nexport function selectEvictions<Id>(\n candidates: EvictionCandidate<Id>[],\n totalBytes: number,\n maxBytes: number,\n): Id[] {\n if (totalBytes <= maxBytes) return [];\n\n const eligible = candidates.filter((c) => Number.isFinite(PHASE_PRIORITY[c.phase]));\n eligible.sort((a, b) => {\n const p = PHASE_PRIORITY[a.phase] - PHASE_PRIORITY[b.phase];\n if (p !== 0) return p;\n return a.lastUsedMs - b.lastUsedMs;\n });\n\n const toEvict: Id[] = [];\n let remaining = totalBytes;\n for (const c of eligible) {\n if (remaining <= maxBytes) break;\n toEvict.push(c.id);\n remaining -= c.bytes;\n }\n return toEvict;\n}\n","/**\n * Port-anchor math (design-001 §5.3): wire geometry NEVER reads port entities —\n * anchors are pure functions over the widget rect + the port declaration, so\n * culled endpoints work by construction.\n */\nimport type { Rect, Vec2 } from \"./shapes\";\n\nexport type PortSide = \"n\" | \"e\" | \"s\" | \"w\";\n\nexport interface PortSlot {\n side: PortSide;\n /** 0-based position among the ports sharing this side. */\n index: number;\n /** Total ports on this side. */\n count: number;\n}\n\n/** World-space anchor point: ports distribute evenly along their side. */\nexport function portAnchor(widget: Rect, slot: PortSlot): Vec2 {\n const f = (slot.index + 1) / (slot.count + 1);\n switch (slot.side) {\n case \"n\":\n return { x: widget.x + widget.width * f, y: widget.y };\n case \"s\":\n return { x: widget.x + widget.width * f, y: widget.y + widget.height };\n case \"w\":\n return { x: widget.x, y: widget.y + widget.height * f };\n case \"e\":\n return { x: widget.x + widget.width, y: widget.y + widget.height * f };\n }\n}\n\n/** Outward unit direction of a side (wire tangent stubs, Y-down world). */\nexport function sideDirection(side: PortSide): Vec2 {\n switch (side) {\n case \"n\":\n return { x: 0, y: -1 };\n case \"s\":\n return { x: 0, y: 1 };\n case \"w\":\n return { x: -1, y: 0 };\n case \"e\":\n return { x: 1, y: 0 };\n }\n}\n","/**\n * Cubic-bezier wire geometry: construction from port anchors, conservative\n * AABB (for the spatial index), and sampled distance (for picking — wires rank\n * below widgets, design-003 §3).\n */\nimport { sideDirection, type PortSide } from \"./anchors\";\nimport type { AABB, Vec2 } from \"./shapes\";\n\nexport interface Cubic {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n x3: number;\n y3: number;\n}\n\n/**\n * Wire curve between two anchors: tangent stubs leave each port along its\n * side's outward direction, scaled with distance (min stub keeps short wires\n * readable).\n */\nexport function wireCubic(\n from: Vec2,\n fromSide: PortSide,\n to: Vec2,\n toSide: PortSide,\n stubScale = 0.4,\n minStub = 24,\n): Cubic {\n const dist = Math.hypot(to.x - from.x, to.y - from.y);\n const stub = Math.max(minStub, dist * stubScale);\n const df = sideDirection(fromSide);\n const dt = sideDirection(toSide);\n return {\n x0: from.x,\n y0: from.y,\n x1: from.x + df.x * stub,\n y1: from.y + df.y * stub,\n x2: to.x + dt.x * stub,\n y2: to.y + dt.y * stub,\n x3: to.x,\n y3: to.y,\n };\n}\n\n/** Point on the curve at t ∈ [0, 1] (Bernstein form). */\nexport function cubicPoint(c: Cubic, t: number): Vec2 {\n const u = 1 - t;\n const b0 = u * u * u;\n const b1 = 3 * u * u * t;\n const b2 = 3 * u * t * t;\n const b3 = t * t * t;\n return {\n x: b0 * c.x0 + b1 * c.x1 + b2 * c.x2 + b3 * c.x3,\n y: b0 * c.y0 + b1 * c.y1 + b2 * c.y2 + b3 * c.y3,\n };\n}\n\n/**\n * Conservative bounds: the control-point hull contains the curve (convex-hull\n * property). Cheap and index-friendly; exact extrema are unnecessary for\n * culling/picking prefilters.\n */\nexport function cubicAABB(c: Cubic): AABB {\n return {\n minX: Math.min(c.x0, c.x1, c.x2, c.x3),\n minY: Math.min(c.y0, c.y1, c.y2, c.y3),\n maxX: Math.max(c.x0, c.x1, c.x2, c.x3),\n maxY: Math.max(c.y0, c.y1, c.y2, c.y3),\n };\n}\n\n/** Distance from a point to a line segment. */\nexport function distanceToSegment(\n px: number,\n py: number,\n ax: number,\n ay: number,\n bx: number,\n by: number,\n): number {\n const dx = bx - ax;\n const dy = by - ay;\n const lenSq = dx * dx + dy * dy;\n let t = 0;\n if (lenSq > 0) {\n t = ((px - ax) * dx + (py - ay) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n }\n const cx = ax + t * dx;\n const cy = ay + t * dy;\n return Math.hypot(px - cx, py - cy);\n}\n\n/**\n * Min distance from a point to the curve via polyline sampling. 32 samples is\n * ample for hit thresholds of a few px; error shrinks with curve flatness.\n */\nexport function distanceToCubic(px: number, py: number, c: Cubic, samples = 32): number {\n let best = Number.POSITIVE_INFINITY;\n let prev = cubicPoint(c, 0);\n for (let i = 1; i <= samples; i++) {\n const cur = cubicPoint(c, i / samples);\n const d = distanceToSegment(px, py, prev.x, prev.y, cur.x, cur.y);\n if (d < best) best = d;\n prev = cur;\n }\n return best;\n}\n","/**\n * @ice/kernel — pure math. Plain structs in, plain structs out.\n * Import wall: nothing but `rbush` (named exception — zero-dep R-tree).\n */\nexport const KERNEL_VERSION = \"0.0.0\";\n\nexport * from \"./shapes\";\nexport * from \"./coords\";\nexport * from \"./snap\";\nexport * from \"./spatial-index\";\nexport * from \"./zoom-bands\";\nexport * from \"./eviction\";\nexport * from \"./anchors\";\nexport * from \"./bezier\";\n"],"mappings":"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","names":[]}