@pascal-app/core 0.9.1 → 0.9.2

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 (321) hide show
  1. package/dist/events/bus.d.ts +30 -2
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/hooks/scene-registry/item-clip-registry.d.ts +18 -0
  4. package/dist/hooks/scene-registry/item-clip-registry.d.ts.map +1 -0
  5. package/dist/hooks/scene-registry/item-clip-registry.js +10 -0
  6. package/dist/hooks/scene-registry/scene-registry.d.ts +8 -1
  7. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  8. package/dist/hooks/scene-registry/scene-registry.js +27 -1
  9. package/dist/hooks/scene-registry/scene-registry.test.d.ts +2 -0
  10. package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +1 -0
  11. package/dist/hooks/scene-registry/scene-registry.test.js +26 -0
  12. package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +93 -0
  13. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +69 -12
  14. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  15. package/dist/hooks/spatial-grid/spatial-grid-manager.js +476 -195
  16. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  17. package/dist/hooks/spatial-grid/spatial-grid-sync.js +19 -1
  18. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +2 -0
  19. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +1 -0
  20. package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +363 -0
  21. package/dist/index.d.ts +16 -6
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +15 -5
  24. package/dist/lib/level-name.d.ts +4 -0
  25. package/dist/lib/level-name.d.ts.map +1 -0
  26. package/dist/lib/level-name.js +10 -0
  27. package/dist/lib/measurement-geometry.d.ts +19 -0
  28. package/dist/lib/measurement-geometry.d.ts.map +1 -0
  29. package/dist/lib/measurement-geometry.js +232 -0
  30. package/dist/lib/measurement-geometry.test.d.ts +2 -0
  31. package/dist/lib/measurement-geometry.test.d.ts.map +1 -0
  32. package/dist/lib/measurement-geometry.test.js +102 -0
  33. package/dist/lib/polygon-geometry.d.ts +0 -1
  34. package/dist/lib/polygon-geometry.d.ts.map +1 -1
  35. package/dist/lib/polygon-geometry.js +0 -18
  36. package/dist/lib/selection-proxy.d.ts +4 -0
  37. package/dist/lib/selection-proxy.d.ts.map +1 -0
  38. package/dist/lib/selection-proxy.js +12 -0
  39. package/dist/lib/slab-polygon.d.ts +31 -2
  40. package/dist/lib/slab-polygon.d.ts.map +1 -1
  41. package/dist/lib/slab-polygon.js +525 -31
  42. package/dist/lib/slab-polygon.test.d.ts +2 -0
  43. package/dist/lib/slab-polygon.test.d.ts.map +1 -0
  44. package/dist/lib/slab-polygon.test.js +635 -0
  45. package/dist/lib/slots.d.ts +14 -0
  46. package/dist/lib/slots.d.ts.map +1 -0
  47. package/dist/lib/slots.js +26 -0
  48. package/dist/lib/space-detection.d.ts +25 -2
  49. package/dist/lib/space-detection.d.ts.map +1 -1
  50. package/dist/lib/space-detection.js +414 -118
  51. package/dist/lib/space-detection.test.js +301 -2
  52. package/dist/lib/wall-distance.d.ts +60 -0
  53. package/dist/lib/wall-distance.d.ts.map +1 -0
  54. package/dist/lib/wall-distance.js +85 -0
  55. package/dist/lib/zone-quantities.d.ts +21 -0
  56. package/dist/lib/zone-quantities.d.ts.map +1 -0
  57. package/dist/lib/zone-quantities.js +183 -0
  58. package/dist/lib/zone-quantities.test.d.ts +2 -0
  59. package/dist/lib/zone-quantities.test.d.ts.map +1 -0
  60. package/dist/lib/zone-quantities.test.js +82 -0
  61. package/dist/material-library.d.ts +20 -1
  62. package/dist/material-library.d.ts.map +1 -1
  63. package/dist/material-library.js +2181 -441
  64. package/dist/registry/handles.d.ts +75 -2
  65. package/dist/registry/handles.d.ts.map +1 -1
  66. package/dist/registry/index.d.ts +3 -3
  67. package/dist/registry/index.d.ts.map +1 -1
  68. package/dist/registry/index.js +1 -1
  69. package/dist/registry/registry.d.ts +46 -3
  70. package/dist/registry/registry.d.ts.map +1 -1
  71. package/dist/registry/registry.js +82 -1
  72. package/dist/registry/registry.test.js +14 -1
  73. package/dist/registry/subtree.d.ts.map +1 -1
  74. package/dist/registry/subtree.js +4 -0
  75. package/dist/registry/subtree.test.js +30 -0
  76. package/dist/registry/types.d.ts +717 -38
  77. package/dist/registry/types.d.ts.map +1 -1
  78. package/dist/schema/index.d.ts +21 -5
  79. package/dist/schema/index.d.ts.map +1 -1
  80. package/dist/schema/index.js +17 -3
  81. package/dist/schema/material.d.ts +3 -2
  82. package/dist/schema/material.d.ts.map +1 -1
  83. package/dist/schema/material.js +7 -5
  84. package/dist/schema/material.test.d.ts +2 -0
  85. package/dist/schema/material.test.d.ts.map +1 -0
  86. package/dist/schema/material.test.js +43 -0
  87. package/dist/schema/nodes/box-vent.d.ts +2 -2
  88. package/dist/schema/nodes/cabinet.d.ts +534 -0
  89. package/dist/schema/nodes/cabinet.d.ts.map +1 -0
  90. package/dist/schema/nodes/cabinet.js +137 -0
  91. package/dist/schema/nodes/ceiling.d.ts +3 -2
  92. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  93. package/dist/schema/nodes/ceiling.js +4 -0
  94. package/dist/schema/nodes/chimney.d.ts +4 -4
  95. package/dist/schema/nodes/column.d.ts +3 -2
  96. package/dist/schema/nodes/column.d.ts.map +1 -1
  97. package/dist/schema/nodes/column.js +3 -0
  98. package/dist/schema/nodes/cupola.d.ts +2 -2
  99. package/dist/schema/nodes/door.d.ts +13 -5
  100. package/dist/schema/nodes/door.d.ts.map +1 -1
  101. package/dist/schema/nodes/door.js +12 -0
  102. package/dist/schema/nodes/dormer.d.ts +8 -8
  103. package/dist/schema/nodes/dormer.js +1 -1
  104. package/dist/schema/nodes/downspout.d.ts +2 -2
  105. package/dist/schema/nodes/duct-fitting.d.ts +91 -0
  106. package/dist/schema/nodes/duct-fitting.d.ts.map +1 -0
  107. package/dist/schema/nodes/duct-fitting.js +92 -0
  108. package/dist/schema/nodes/duct-segment.d.ts +61 -0
  109. package/dist/schema/nodes/duct-segment.d.ts.map +1 -0
  110. package/dist/schema/nodes/duct-segment.js +73 -0
  111. package/dist/schema/nodes/duct-terminal.d.ts +57 -0
  112. package/dist/schema/nodes/duct-terminal.d.ts.map +1 -0
  113. package/dist/schema/nodes/duct-terminal.js +51 -0
  114. package/dist/schema/nodes/elevator.d.ts +3 -2
  115. package/dist/schema/nodes/elevator.d.ts.map +1 -1
  116. package/dist/schema/nodes/elevator.js +3 -0
  117. package/dist/schema/nodes/eyebrow-vent.d.ts +2 -2
  118. package/dist/schema/nodes/fence.d.ts +18 -2
  119. package/dist/schema/nodes/fence.d.ts.map +1 -1
  120. package/dist/schema/nodes/fence.js +25 -2
  121. package/dist/schema/nodes/gutter.d.ts +2 -2
  122. package/dist/schema/nodes/hvac-equipment.d.ts +63 -0
  123. package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -0
  124. package/dist/schema/nodes/hvac-equipment.js +55 -0
  125. package/dist/schema/nodes/item.d.ts +8 -0
  126. package/dist/schema/nodes/item.d.ts.map +1 -1
  127. package/dist/schema/nodes/item.js +11 -0
  128. package/dist/schema/nodes/level.d.ts +1 -1
  129. package/dist/schema/nodes/level.d.ts.map +1 -1
  130. package/dist/schema/nodes/level.js +2 -0
  131. package/dist/schema/nodes/lineset.d.ts +42 -0
  132. package/dist/schema/nodes/lineset.d.ts.map +1 -0
  133. package/dist/schema/nodes/lineset.js +38 -0
  134. package/dist/schema/nodes/liquid-line.d.ts +34 -0
  135. package/dist/schema/nodes/liquid-line.d.ts.map +1 -0
  136. package/dist/schema/nodes/liquid-line.js +24 -0
  137. package/dist/schema/nodes/measurement.d.ts +306 -0
  138. package/dist/schema/nodes/measurement.d.ts.map +1 -0
  139. package/dist/schema/nodes/measurement.js +87 -0
  140. package/dist/schema/nodes/measurement.test.d.ts +2 -0
  141. package/dist/schema/nodes/measurement.test.d.ts.map +1 -0
  142. package/dist/schema/nodes/measurement.test.js +139 -0
  143. package/dist/schema/nodes/pipe-fitting.d.ts +56 -0
  144. package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -0
  145. package/dist/schema/nodes/pipe-fitting.js +45 -0
  146. package/dist/schema/nodes/pipe-segment.d.ts +48 -0
  147. package/dist/schema/nodes/pipe-segment.d.ts.map +1 -0
  148. package/dist/schema/nodes/pipe-segment.js +36 -0
  149. package/dist/schema/nodes/pipe-trap.d.ts +43 -0
  150. package/dist/schema/nodes/pipe-trap.d.ts.map +1 -0
  151. package/dist/schema/nodes/pipe-trap.js +36 -0
  152. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +2 -0
  153. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +1 -0
  154. package/dist/schema/nodes/ridge-vent-defaults.test.js +205 -0
  155. package/dist/schema/nodes/ridge-vent.d.ts +18 -3
  156. package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
  157. package/dist/schema/nodes/ridge-vent.js +221 -3
  158. package/dist/schema/nodes/roof-segment-shape.d.ts +90 -0
  159. package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -0
  160. package/dist/schema/nodes/roof-segment-shape.js +318 -0
  161. package/dist/schema/nodes/roof-segment-shape.test.d.ts +2 -0
  162. package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +1 -0
  163. package/dist/schema/nodes/roof-segment-shape.test.js +175 -0
  164. package/dist/schema/nodes/roof-segment-surface.test.d.ts +2 -0
  165. package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +1 -0
  166. package/dist/schema/nodes/roof-segment-surface.test.js +48 -0
  167. package/dist/schema/nodes/roof-segment-trim.test.d.ts +2 -0
  168. package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +1 -0
  169. package/dist/schema/nodes/roof-segment-trim.test.js +107 -0
  170. package/dist/schema/nodes/roof-segment-walls.d.ts +101 -0
  171. package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -0
  172. package/dist/schema/nodes/roof-segment-walls.js +330 -0
  173. package/dist/schema/nodes/roof-segment-walls.test.d.ts +2 -0
  174. package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +1 -0
  175. package/dist/schema/nodes/roof-segment-walls.test.js +92 -0
  176. package/dist/schema/nodes/roof-segment.d.ts +84 -8
  177. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  178. package/dist/schema/nodes/roof-segment.js +290 -5
  179. package/dist/schema/nodes/roof.d.ts +8 -8
  180. package/dist/schema/nodes/shelf.d.ts +3 -2
  181. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  182. package/dist/schema/nodes/shelf.js +6 -0
  183. package/dist/schema/nodes/skylight.d.ts +10 -10
  184. package/dist/schema/nodes/slab.d.ts +3 -2
  185. package/dist/schema/nodes/slab.d.ts.map +1 -1
  186. package/dist/schema/nodes/slab.js +4 -0
  187. package/dist/schema/nodes/solar-panel.d.ts +4 -4
  188. package/dist/schema/nodes/stair-segment.d.ts +4 -4
  189. package/dist/schema/nodes/stair.d.ts +13 -12
  190. package/dist/schema/nodes/stair.d.ts.map +1 -1
  191. package/dist/schema/nodes/stair.js +3 -0
  192. package/dist/schema/nodes/turbine-vent.d.ts +2 -2
  193. package/dist/schema/nodes/wall.d.ts +245 -6
  194. package/dist/schema/nodes/wall.d.ts.map +1 -1
  195. package/dist/schema/nodes/wall.js +257 -0
  196. package/dist/schema/nodes/wall.test.d.ts +2 -0
  197. package/dist/schema/nodes/wall.test.d.ts.map +1 -0
  198. package/dist/schema/nodes/wall.test.js +208 -0
  199. package/dist/schema/nodes/window.d.ts +11 -3
  200. package/dist/schema/nodes/window.d.ts.map +1 -1
  201. package/dist/schema/nodes/window.js +12 -0
  202. package/dist/schema/nodes/zone.d.ts +2 -0
  203. package/dist/schema/nodes/zone.d.ts.map +1 -1
  204. package/dist/schema/nodes/zone.js +6 -0
  205. package/dist/schema/scene-material.d.ts +41 -0
  206. package/dist/schema/scene-material.d.ts.map +1 -0
  207. package/dist/schema/scene-material.js +9 -0
  208. package/dist/schema/types.d.ts +1089 -94
  209. package/dist/schema/types.d.ts.map +1 -1
  210. package/dist/schema/types.js +23 -0
  211. package/dist/services/alignment-anchors.d.ts.map +1 -1
  212. package/dist/services/alignment-anchors.js +30 -1
  213. package/dist/services/alignment.d.ts +5 -0
  214. package/dist/services/alignment.d.ts.map +1 -1
  215. package/dist/services/alignment.js +2 -0
  216. package/dist/services/hosting.d.ts +8 -0
  217. package/dist/services/hosting.d.ts.map +1 -1
  218. package/dist/services/hosting.js +13 -4
  219. package/dist/services/hosting.test.js +32 -1
  220. package/dist/services/index.d.ts +8 -2
  221. package/dist/services/index.d.ts.map +1 -1
  222. package/dist/services/index.js +8 -2
  223. package/dist/services/level-height.d.ts +28 -0
  224. package/dist/services/level-height.d.ts.map +1 -0
  225. package/dist/services/level-height.js +62 -0
  226. package/dist/services/opening-guides.d.ts +141 -0
  227. package/dist/services/opening-guides.d.ts.map +1 -0
  228. package/dist/services/opening-guides.js +267 -0
  229. package/dist/services/opening-guides.test.d.ts +2 -0
  230. package/dist/services/opening-guides.test.d.ts.map +1 -0
  231. package/dist/services/opening-guides.test.js +208 -0
  232. package/dist/services/port-connectivity.d.ts +115 -0
  233. package/dist/services/port-connectivity.d.ts.map +1 -0
  234. package/dist/services/port-connectivity.js +300 -0
  235. package/dist/services/port-connectivity.test.d.ts +2 -0
  236. package/dist/services/port-connectivity.test.d.ts.map +1 -0
  237. package/dist/services/port-connectivity.test.js +297 -0
  238. package/dist/services/riser-diagram.d.ts +40 -0
  239. package/dist/services/riser-diagram.d.ts.map +1 -0
  240. package/dist/services/riser-diagram.js +110 -0
  241. package/dist/services/riser-diagram.test.d.ts +2 -0
  242. package/dist/services/riser-diagram.test.d.ts.map +1 -0
  243. package/dist/services/riser-diagram.test.js +66 -0
  244. package/dist/services/snap.d.ts +9 -1
  245. package/dist/services/snap.d.ts.map +1 -1
  246. package/dist/services/snap.js +21 -1
  247. package/dist/services/snap.test.js +43 -1
  248. package/dist/services/system-graph.d.ts +30 -0
  249. package/dist/services/system-graph.d.ts.map +1 -0
  250. package/dist/services/system-graph.js +164 -0
  251. package/dist/services/system-graph.test.d.ts +2 -0
  252. package/dist/services/system-graph.test.d.ts.map +1 -0
  253. package/dist/services/system-graph.test.js +138 -0
  254. package/dist/services/validate-dwv.d.ts +32 -0
  255. package/dist/services/validate-dwv.d.ts.map +1 -0
  256. package/dist/services/validate-dwv.js +118 -0
  257. package/dist/services/validate-dwv.test.d.ts +2 -0
  258. package/dist/services/validate-dwv.test.d.ts.map +1 -0
  259. package/dist/services/validate-dwv.test.js +109 -0
  260. package/dist/store/actions/node-actions.d.ts.map +1 -1
  261. package/dist/store/actions/node-actions.js +94 -1
  262. package/dist/store/actions/ridge-vent-update.test.d.ts +2 -0
  263. package/dist/store/actions/ridge-vent-update.test.d.ts.map +1 -0
  264. package/dist/store/actions/ridge-vent-update.test.js +264 -0
  265. package/dist/store/history-control.d.ts +11 -0
  266. package/dist/store/history-control.d.ts.map +1 -1
  267. package/dist/store/history-control.js +33 -0
  268. package/dist/store/use-scene-dirty-tracking.test.d.ts +2 -0
  269. package/dist/store/use-scene-dirty-tracking.test.d.ts.map +1 -0
  270. package/dist/store/use-scene-dirty-tracking.test.js +68 -0
  271. package/dist/store/use-scene-measurement-roundtrip.test.d.ts +2 -0
  272. package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +1 -0
  273. package/dist/store/use-scene-measurement-roundtrip.test.js +97 -0
  274. package/dist/store/use-scene-plugins.test.d.ts +2 -0
  275. package/dist/store/use-scene-plugins.test.d.ts.map +1 -0
  276. package/dist/store/use-scene-plugins.test.js +51 -0
  277. package/dist/store/use-scene-wall-slot-migration.test.d.ts +2 -0
  278. package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +1 -0
  279. package/dist/store/use-scene-wall-slot-migration.test.js +210 -0
  280. package/dist/store/use-scene-window-migration.test.d.ts +2 -0
  281. package/dist/store/use-scene-window-migration.test.d.ts.map +1 -0
  282. package/dist/store/use-scene-window-migration.test.js +85 -0
  283. package/dist/store/use-scene.d.ts +17 -2
  284. package/dist/store/use-scene.d.ts.map +1 -1
  285. package/dist/store/use-scene.js +358 -51
  286. package/dist/systems/elevator/elevator-service.js +1 -1
  287. package/dist/systems/fence/fence-centerline.d.ts +12 -0
  288. package/dist/systems/fence/fence-centerline.d.ts.map +1 -0
  289. package/dist/systems/fence/fence-centerline.js +37 -0
  290. package/dist/systems/fence/fence-spline.d.ts +39 -0
  291. package/dist/systems/fence/fence-spline.d.ts.map +1 -0
  292. package/dist/systems/fence/fence-spline.js +196 -0
  293. package/dist/systems/fence/fence-spline.test.d.ts +2 -0
  294. package/dist/systems/fence/fence-spline.test.d.ts.map +1 -0
  295. package/dist/systems/fence/fence-spline.test.js +136 -0
  296. package/dist/systems/stair/stair-footprint.d.ts.map +1 -1
  297. package/dist/systems/stair/stair-footprint.js +21 -11
  298. package/dist/systems/stair/stair-opening-preview.d.ts +1139 -469
  299. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  300. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  301. package/dist/systems/stair/stair-opening-sync.js +1 -18
  302. package/dist/systems/stair/stair-opening-sync.test.js +39 -0
  303. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  304. package/dist/systems/wall/wall-mitering.js +38 -2
  305. package/dist/systems/wall/wall-mitering.test.d.ts +2 -0
  306. package/dist/systems/wall/wall-mitering.test.d.ts.map +1 -0
  307. package/dist/systems/wall/wall-mitering.test.js +63 -0
  308. package/dist/utils/clone-scene-graph.d.ts +1 -0
  309. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  310. package/dist/utils/clone-scene-graph.js +23 -3
  311. package/dist/utils/clone-scene-graph.test.js +3 -0
  312. package/dist/utils/heal-scene-graph.d.ts +18 -0
  313. package/dist/utils/heal-scene-graph.d.ts.map +1 -0
  314. package/dist/utils/heal-scene-graph.js +90 -0
  315. package/dist/utils/heal-scene-graph.test.d.ts +2 -0
  316. package/dist/utils/heal-scene-graph.test.d.ts.map +1 -0
  317. package/dist/utils/heal-scene-graph.test.js +88 -0
  318. package/dist/validation/validate-build-json.d.ts +1 -0
  319. package/dist/validation/validate-build-json.d.ts.map +1 -1
  320. package/dist/validation/validate-build-json.js +31 -2
  321. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAkCnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiClB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAC7C,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AA6CnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA6ClB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAC7C,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import z from 'zod';
2
2
  import { BoxVentNode } from './nodes/box-vent';
3
3
  import { BuildingNode } from './nodes/building';
4
+ import { CabinetModuleNode, CabinetNode } from './nodes/cabinet';
4
5
  import { CeilingNode } from './nodes/ceiling';
5
6
  import { ChimneyNode } from './nodes/chimney';
6
7
  import { ColumnNode } from './nodes/column';
@@ -8,13 +9,23 @@ import { CupolaNode } from './nodes/cupola';
8
9
  import { DoorNode } from './nodes/door';
9
10
  import { DormerNode } from './nodes/dormer';
10
11
  import { DownspoutNode } from './nodes/downspout';
12
+ import { DuctFittingNode } from './nodes/duct-fitting';
13
+ import { DuctSegmentNode } from './nodes/duct-segment';
14
+ import { DuctTerminalNode } from './nodes/duct-terminal';
11
15
  import { ElevatorNode } from './nodes/elevator';
12
16
  import { EyebrowVentNode } from './nodes/eyebrow-vent';
13
17
  import { FenceNode } from './nodes/fence';
14
18
  import { GuideNode } from './nodes/guide';
15
19
  import { GutterNode } from './nodes/gutter';
20
+ import { HvacEquipmentNode } from './nodes/hvac-equipment';
16
21
  import { ItemNode } from './nodes/item';
17
22
  import { LevelNode } from './nodes/level';
23
+ import { LinesetNode } from './nodes/lineset';
24
+ import { LiquidLineNode } from './nodes/liquid-line';
25
+ import { MeasurementNode } from './nodes/measurement';
26
+ import { PipeFittingNode } from './nodes/pipe-fitting';
27
+ import { PipeSegmentNode } from './nodes/pipe-segment';
28
+ import { PipeTrapNode } from './nodes/pipe-trap';
18
29
  import { RidgeVentNode } from './nodes/ridge-vent';
19
30
  import { RoofNode } from './nodes/roof';
20
31
  import { RoofSegmentNode } from './nodes/roof-segment';
@@ -39,6 +50,8 @@ export const AnyNode = z.discriminatedUnion('type', [
39
50
  ColumnNode,
40
51
  WallNode,
41
52
  FenceNode,
53
+ CabinetNode,
54
+ CabinetModuleNode,
42
55
  ItemNode,
43
56
  ZoneNode,
44
57
  SlabNode,
@@ -50,6 +63,7 @@ export const AnyNode = z.discriminatedUnion('type', [
50
63
  StairSegmentNode,
51
64
  ScanNode,
52
65
  GuideNode,
66
+ MeasurementNode,
53
67
  SpawnNode,
54
68
  WindowNode,
55
69
  DoorNode,
@@ -64,4 +78,13 @@ export const AnyNode = z.discriminatedUnion('type', [
64
78
  SkylightNode,
65
79
  DormerNode,
66
80
  DownspoutNode,
81
+ DuctSegmentNode,
82
+ DuctFittingNode,
83
+ DuctTerminalNode,
84
+ HvacEquipmentNode,
85
+ LinesetNode,
86
+ LiquidLineNode,
87
+ PipeSegmentNode,
88
+ PipeFittingNode,
89
+ PipeTrapNode,
67
90
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"alignment-anchors.d.ts","sourceRoot":"","sources":["../../src/services/alignment-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,aAAa,CAAA;AAErE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC3C,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7C,SAAS,EAAE,MAAM,GAChB,aAAa,CA4Bf;AAwDD;iDACiD;AACjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAKjE;AAED;;4EAE4E;AAC5E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,aAAa,GAAG,IAAI,CAItB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAInB;AAoBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACpD,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAuBnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAwBnB;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAC7C,eAAe,EAAE,CAEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,eAAe,EAAE,CAkBnB;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,eAAe,EAAE,CAWnB"}
1
+ {"version":3,"file":"alignment-anchors.d.ts","sourceRoot":"","sources":["../../src/services/alignment-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,aAAa,CAAA;AAErE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC3C,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7C,SAAS,EAAE,MAAM,GAChB,aAAa,CA4Bf;AAwDD;iDACiD;AACjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAKjE;AAED;;4EAE4E;AAC5E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,aAAa,GAAG,IAAI,CAItB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAInB;AAoBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACpD,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAuBnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,EAAE,CAwBnB;AAED,gFAAgF;AAChF,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAC7C,eAAe,EAAE,CAEnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,eAAe,EAAE,CAqDnB;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,eAAe,EAAE,CAWnB"}
@@ -233,8 +233,37 @@ export function nodeAlignmentAnchors(node, nodes) {
233
233
  const poly = node.polygon;
234
234
  return poly ? polygonAnchors(node.id, poly) : [];
235
235
  }
236
+ const anchors = [];
237
+ // Box footprint (items, columns, shelves, stairs, …).
236
238
  const aabb = alignmentAABB(node, nodes);
237
- return aabb ? bboxCornerAnchors(node.id, aabb.minX, aabb.minZ, aabb.maxX, aabb.maxZ) : [];
239
+ if (aabb) {
240
+ anchors.push(...bboxCornerAnchors(node.id, aabb.minX, aabb.minZ, aabb.maxX, aabb.maxZ));
241
+ }
242
+ // Polyline kinds (duct / pipe / lineset): every path vertex is an anchor,
243
+ // so anything dragged snaps to a run's ends and bends.
244
+ const path = node.path;
245
+ if (Array.isArray(path)) {
246
+ for (const p of path) {
247
+ anchors.push({ nodeId: node.id, kind: 'corner', x: p[0], z: p[2] });
248
+ }
249
+ }
250
+ // Typed ports (fittings, equipment, terminals, run ends): connection points
251
+ // are natural alignment targets — line a new run up with an existing collar.
252
+ const ports = nodeRegistry.get(node.type)?.ports?.(node);
253
+ if (ports) {
254
+ for (const port of ports) {
255
+ anchors.push({ nodeId: node.id, kind: 'corner', x: port.position[0], z: port.position[2] });
256
+ }
257
+ }
258
+ // Position-based kinds with no footprint (e.g. duct fittings): the origin
259
+ // itself is a useful centre anchor.
260
+ if (!aabb) {
261
+ const position = node.position;
262
+ if (Array.isArray(position)) {
263
+ anchors.push({ nodeId: node.id, kind: 'center', x: position[0], z: position[2] });
264
+ }
265
+ }
266
+ return anchors;
238
267
  }
239
268
  /**
240
269
  * Resolve the level a node belongs to by walking its `parentId` chain, or
@@ -46,6 +46,11 @@ export type AlignmentGuide = {
46
46
  x: number;
47
47
  z: number;
48
48
  };
49
+ /** The matched candidate anchor — the fixed end the moving point aligns to. */
50
+ anchor: {
51
+ x: number;
52
+ z: number;
53
+ };
49
54
  movingAnchorKind: AnchorKind;
50
55
  candidateAnchorKind: AnchorKind;
51
56
  candidateNodeId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../src/services/alignment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEzD,MAAM,MAAM,eAAe,GAAG;IAC5B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,UAAU,CAAA;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,GAAG,GAAG,GAAG,CAAA;AAE1C;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9B,EAAE,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5B,gBAAgB,EAAE,UAAU,CAAA;IAC5B,mBAAmB,EAAE,UAAU,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,kFAAkF;IAClF,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,+EAA+E;IAC/E,UAAU,EAAE,SAAS,eAAe,EAAE,CAAA;IACtC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB;;;OAGG;IACH,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACxC,CAAA;AAgCD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,gCAAgC,GAAG;IAC7C,6EAA6E;IAC7E,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,gFAAgF;IAChF,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACxC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;CAC1B,GAAG,gCAAgC,CAwBnC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CA0FrF;AAID;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAcnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAOnB"}
1
+ {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../src/services/alignment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEzD,MAAM,MAAM,eAAe,GAAG;IAC5B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,UAAU,CAAA;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,GAAG,GAAG,GAAG,CAAA;AAE1C;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9B,EAAE,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5B,+EAA+E;IAC/E,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChC,gBAAgB,EAAE,UAAU,CAAA;IAC5B,mBAAmB,EAAE,UAAU,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAA;IACvB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,kFAAkF;IAClF,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,+EAA+E;IAC/E,UAAU,EAAE,SAAS,eAAe,EAAE,CAAA;IACtC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB;;;OAGG;IACH,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACxC,CAAA;AAgCD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,gCAAgC,GAAG;IAC7C,6EAA6E;IAC7E,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,gFAAgF;IAChF,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACxC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAA;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;CAC1B,GAAG,gCAAgC,CAwBnC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CA4FrF;AAID;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAcnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,eAAe,EAAE,CAOnB"}
@@ -107,6 +107,7 @@ export function resolveAlignment(input) {
107
107
  coord: bestX.c.x,
108
108
  from: { x: bestX.c.x, z: z1 },
109
109
  to: { x: bestX.c.x, z: z2 },
110
+ anchor: { x: bestX.c.x, z: bestX.c.z },
110
111
  movingAnchorKind: bestX.m.kind,
111
112
  candidateAnchorKind: bestX.c.kind,
112
113
  candidateNodeId: bestX.c.nodeId,
@@ -122,6 +123,7 @@ export function resolveAlignment(input) {
122
123
  coord: bestZ.c.z,
123
124
  from: { x: x1, z: bestZ.c.z },
124
125
  to: { x: x2, z: bestZ.c.z },
126
+ anchor: { x: bestZ.c.x, z: bestZ.c.z },
125
127
  movingAnchorKind: bestZ.m.kind,
126
128
  candidateAnchorKind: bestZ.c.kind,
127
129
  candidateNodeId: bestZ.c.nodeId,
@@ -59,6 +59,14 @@ export declare function getSurface(host: AnyNode): SurfacesConfig | null;
59
59
  * stair landing). Returns `null` when the host has no `surfaces.top`.
60
60
  */
61
61
  export declare function getTopSurfaceHeight(host: AnyNode): number | null;
62
+ /**
63
+ * Whether `host` can receive a surface-resting (top-stacked) child. A
64
+ * ceiling-mounted item hangs from the ceiling, so its visible "top" is not a
65
+ * usable resting surface — nothing should stack on a ceiling fan. The check
66
+ * reads the instance-level `asset.attachTo` (not the host KIND, which is shared
67
+ * across all items) so a single gate covers every interaction path.
68
+ */
69
+ export declare function canHostOnTop(host: AnyNode): boolean;
62
70
  /**
63
71
  * Pure host-discovery helper. Given a list of candidate hosts (already
64
72
  * narrowed by spatial query) and a point, returns the first whose
@@ -1 +1 @@
1
- {"version":3,"file":"hosting.d.ts","sourceRoot":"","sources":["../../src/services/hosting.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B,MAAM,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEpD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAA;AAE9E,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAA;AAE3E;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,YAAY,CAoC9F;AAoBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAG/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,KAAK,EAAE,IAAI,CAAA;IACX,UAAU,EAAE,SAAS,OAAO,EAAE,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,OAAO,CAAA;CAClD,GAAG,OAAO,GAAG,IAAI,CAajB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGxE"}
1
+ {"version":3,"file":"hosting.d.ts","sourceRoot":"","sources":["../../src/services/hosting.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B,MAAM,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAEpD,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAA;AAE9E,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAA;AAE3E;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,YAAY,CAoC9F;AAoBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAG/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAGnD;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,KAAK,EAAE,IAAI,CAAA;IACX,UAAU,EAAE,SAAS,OAAO,EAAE,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,OAAO,CAAA;CAClD,GAAG,OAAO,GAAG,IAAI,CAUjB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGxE"}
@@ -89,6 +89,17 @@ export function getTopSurfaceHeight(host) {
89
89
  const { height } = surfaces.top;
90
90
  return typeof height === 'function' ? height(host) : height;
91
91
  }
92
+ /**
93
+ * Whether `host` can receive a surface-resting (top-stacked) child. A
94
+ * ceiling-mounted item hangs from the ceiling, so its visible "top" is not a
95
+ * usable resting surface — nothing should stack on a ceiling fan. The check
96
+ * reads the instance-level `asset.attachTo` (not the host KIND, which is shared
97
+ * across all items) so a single gate covers every interaction path.
98
+ */
99
+ export function canHostOnTop(host) {
100
+ const attachTo = host.asset?.attachTo;
101
+ return attachTo !== 'ceiling';
102
+ }
92
103
  /**
93
104
  * Pure host-discovery helper. Given a list of candidate hosts (already
94
105
  * narrowed by spatial query) and a point, returns the first whose
@@ -102,10 +113,8 @@ export function pickHost(args) {
102
113
  const hostable = def?.capabilities.hostable;
103
114
  if (!hostable)
104
115
  continue;
105
- if (hostable.parents.length > 0 && !hostable.parents.includes('*')) {
106
- // capability declares specific parents; verify the placed kind's own def
107
- // also permits this host kind.
108
- }
116
+ if (!canHostOnTop(host))
117
+ continue;
109
118
  if (args.hitTest && !args.hitTest(host, args.point))
110
119
  continue;
111
120
  return host;
@@ -1,8 +1,17 @@
1
1
  import { beforeEach, describe, expect, test } from 'bun:test';
2
2
  import { z } from 'zod';
3
3
  import { nodeRegistry, registerNode } from '../registry/registry';
4
- import { canAttach, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, } from './hosting';
4
+ import { canAttach, canHostOnTop, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, } from './hosting';
5
5
  const id = (s) => s;
6
+ function makeItem(idStr, attachTo) {
7
+ return {
8
+ id: id(idStr),
9
+ type: 'item',
10
+ parentId: null,
11
+ visible: true,
12
+ asset: attachTo ? { attachTo } : {},
13
+ };
14
+ }
6
15
  function makeDef(kind, capabilities = {}, overrides = {}) {
7
16
  return {
8
17
  kind,
@@ -196,4 +205,26 @@ describe('pickHost', () => {
196
205
  });
197
206
  expect(picked?.id).toBe(id('s2'));
198
207
  });
208
+ test('excludes ceiling-mounted hosts (ceiling fan cannot be a top surface)', () => {
209
+ registerNode(makeDef('item', { hostable: { parents: ['*'] } }));
210
+ const candidates = [makeItem('fan', 'ceiling'), makeItem('table')];
211
+ const picked = pickHost({ point: [0, 0, 0], candidates, placedKind: 'item' });
212
+ expect(picked?.id).toBe(id('table'));
213
+ });
214
+ test('keeps wall-mounted hosts (wall shelf still hosts)', () => {
215
+ registerNode(makeDef('item', { hostable: { parents: ['*'] } }));
216
+ const candidates = [makeItem('shelf', 'wall')];
217
+ const picked = pickHost({ point: [0, 0, 0], candidates, placedKind: 'item' });
218
+ expect(picked?.id).toBe(id('shelf'));
219
+ });
220
+ });
221
+ describe('canHostOnTop', () => {
222
+ test('rejects ceiling-attachTo hosts', () => {
223
+ expect(canHostOnTop(makeItem('fan', 'ceiling'))).toBe(false);
224
+ });
225
+ test('accepts wall / wall-side / floor (undefined) hosts', () => {
226
+ expect(canHostOnTop(makeItem('shelf', 'wall'))).toBe(true);
227
+ expect(canHostOnTop(makeItem('sconce', 'wall-side'))).toBe(true);
228
+ expect(canHostOnTop(makeItem('table'))).toBe(true);
229
+ });
199
230
  });
@@ -1,7 +1,13 @@
1
1
  export { type AlignmentAnchor, type AlignmentGuide, type AlignmentGuideAxis, type AnchorKind, type BuildingPose, bboxAnchors, bboxCornerAnchors, type ResolveAlignmentInBuildingResult, type ResolveAlignmentInput, type ResolveAlignmentResult, resolveAlignment, resolveAlignmentInBuildingWorld, } from './alignment';
2
2
  export { collectAlignmentAnchors, type FootprintAABB, footprintAABB, footprintAABBAt, footprintAABBFrom, movingAlignmentAnchors, movingFootprintAnchors, nodeAlignmentAnchors, polygonAnchors, wallSegmentAnchors, } from './alignment-anchors';
3
3
  export { createDragSession, type DragSession, type DragSessionInput, type DragSessionOptions, } from './drag-session';
4
- export { type AttachError, type AttachResult, canAttach, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, type Vec3, } from './hosting';
4
+ export { type AttachError, type AttachResult, canAttach, canHostOnTop, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, type Vec3, } from './hosting';
5
+ export { DEFAULT_LEVEL_HEIGHT, getCeilingAt, getCeilingHeightAt, getLevelHeight, } from './level-height';
5
6
  export { type AxisLock, applyAxisLock, isMovable, movePlanToward, moveToward, resolveMovable, } from './movement';
6
- export { DEFAULT_ANGLE_STEP, DEFAULT_GRID_STEP, type SnapServices, snapAngleToList, snapPointToAngle, snapPointToGrid, snapScalar, snapServices, snapVec3ToGrid, snapWorldXZToBuildingLocal, } from './snap';
7
+ export { type AlongWallAlignment, type AlongWallFeature, computeEdgeGaps, computeOpeningGuides, DEFAULT_OPENING_GUIDE_TOLERANCES, detectAlongWallAlignment, detectEqualSpacing, detectVerticalAlignment, type EdgeGap, type EqualSpacingRun, type OpeningGuideInput, type OpeningGuides, type OpeningGuideTolerances, type OpeningSpan, type SillHeadGuide, type VerticalAlignment, type VerticalFeature, type WallExtent, } from './opening-guides';
8
+ export { analyzePortConnectivity, type PortConnection, type PortConnectivity, resolveConnectivityUpdates, } from './port-connectivity';
9
+ export { buildRiserDiagram, projectIso, type RiserDiagram, type RiserLine, type RiserMarker, } from './riser-diagram';
10
+ export { DEFAULT_ANGLE_STEP, DEFAULT_GRID_STEP, type SnapServices, snapAngleToList, snapPointAlongAngleRay, snapPointToAngle, snapPointToGrid, snapScalar, snapServices, snapVec3ToGrid, snapWorldXZToBuildingLocal, } from './snap';
11
+ export { buildPortComponents, type SystemSummary, summarizeSystemFor, } from './system-graph';
12
+ export { type DwvFinding, type DwvSeverity, validateDwv, } from './validate-dwv';
7
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,WAAW,EACX,iBAAiB,EACjB,KAAK,gCAAgC,EACrC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,uBAAuB,EACvB,KAAK,aAAa,EAClB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,SAAS,EACT,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,KAAK,IAAI,GACV,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,KAAK,QAAQ,EACb,aAAa,EACb,SAAS,EACT,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,YAAY,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,cAAc,EACd,0BAA0B,GAC3B,MAAM,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,WAAW,EACX,iBAAiB,EACjB,KAAK,gCAAgC,EACrC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,uBAAuB,EACvB,KAAK,aAAa,EAClB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,SAAS,EACT,YAAY,EACZ,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,KAAK,IAAI,GACV,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,KAAK,QAAQ,EACb,aAAa,EACb,SAAS,EACT,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,eAAe,EACf,oBAAoB,EACpB,gCAAgC,EAChC,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,YAAY,EACjB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,cAAc,EACd,0BAA0B,GAC3B,MAAM,QAAQ,CAAA;AACf,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,WAAW,GACZ,MAAM,gBAAgB,CAAA"}
@@ -1,6 +1,12 @@
1
1
  export { bboxAnchors, bboxCornerAnchors, resolveAlignment, resolveAlignmentInBuildingWorld, } from './alignment';
2
2
  export { collectAlignmentAnchors, footprintAABB, footprintAABBAt, footprintAABBFrom, movingAlignmentAnchors, movingFootprintAnchors, nodeAlignmentAnchors, polygonAnchors, wallSegmentAnchors, } from './alignment-anchors';
3
3
  export { createDragSession, } from './drag-session';
4
- export { canAttach, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, } from './hosting';
4
+ export { canAttach, canHostOnTop, clampYToHostTop, getSurface, getTopSurfaceHeight, MAX_HOST_DEPTH, pickHost, } from './hosting';
5
+ export { DEFAULT_LEVEL_HEIGHT, getCeilingAt, getCeilingHeightAt, getLevelHeight, } from './level-height';
5
6
  export { applyAxisLock, isMovable, movePlanToward, moveToward, resolveMovable, } from './movement';
6
- export { DEFAULT_ANGLE_STEP, DEFAULT_GRID_STEP, snapAngleToList, snapPointToAngle, snapPointToGrid, snapScalar, snapServices, snapVec3ToGrid, snapWorldXZToBuildingLocal, } from './snap';
7
+ export { computeEdgeGaps, computeOpeningGuides, DEFAULT_OPENING_GUIDE_TOLERANCES, detectAlongWallAlignment, detectEqualSpacing, detectVerticalAlignment, } from './opening-guides';
8
+ export { analyzePortConnectivity, resolveConnectivityUpdates, } from './port-connectivity';
9
+ export { buildRiserDiagram, projectIso, } from './riser-diagram';
10
+ export { DEFAULT_ANGLE_STEP, DEFAULT_GRID_STEP, snapAngleToList, snapPointAlongAngleRay, snapPointToAngle, snapPointToGrid, snapScalar, snapServices, snapVec3ToGrid, snapWorldXZToBuildingLocal, } from './snap';
11
+ export { buildPortComponents, summarizeSystemFor, } from './system-graph';
12
+ export { validateDwv, } from './validate-dwv';
@@ -0,0 +1,28 @@
1
+ import type { CeilingNode } from '../schema';
2
+ import type { AnyNode, AnyNodeId } from '../schema/types';
3
+ export declare const DEFAULT_LEVEL_HEIGHT = 2.5;
4
+ /**
5
+ * Optional resolver for a wall's rendered base Y (mesh elevation).
6
+ *
7
+ * `packages/core` is pure domain logic and must not read viewer/Three.js
8
+ * state (see AGENTS.md “Layer Boundaries”). Callers that legitimately have
9
+ * registry access (viewer systems, node tools) may pass a resolver so the
10
+ * mesh elevation is factored in; pure/headless callers (MCP, tests, server)
11
+ * omit it and get a deterministic result from serialized node data alone.
12
+ */
13
+ export type WallBaseYResolver = (wallId: AnyNodeId) => number | undefined;
14
+ export declare function getLevelHeight(levelId: string, nodes: Record<AnyNodeId, AnyNode>, resolveWallBaseY?: WallBaseYResolver): number;
15
+ /**
16
+ * The ceiling covering level-local point `[x, z]`, or `null` when none
17
+ * sits over it. Points inside a ceiling's hole are treated as uncovered.
18
+ * When ceilings overlap, the lowest one wins — that's the surface a duct
19
+ * would actually hang from.
20
+ */
21
+ export declare function getCeilingAt(levelId: string, nodes: Record<AnyNodeId, AnyNode>, x: number, z: number): CeilingNode | null;
22
+ /**
23
+ * Underside elevation (meters above the level floor) of the ceiling
24
+ * covering level-local point `[x, z]`, or `null` when no ceiling sits
25
+ * over that point. See {@link getCeilingAt}.
26
+ */
27
+ export declare function getCeilingHeightAt(levelId: string, nodes: Record<AnyNodeId, AnyNode>, x: number, z: number): number | null;
28
+ //# sourceMappingURL=level-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"level-height.d.ts","sourceRoot":"","sources":["../../src/services/level-height.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,WAAW,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEzD,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,SAAS,KAAK,MAAM,GAAG,SAAS,CAAA;AAEzE,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,gBAAgB,CAAC,EAAE,iBAAiB,GACnC,MAAM,CAqBR;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,WAAW,GAAG,IAAI,CAepB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM,GAAG,IAAI,CAGf"}
@@ -0,0 +1,62 @@
1
+ import { pointInPolygon } from '../hooks/spatial-grid/spatial-grid-manager';
2
+ export const DEFAULT_LEVEL_HEIGHT = 2.5;
3
+ export function getLevelHeight(levelId, nodes, resolveWallBaseY) {
4
+ const level = nodes[levelId];
5
+ if (!level)
6
+ return DEFAULT_LEVEL_HEIGHT;
7
+ let maxTop = 0;
8
+ for (const childId of level.children) {
9
+ const child = nodes[childId];
10
+ if (!child)
11
+ continue;
12
+ if (child.type === 'ceiling') {
13
+ const ch = child.height ?? DEFAULT_LEVEL_HEIGHT;
14
+ if (ch > maxTop)
15
+ maxTop = ch;
16
+ }
17
+ else if (child.type === 'wall') {
18
+ let baseY = resolveWallBaseY?.(childId) ?? 0;
19
+ if (baseY < 0)
20
+ baseY = 0;
21
+ const top = baseY + (child.height ?? DEFAULT_LEVEL_HEIGHT);
22
+ if (top > maxTop)
23
+ maxTop = top;
24
+ }
25
+ }
26
+ return maxTop > 0 ? maxTop : DEFAULT_LEVEL_HEIGHT;
27
+ }
28
+ /**
29
+ * The ceiling covering level-local point `[x, z]`, or `null` when none
30
+ * sits over it. Points inside a ceiling's hole are treated as uncovered.
31
+ * When ceilings overlap, the lowest one wins — that's the surface a duct
32
+ * would actually hang from.
33
+ */
34
+ export function getCeilingAt(levelId, nodes, x, z) {
35
+ const level = nodes[levelId];
36
+ if (!level)
37
+ return null;
38
+ let best = null;
39
+ for (const childId of level.children) {
40
+ const child = nodes[childId];
41
+ if (child?.type !== 'ceiling')
42
+ continue;
43
+ const ceiling = child;
44
+ if (ceiling.polygon.length < 3 || !pointInPolygon(x, z, ceiling.polygon))
45
+ continue;
46
+ if (ceiling.holes.some((hole) => hole.length >= 3 && pointInPolygon(x, z, hole)))
47
+ continue;
48
+ const h = ceiling.height ?? DEFAULT_LEVEL_HEIGHT;
49
+ if (best === null || h < (best.height ?? DEFAULT_LEVEL_HEIGHT))
50
+ best = ceiling;
51
+ }
52
+ return best;
53
+ }
54
+ /**
55
+ * Underside elevation (meters above the level floor) of the ceiling
56
+ * covering level-local point `[x, z]`, or `null` when no ceiling sits
57
+ * over that point. See {@link getCeilingAt}.
58
+ */
59
+ export function getCeilingHeightAt(levelId, nodes, x, z) {
60
+ const ceiling = getCeilingAt(levelId, nodes, x, z);
61
+ return ceiling ? (ceiling.height ?? DEFAULT_LEVEL_HEIGHT) : null;
62
+ }
@@ -0,0 +1,141 @@
1
+ /** An opening's footprint in its host wall's local frame. */
2
+ export type OpeningSpan = {
3
+ id: string;
4
+ /** Centre along the wall, measured from `wall.start` (m). */
5
+ centerS: number;
6
+ /** Along-wall extent (m). */
7
+ width: number;
8
+ /** Vertical centre above the wall base (floor at y=0) (m). */
9
+ centerY: number;
10
+ /** Vertical extent (m). */
11
+ height: number;
12
+ };
13
+ export type WallExtent = {
14
+ /** Wall length (m). */
15
+ length: number;
16
+ /** Wall height (m). */
17
+ height: number;
18
+ };
19
+ export type OpeningGuideTolerances = {
20
+ /** Max distance for an edge/centre to count as aligned with a neighbour (m). */
21
+ align: number;
22
+ /** Max difference between two gaps for them to count as equal (m). */
23
+ equalSpacing: number;
24
+ /** Gaps below this are treated as touching/overlap noise and ignored (m). */
25
+ minGap: number;
26
+ };
27
+ export declare const DEFAULT_OPENING_GUIDE_TOLERANCES: OpeningGuideTolerances;
28
+ /** Which along-wall feature of an opening a guide references. */
29
+ export type AlongWallFeature = 'left' | 'center' | 'right';
30
+ /** Which vertical feature of an opening a guide references. */
31
+ export type VerticalFeature = 'sill' | 'center' | 'top';
32
+ export type SillHeadGuide = {
33
+ /** Floor (y=0) → the opening's bottom edge (m). */
34
+ sill: number;
35
+ /** Wall-local y of the bottom edge. */
36
+ bottomY: number;
37
+ /** The opening's top edge → the wall top (m). */
38
+ head: number;
39
+ /** Wall-local y of the top edge. */
40
+ topY: number;
41
+ };
42
+ export type EdgeGap = {
43
+ side: 'left' | 'right';
44
+ /** Clearance along the wall (m). */
45
+ distance: number;
46
+ /** Wall-local s of the moving opening's edge. */
47
+ fromS: number;
48
+ /** Wall-local s of the neighbour edge / wall end. */
49
+ toS: number;
50
+ target: 'opening' | 'wall-start' | 'wall-end';
51
+ /** Set when `target === 'opening'`. */
52
+ targetId?: string;
53
+ };
54
+ export type AlongWallAlignment = {
55
+ /** Wall-local s the two features share. */
56
+ s: number;
57
+ movingFeature: AlongWallFeature;
58
+ targetId: string;
59
+ targetFeature: AlongWallFeature;
60
+ /** Delta to add to the moving opening's `centerS` to make them coincide. */
61
+ snap: number;
62
+ };
63
+ export type VerticalAlignment = {
64
+ /** Wall-local y the two features share. */
65
+ y: number;
66
+ movingFeature: VerticalFeature;
67
+ targetId: string;
68
+ targetFeature: VerticalFeature;
69
+ /** Delta to add to the moving opening's `centerY` to make them coincide. */
70
+ snap: number;
71
+ };
72
+ export type EqualSpacingRun = {
73
+ /** The repeated gap value (average of the run's gaps) (m). */
74
+ gap: number;
75
+ /** The equal-gap segments along the wall, in order (left → right). */
76
+ segments: {
77
+ fromS: number;
78
+ toS: number;
79
+ }[];
80
+ /** Participating opening ids, ordered along the wall, including the moving one. */
81
+ openingIds: string[];
82
+ };
83
+ export type OpeningGuides = {
84
+ sillHead: SillHeadGuide | null;
85
+ gaps: EdgeGap[];
86
+ alongWall: AlongWallAlignment | null;
87
+ vertical: VerticalAlignment | null;
88
+ equalSpacing: EqualSpacingRun | null;
89
+ };
90
+ export type OpeningGuideInput = {
91
+ moving: OpeningSpan;
92
+ /** Other openings on the SAME wall (the moving opening excluded). */
93
+ siblings: readonly OpeningSpan[];
94
+ wall: WallExtent;
95
+ /**
96
+ * Whether to compute vertical (sill/head/vertical-alignment) guides. True for
97
+ * windows; false for doors, which sit on the floor so their sill is always 0.
98
+ */
99
+ includeVertical: boolean;
100
+ tolerances?: Partial<OpeningGuideTolerances>;
101
+ };
102
+ /**
103
+ * Edge-to-edge clearance from the moving opening to the nearest neighbour on
104
+ * each side, falling back to the wall ends when there is no neighbour — the
105
+ * "how much wall is left here" reading. Returns 0–2 gaps (one per side); a side
106
+ * is omitted when its clearance is below `minGap` (the opening is flush against
107
+ * or overlapping that neighbour).
108
+ */
109
+ export declare function computeEdgeGaps(moving: OpeningSpan, siblings: readonly OpeningSpan[], wall: WallExtent, minGap: number): EdgeGap[];
110
+ /**
111
+ * The closest coincidence between any of the moving opening's edges/centre and
112
+ * any sibling's edges/centre along the wall, within `tolerance`. Edge-to-edge
113
+ * and centre-to-centre are weighed equally; the single closest pair wins
114
+ * (matching the one-guide-per-axis behaviour of the floor-plane resolver).
115
+ */
116
+ export declare function detectAlongWallAlignment(moving: OpeningSpan, siblings: readonly OpeningSpan[], tolerance: number): AlongWallAlignment | null;
117
+ /**
118
+ * The closest coincidence between the moving opening's sill/centre/top and any
119
+ * sibling's sill/centre/top, within `tolerance` — the "these two windows share
120
+ * a sill height" detector. Same single-best-match policy as the along-wall
121
+ * variant.
122
+ */
123
+ export declare function detectVerticalAlignment(moving: OpeningSpan, siblings: readonly OpeningSpan[], tolerance: number): VerticalAlignment | null;
124
+ /**
125
+ * Figma-style equal-spacing detection: order all openings along the wall, look
126
+ * at the clearances BETWEEN consecutive openings, and return the longest run of
127
+ * ≥2 consecutive gaps that are equal within `tolerance` and that the moving
128
+ * opening participates in (so the badges only appear while the drag is actually
129
+ * forming or extending a series). Returns null when no such run exists.
130
+ *
131
+ * Gaps below `minGap` (touching/overlapping openings) break a run — a row of
132
+ * flush openings is not "equally spaced".
133
+ */
134
+ export declare function detectEqualSpacing(allOpenings: readonly OpeningSpan[], movingId: string, tolerance: number, minGap: number): EqualSpacingRun | null;
135
+ /**
136
+ * Compute every proximity/alignment guide for the moving opening in one pass.
137
+ * Pure: feed it the moving opening's wall-local span, its same-wall siblings,
138
+ * and the wall extent; render the result in whichever view.
139
+ */
140
+ export declare function computeOpeningGuides(input: OpeningGuideInput): OpeningGuides;
141
+ //# sourceMappingURL=opening-guides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-guides.d.ts","sourceRoot":"","sources":["../../src/services/opening-guides.ts"],"names":[],"mappings":"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"}