@pascal-app/nodes 1.0.0-beta.5 → 1.0.1

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 (929) hide show
  1. package/LICENSE +21 -0
  2. package/dist/block/commands.d.ts +68 -0
  3. package/dist/block/commands.d.ts.map +1 -0
  4. package/dist/block/commands.js +1144 -0
  5. package/dist/block/contextual-help.d.ts +3 -0
  6. package/dist/block/contextual-help.d.ts.map +1 -0
  7. package/dist/block/contextual-help.js +38 -0
  8. package/dist/block/definition.d.ts +8 -0
  9. package/dist/block/definition.d.ts.map +1 -0
  10. package/dist/block/definition.js +126 -0
  11. package/dist/block/edit-session.d.ts +16 -0
  12. package/dist/block/edit-session.d.ts.map +1 -0
  13. package/dist/block/edit-session.js +32 -0
  14. package/dist/block/face-host.d.ts +3 -0
  15. package/dist/block/face-host.d.ts.map +1 -0
  16. package/dist/block/face-host.js +178 -0
  17. package/dist/block/floorplan.d.ts +3 -0
  18. package/dist/block/floorplan.d.ts.map +1 -0
  19. package/dist/block/floorplan.js +43 -0
  20. package/dist/block/geometry-snap.d.ts +18 -0
  21. package/dist/block/geometry-snap.d.ts.map +1 -0
  22. package/dist/block/geometry-snap.js +137 -0
  23. package/dist/block/geometry.d.ts +11 -0
  24. package/dist/block/geometry.d.ts.map +1 -0
  25. package/dist/block/geometry.js +146 -0
  26. package/dist/block/gesture-wheel.d.ts +8 -0
  27. package/dist/block/gesture-wheel.d.ts.map +1 -0
  28. package/dist/block/gesture-wheel.js +7 -0
  29. package/dist/block/interaction-sfx.d.ts +3 -0
  30. package/dist/block/interaction-sfx.d.ts.map +1 -0
  31. package/dist/block/interaction-sfx.js +16 -0
  32. package/dist/block/last-operation.d.ts +48 -0
  33. package/dist/block/last-operation.d.ts.map +1 -0
  34. package/dist/block/last-operation.js +120 -0
  35. package/dist/block/loop-cut-interaction.d.ts +5 -0
  36. package/dist/block/loop-cut-interaction.d.ts.map +1 -0
  37. package/dist/block/loop-cut-interaction.js +13 -0
  38. package/dist/block/material-slots.d.ts +61 -0
  39. package/dist/block/material-slots.d.ts.map +1 -0
  40. package/dist/block/material-slots.js +131 -0
  41. package/dist/block/modal-face-operation.d.ts +13 -0
  42. package/dist/block/modal-face-operation.d.ts.map +1 -0
  43. package/dist/block/modal-face-operation.js +40 -0
  44. package/dist/block/modal-session.d.ts +15 -0
  45. package/dist/block/modal-session.d.ts.map +1 -0
  46. package/dist/block/modal-session.js +40 -0
  47. package/dist/block/modal-transform.d.ts +30 -0
  48. package/dist/block/modal-transform.d.ts.map +1 -0
  49. package/dist/block/modal-transform.js +144 -0
  50. package/dist/block/paint.d.ts +3 -0
  51. package/dist/block/paint.d.ts.map +1 -0
  52. package/dist/block/paint.js +136 -0
  53. package/dist/block/panel.d.ts +2 -0
  54. package/dist/block/panel.d.ts.map +1 -0
  55. package/dist/block/panel.js +234 -0
  56. package/dist/block/parametrics.d.ts +4 -0
  57. package/dist/block/parametrics.d.ts.map +1 -0
  58. package/dist/block/parametrics.js +9 -0
  59. package/dist/block/preview.d.ts +6 -0
  60. package/dist/block/preview.d.ts.map +1 -0
  61. package/dist/block/preview.js +46 -0
  62. package/dist/block/rotation-drag.d.ts +5 -0
  63. package/dist/block/rotation-drag.d.ts.map +1 -0
  64. package/dist/block/rotation-drag.js +18 -0
  65. package/dist/block/schema.d.ts +2 -0
  66. package/dist/block/schema.d.ts.map +1 -0
  67. package/dist/block/schema.js +1 -0
  68. package/dist/block/selection-geometry.d.ts +9 -0
  69. package/dist/block/selection-geometry.d.ts.map +1 -0
  70. package/dist/block/selection-geometry.js +31 -0
  71. package/dist/block/selection-model.d.ts +17 -0
  72. package/dist/block/selection-model.d.ts.map +1 -0
  73. package/dist/block/selection-model.js +84 -0
  74. package/dist/block/selection.d.ts +4 -0
  75. package/dist/block/selection.d.ts.map +1 -0
  76. package/dist/block/selection.js +2570 -0
  77. package/dist/block/slots.d.ts +4 -0
  78. package/dist/block/slots.d.ts.map +1 -0
  79. package/dist/block/slots.js +17 -0
  80. package/dist/block/tool.d.ts +3 -0
  81. package/dist/block/tool.d.ts.map +1 -0
  82. package/dist/block/tool.js +174 -0
  83. package/dist/block/toolbar-state.d.ts +46 -0
  84. package/dist/block/toolbar-state.d.ts.map +1 -0
  85. package/dist/block/toolbar-state.js +67 -0
  86. package/dist/block/use-block-face-operation.d.ts +39 -0
  87. package/dist/block/use-block-face-operation.d.ts.map +1 -0
  88. package/dist/block/use-block-face-operation.js +218 -0
  89. package/dist/box-vent/definition.d.ts.map +1 -1
  90. package/dist/box-vent/definition.js +8 -5
  91. package/dist/box-vent/geometry.d.ts +4 -0
  92. package/dist/box-vent/geometry.d.ts.map +1 -1
  93. package/dist/box-vent/geometry.js +76 -44
  94. package/dist/box-vent/paint.d.ts +4 -0
  95. package/dist/box-vent/paint.d.ts.map +1 -0
  96. package/dist/box-vent/paint.js +40 -0
  97. package/dist/box-vent/panel.js +4 -4
  98. package/dist/box-vent/parametrics.js +3 -3
  99. package/dist/box-vent/renderer.d.ts.map +1 -1
  100. package/dist/box-vent/renderer.js +29 -10
  101. package/dist/cabinet/appliance-layout.d.ts +26 -0
  102. package/dist/cabinet/appliance-layout.d.ts.map +1 -0
  103. package/dist/cabinet/appliance-layout.js +52 -0
  104. package/dist/cabinet/compartment-card.d.ts.map +1 -1
  105. package/dist/cabinet/compartment-card.js +11 -3
  106. package/dist/cabinet/continuous-placement.d.ts +3 -0
  107. package/dist/cabinet/continuous-placement.d.ts.map +1 -1
  108. package/dist/cabinet/continuous-placement.js +6 -0
  109. package/dist/cabinet/countertop-layout.d.ts +173 -0
  110. package/dist/cabinet/countertop-layout.d.ts.map +1 -0
  111. package/dist/cabinet/countertop-layout.js +80 -0
  112. package/dist/cabinet/definition.d.ts.map +1 -1
  113. package/dist/cabinet/definition.js +414 -61
  114. package/dist/cabinet/floorplan-move.d.ts.map +1 -1
  115. package/dist/cabinet/floorplan-move.js +91 -22
  116. package/dist/cabinet/geometry/cooktop.d.ts.map +1 -1
  117. package/dist/cabinet/geometry/cooktop.js +2 -2
  118. package/dist/cabinet/geometry/fridge.d.ts.map +1 -1
  119. package/dist/cabinet/geometry/fridge.js +25 -1
  120. package/dist/cabinet/geometry/fronts.d.ts +4 -0
  121. package/dist/cabinet/geometry/fronts.d.ts.map +1 -1
  122. package/dist/cabinet/geometry/fronts.js +1 -1
  123. package/dist/cabinet/geometry/run.d.ts.map +1 -1
  124. package/dist/cabinet/geometry/run.js +28 -71
  125. package/dist/cabinet/geometry/sink.d.ts +2 -12
  126. package/dist/cabinet/geometry/sink.d.ts.map +1 -1
  127. package/dist/cabinet/geometry/sink.js +8 -39
  128. package/dist/cabinet/geometry.d.ts.map +1 -1
  129. package/dist/cabinet/geometry.js +63 -1
  130. package/dist/cabinet/hosted-resize.d.ts +8 -0
  131. package/dist/cabinet/hosted-resize.d.ts.map +1 -0
  132. package/dist/cabinet/hosted-resize.js +158 -0
  133. package/dist/cabinet/index.d.ts +1 -0
  134. package/dist/cabinet/index.d.ts.map +1 -1
  135. package/dist/cabinet/index.js +1 -0
  136. package/dist/cabinet/insertion.d.ts +19 -0
  137. package/dist/cabinet/insertion.d.ts.map +1 -0
  138. package/dist/cabinet/insertion.js +49 -0
  139. package/dist/cabinet/move-frame.d.ts.map +1 -1
  140. package/dist/cabinet/move-frame.js +68 -2
  141. package/dist/cabinet/panel-context.d.ts +7 -0
  142. package/dist/cabinet/panel-context.d.ts.map +1 -0
  143. package/dist/cabinet/panel-context.js +16 -0
  144. package/dist/cabinet/panel-visibility.d.ts +9 -0
  145. package/dist/cabinet/panel-visibility.d.ts.map +1 -0
  146. package/dist/cabinet/panel-visibility.js +26 -0
  147. package/dist/cabinet/panel.d.ts.map +1 -1
  148. package/dist/cabinet/panel.js +221 -37
  149. package/dist/cabinet/placement-dimensions.d.ts +42 -0
  150. package/dist/cabinet/placement-dimensions.d.ts.map +1 -0
  151. package/dist/cabinet/placement-dimensions.js +227 -0
  152. package/dist/cabinet/placement-snap.d.ts +21 -1
  153. package/dist/cabinet/placement-snap.d.ts.map +1 -1
  154. package/dist/cabinet/placement-snap.js +48 -6
  155. package/dist/cabinet/preset-width-debt.d.ts +7 -0
  156. package/dist/cabinet/preset-width-debt.d.ts.map +1 -0
  157. package/dist/cabinet/preset-width-debt.js +45 -0
  158. package/dist/cabinet/presets.d.ts.map +1 -1
  159. package/dist/cabinet/presets.js +14 -13
  160. package/dist/cabinet/profiles.d.ts +14 -0
  161. package/dist/cabinet/profiles.d.ts.map +1 -0
  162. package/dist/cabinet/profiles.js +30 -0
  163. package/dist/cabinet/quick-actions.d.ts.map +1 -1
  164. package/dist/cabinet/quick-actions.js +8 -24
  165. package/dist/cabinet/reveals.d.ts +37 -0
  166. package/dist/cabinet/reveals.d.ts.map +1 -0
  167. package/dist/cabinet/reveals.js +13 -0
  168. package/dist/cabinet/run-layout.d.ts +98 -5
  169. package/dist/cabinet/run-layout.d.ts.map +1 -1
  170. package/dist/cabinet/run-layout.js +430 -37
  171. package/dist/cabinet/run-ops.d.ts +204 -12
  172. package/dist/cabinet/run-ops.d.ts.map +1 -1
  173. package/dist/cabinet/run-ops.js +523 -36
  174. package/dist/cabinet/run-panel.d.ts +6 -2
  175. package/dist/cabinet/run-panel.d.ts.map +1 -1
  176. package/dist/cabinet/run-panel.js +294 -108
  177. package/dist/cabinet/stack-transitions.d.ts.map +1 -1
  178. package/dist/cabinet/stack-transitions.js +35 -24
  179. package/dist/cabinet/stack.d.ts +169 -1
  180. package/dist/cabinet/stack.d.ts.map +1 -1
  181. package/dist/cabinet/stack.js +57 -18
  182. package/dist/cabinet/surfaces.d.ts +4 -0
  183. package/dist/cabinet/surfaces.d.ts.map +1 -0
  184. package/dist/cabinet/surfaces.js +101 -0
  185. package/dist/cabinet/tool.d.ts.map +1 -1
  186. package/dist/cabinet/tool.js +615 -91
  187. package/dist/cabinet/tree-structure.d.ts.map +1 -1
  188. package/dist/cabinet/tree-structure.js +10 -9
  189. package/dist/cabinet/validation.d.ts +27 -0
  190. package/dist/cabinet/validation.d.ts.map +1 -0
  191. package/dist/cabinet/validation.js +56 -0
  192. package/dist/cabinet/wall-height-presets.d.ts +12 -0
  193. package/dist/cabinet/wall-height-presets.d.ts.map +1 -0
  194. package/dist/cabinet/wall-height-presets.js +15 -0
  195. package/dist/cabinet/wall-snap.d.ts +27 -3
  196. package/dist/cabinet/wall-snap.d.ts.map +1 -1
  197. package/dist/cabinet/wall-snap.js +278 -62
  198. package/dist/cabinet/widths.d.ts +10 -0
  199. package/dist/cabinet/widths.d.ts.map +1 -0
  200. package/dist/cabinet/widths.js +13 -0
  201. package/dist/ceiling/definition.d.ts.map +1 -1
  202. package/dist/ceiling/definition.js +8 -2
  203. package/dist/ceiling/floorplan-affordances.d.ts +12 -12
  204. package/dist/ceiling/materials.d.ts.map +1 -1
  205. package/dist/ceiling/materials.js +0 -1
  206. package/dist/ceiling/panel.js +1 -1
  207. package/dist/ceiling/parametrics.js +1 -1
  208. package/dist/chimney/definition.js +1 -1
  209. package/dist/chimney/panel.js +9 -9
  210. package/dist/chimney/parametrics.js +3 -3
  211. package/dist/column/definition.d.ts.map +1 -1
  212. package/dist/column/definition.js +22 -4
  213. package/dist/column/panel.d.ts.map +1 -1
  214. package/dist/column/panel.js +37 -7
  215. package/dist/column/parametrics.d.ts.map +1 -1
  216. package/dist/column/parametrics.js +5 -3
  217. package/dist/column/tool.d.ts.map +1 -1
  218. package/dist/column/tool.js +50 -14
  219. package/dist/cupola/definition.d.ts.map +1 -1
  220. package/dist/cupola/definition.js +15 -6
  221. package/dist/cupola/geometry.d.ts +6 -0
  222. package/dist/cupola/geometry.d.ts.map +1 -1
  223. package/dist/cupola/geometry.js +60 -13
  224. package/dist/cupola/paint.d.ts +4 -0
  225. package/dist/cupola/paint.d.ts.map +1 -0
  226. package/dist/cupola/paint.js +39 -0
  227. package/dist/cupola/panel.js +1 -1
  228. package/dist/cupola/parametrics.js +3 -3
  229. package/dist/cupola/renderer.d.ts.map +1 -1
  230. package/dist/cupola/renderer.js +27 -8
  231. package/dist/door/floorplan-move.d.ts.map +1 -1
  232. package/dist/door/floorplan-move.js +1 -1
  233. package/dist/door/move-tool.d.ts.map +1 -1
  234. package/dist/door/move-tool.js +86 -32
  235. package/dist/door/panel.d.ts.map +1 -1
  236. package/dist/door/panel.js +12 -12
  237. package/dist/door/parametrics.js +2 -2
  238. package/dist/door/tool.d.ts.map +1 -1
  239. package/dist/door/tool.js +16 -4
  240. package/dist/dormer/csg-geometry.d.ts +6 -42
  241. package/dist/dormer/csg-geometry.d.ts.map +1 -1
  242. package/dist/dormer/csg-geometry.js +38 -209
  243. package/dist/dormer/definition.d.ts +4 -12
  244. package/dist/dormer/definition.d.ts.map +1 -1
  245. package/dist/dormer/definition.js +18 -193
  246. package/dist/dormer/floorplan.d.ts +3 -3
  247. package/dist/dormer/floorplan.d.ts.map +1 -1
  248. package/dist/dormer/floorplan.js +6 -17
  249. package/dist/dormer/geometry.d.ts +5 -24
  250. package/dist/dormer/geometry.d.ts.map +1 -1
  251. package/dist/dormer/geometry.js +64 -41
  252. package/dist/dormer/index.d.ts +1 -1
  253. package/dist/dormer/index.d.ts.map +1 -1
  254. package/dist/dormer/index.js +1 -1
  255. package/dist/dormer/move-tool.d.ts.map +1 -1
  256. package/dist/dormer/move-tool.js +31 -3
  257. package/dist/dormer/panel-position-section.js +2 -2
  258. package/dist/dormer/panel-windows-section.d.ts +9 -0
  259. package/dist/dormer/panel-windows-section.d.ts.map +1 -0
  260. package/dist/dormer/panel-windows-section.js +7 -0
  261. package/dist/dormer/panel.d.ts.map +1 -1
  262. package/dist/dormer/panel.js +100 -18
  263. package/dist/dormer/parametrics.d.ts.map +1 -1
  264. package/dist/dormer/parametrics.js +8 -77
  265. package/dist/dormer/preview.d.ts.map +1 -1
  266. package/dist/dormer/preview.js +9 -1
  267. package/dist/dormer/renderer.d.ts.map +1 -1
  268. package/dist/dormer/renderer.js +24 -26
  269. package/dist/dormer/tool.d.ts.map +1 -1
  270. package/dist/dormer/tool.js +3 -1
  271. package/dist/dormer/window-layout.d.ts +15 -0
  272. package/dist/dormer/window-layout.d.ts.map +1 -0
  273. package/dist/dormer/window-layout.js +59 -0
  274. package/dist/downspout/definition.d.ts.map +1 -1
  275. package/dist/downspout/definition.js +17 -4
  276. package/dist/downspout/geometry.d.ts.map +1 -1
  277. package/dist/downspout/geometry.js +10 -0
  278. package/dist/downspout/inspector-editors.d.ts.map +1 -1
  279. package/dist/downspout/inspector-editors.js +9 -1
  280. package/dist/downspout/parametrics.d.ts.map +1 -1
  281. package/dist/downspout/parametrics.js +2 -1
  282. package/dist/downspout/renderer.d.ts.map +1 -1
  283. package/dist/downspout/renderer.js +19 -3
  284. package/dist/downspout/system.d.ts +7 -0
  285. package/dist/downspout/system.d.ts.map +1 -0
  286. package/dist/downspout/system.js +114 -0
  287. package/dist/duct-fitting/accessory-geometry.d.ts +4 -0
  288. package/dist/duct-fitting/accessory-geometry.d.ts.map +1 -0
  289. package/dist/duct-fitting/accessory-geometry.js +47 -0
  290. package/dist/duct-fitting/definition.d.ts.map +1 -1
  291. package/dist/duct-fitting/definition.js +11 -1
  292. package/dist/duct-fitting/floorplan.d.ts.map +1 -1
  293. package/dist/duct-fitting/floorplan.js +8 -0
  294. package/dist/duct-fitting/geometry.d.ts.map +1 -1
  295. package/dist/duct-fitting/geometry.js +52 -38
  296. package/dist/duct-fitting/parametrics.d.ts.map +1 -1
  297. package/dist/duct-fitting/parametrics.js +78 -15
  298. package/dist/duct-fitting/ports.d.ts +1 -0
  299. package/dist/duct-fitting/ports.d.ts.map +1 -1
  300. package/dist/duct-fitting/ports.js +46 -0
  301. package/dist/duct-fitting/tool.d.ts +19 -0
  302. package/dist/duct-fitting/tool.d.ts.map +1 -1
  303. package/dist/duct-fitting/tool.js +126 -34
  304. package/dist/duct-segment/continuation.d.ts +21 -0
  305. package/dist/duct-segment/continuation.d.ts.map +1 -0
  306. package/dist/duct-segment/continuation.js +167 -0
  307. package/dist/duct-segment/definition.d.ts.map +1 -1
  308. package/dist/duct-segment/definition.js +19 -18
  309. package/dist/duct-segment/floorplan.d.ts.map +1 -1
  310. package/dist/duct-segment/floorplan.js +43 -0
  311. package/dist/duct-segment/geometry.d.ts.map +1 -1
  312. package/dist/duct-segment/geometry.js +3 -0
  313. package/dist/duct-segment/move-tool.d.ts.map +1 -1
  314. package/dist/duct-segment/move-tool.js +33 -6
  315. package/dist/duct-segment/parametrics.d.ts.map +1 -1
  316. package/dist/duct-segment/parametrics.js +49 -1
  317. package/dist/duct-segment/selection.d.ts +3 -4
  318. package/dist/duct-segment/selection.d.ts.map +1 -1
  319. package/dist/duct-segment/selection.js +186 -158
  320. package/dist/duct-segment/tool.d.ts +38 -0
  321. package/dist/duct-segment/tool.d.ts.map +1 -1
  322. package/dist/duct-segment/tool.js +306 -677
  323. package/dist/duct-terminal/parametrics.js +2 -2
  324. package/dist/duct-terminal/tool.d.ts.map +1 -1
  325. package/dist/duct-terminal/tool.js +37 -7
  326. package/dist/elevator/panel.d.ts.map +1 -1
  327. package/dist/elevator/panel.js +7 -7
  328. package/dist/elevator/system.d.ts.map +1 -1
  329. package/dist/elevator/system.js +10 -1
  330. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  331. package/dist/eyebrow-vent/definition.js +8 -5
  332. package/dist/eyebrow-vent/geometry.d.ts +4 -0
  333. package/dist/eyebrow-vent/geometry.d.ts.map +1 -1
  334. package/dist/eyebrow-vent/geometry.js +60 -15
  335. package/dist/eyebrow-vent/paint.d.ts +4 -0
  336. package/dist/eyebrow-vent/paint.d.ts.map +1 -0
  337. package/dist/eyebrow-vent/paint.js +33 -0
  338. package/dist/eyebrow-vent/panel.js +1 -1
  339. package/dist/eyebrow-vent/parametrics.js +3 -3
  340. package/dist/eyebrow-vent/renderer.d.ts.map +1 -1
  341. package/dist/eyebrow-vent/renderer.js +27 -8
  342. package/dist/fence/definition.d.ts.map +1 -1
  343. package/dist/fence/definition.js +2 -1
  344. package/dist/fence/floorplan-affordances.d.ts +1 -0
  345. package/dist/fence/floorplan-affordances.d.ts.map +1 -1
  346. package/dist/fence/floorplan-affordances.js +30 -1
  347. package/dist/fence/floorplan.d.ts.map +1 -1
  348. package/dist/fence/floorplan.js +14 -0
  349. package/dist/fence/inspector-editors.js +1 -1
  350. package/dist/fence/parametrics.js +3 -3
  351. package/dist/fence/tool.d.ts.map +1 -1
  352. package/dist/fence/tool.js +47 -20
  353. package/dist/gutter/corner-mitre.d.ts.map +1 -1
  354. package/dist/gutter/corner-mitre.js +47 -7
  355. package/dist/gutter/definition.d.ts.map +1 -1
  356. package/dist/gutter/definition.js +23 -13
  357. package/dist/gutter/eave-align.d.ts.map +1 -1
  358. package/dist/gutter/eave-align.js +10 -0
  359. package/dist/gutter/eave-snap.d.ts +1 -1
  360. package/dist/gutter/eave-snap.d.ts.map +1 -1
  361. package/dist/gutter/eave-snap.js +10 -23
  362. package/dist/gutter/geometry.d.ts.map +1 -1
  363. package/dist/gutter/geometry.js +126 -8
  364. package/dist/gutter/outlet-lookup.d.ts.map +1 -1
  365. package/dist/gutter/outlet-lookup.js +22 -1
  366. package/dist/gutter/paint.d.ts +3 -0
  367. package/dist/gutter/paint.d.ts.map +1 -0
  368. package/dist/gutter/paint.js +6 -0
  369. package/dist/gutter/parametrics.d.ts.map +1 -1
  370. package/dist/gutter/parametrics.js +4 -1
  371. package/dist/gutter/renderer.d.ts.map +1 -1
  372. package/dist/gutter/renderer.js +63 -7
  373. package/dist/gutter/trim-clip.d.ts +3 -0
  374. package/dist/gutter/trim-clip.d.ts.map +1 -0
  375. package/dist/gutter/trim-clip.js +5 -0
  376. package/dist/hvac-equipment/parametrics.js +3 -3
  377. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  378. package/dist/hvac-equipment/tool.js +12 -2
  379. package/dist/imported-mesh/definition.d.ts +5 -0
  380. package/dist/imported-mesh/definition.d.ts.map +1 -0
  381. package/dist/imported-mesh/definition.js +38 -0
  382. package/dist/imported-mesh/floorplan.d.ts +4 -0
  383. package/dist/imported-mesh/floorplan.d.ts.map +1 -0
  384. package/dist/imported-mesh/floorplan.js +34 -0
  385. package/dist/imported-mesh/geometry.d.ts +5 -0
  386. package/dist/imported-mesh/geometry.d.ts.map +1 -0
  387. package/dist/imported-mesh/geometry.js +34 -0
  388. package/dist/imported-mesh/index.d.ts +4 -0
  389. package/dist/imported-mesh/index.d.ts.map +1 -0
  390. package/dist/imported-mesh/index.js +3 -0
  391. package/dist/imported-mesh/schema.d.ts +2 -0
  392. package/dist/imported-mesh/schema.d.ts.map +1 -0
  393. package/dist/imported-mesh/schema.js +1 -0
  394. package/dist/index.d.ts +7 -2
  395. package/dist/index.d.ts.map +1 -1
  396. package/dist/index.js +17 -2
  397. package/dist/item/definition.d.ts.map +1 -1
  398. package/dist/item/definition.js +10 -2
  399. package/dist/item/floorplan-move.d.ts +9 -1
  400. package/dist/item/floorplan-move.d.ts.map +1 -1
  401. package/dist/item/floorplan-move.js +74 -2
  402. package/dist/item/floorplan.d.ts.map +1 -1
  403. package/dist/item/floorplan.js +33 -1
  404. package/dist/item/move-tool.d.ts +28 -1
  405. package/dist/item/move-tool.d.ts.map +1 -1
  406. package/dist/item/move-tool.js +15 -3
  407. package/dist/item/panel.js +1 -1
  408. package/dist/item/renderer.d.ts.map +1 -1
  409. package/dist/item/renderer.js +16 -6
  410. package/dist/item/system.d.ts +5 -0
  411. package/dist/item/system.d.ts.map +1 -1
  412. package/dist/item/system.js +7 -1
  413. package/dist/lean-to-extension/arc.d.ts +14 -0
  414. package/dist/lean-to-extension/arc.d.ts.map +1 -0
  415. package/dist/lean-to-extension/arc.js +56 -0
  416. package/dist/lean-to-extension/assembly.d.ts +61 -0
  417. package/dist/lean-to-extension/assembly.d.ts.map +1 -0
  418. package/dist/lean-to-extension/assembly.js +761 -0
  419. package/dist/lean-to-extension/canopy-joint.d.ts +35 -0
  420. package/dist/lean-to-extension/canopy-joint.d.ts.map +1 -0
  421. package/dist/lean-to-extension/canopy-joint.js +234 -0
  422. package/dist/lean-to-extension/conical-host.d.ts +15 -0
  423. package/dist/lean-to-extension/conical-host.d.ts.map +1 -0
  424. package/dist/lean-to-extension/conical-host.js +113 -0
  425. package/dist/lean-to-extension/corner-joint.d.ts +29 -0
  426. package/dist/lean-to-extension/corner-joint.d.ts.map +1 -0
  427. package/dist/lean-to-extension/corner-joint.js +1202 -0
  428. package/dist/lean-to-extension/definition.d.ts +4 -0
  429. package/dist/lean-to-extension/definition.d.ts.map +1 -0
  430. package/dist/lean-to-extension/definition.js +433 -0
  431. package/dist/lean-to-extension/floorplan-affordances.d.ts +4 -0
  432. package/dist/lean-to-extension/floorplan-affordances.d.ts.map +1 -0
  433. package/dist/lean-to-extension/floorplan-affordances.js +144 -0
  434. package/dist/lean-to-extension/floorplan-move.d.ts +3 -0
  435. package/dist/lean-to-extension/floorplan-move.d.ts.map +1 -0
  436. package/dist/lean-to-extension/floorplan-move.js +157 -0
  437. package/dist/lean-to-extension/floorplan-tool.d.ts +4 -0
  438. package/dist/lean-to-extension/floorplan-tool.d.ts.map +1 -0
  439. package/dist/lean-to-extension/floorplan-tool.js +385 -0
  440. package/dist/lean-to-extension/floorplan.d.ts +3 -0
  441. package/dist/lean-to-extension/floorplan.d.ts.map +1 -0
  442. package/dist/lean-to-extension/floorplan.js +373 -0
  443. package/dist/lean-to-extension/geometry.d.ts +7 -0
  444. package/dist/lean-to-extension/geometry.d.ts.map +1 -0
  445. package/dist/lean-to-extension/geometry.js +662 -0
  446. package/dist/lean-to-extension/index.d.ts +8 -0
  447. package/dist/lean-to-extension/index.d.ts.map +1 -0
  448. package/dist/lean-to-extension/index.js +7 -0
  449. package/dist/lean-to-extension/layout.d.ts +108 -0
  450. package/dist/lean-to-extension/layout.d.ts.map +1 -0
  451. package/dist/lean-to-extension/layout.js +477 -0
  452. package/dist/lean-to-extension/managed-preview.d.ts +3 -0
  453. package/dist/lean-to-extension/managed-preview.d.ts.map +1 -0
  454. package/dist/lean-to-extension/managed-preview.js +93 -0
  455. package/dist/lean-to-extension/move-tool.d.ts +8 -0
  456. package/dist/lean-to-extension/move-tool.d.ts.map +1 -0
  457. package/dist/lean-to-extension/move-tool.js +202 -0
  458. package/dist/lean-to-extension/paint.d.ts +2 -0
  459. package/dist/lean-to-extension/paint.d.ts.map +1 -0
  460. package/dist/lean-to-extension/paint.js +16 -0
  461. package/dist/lean-to-extension/parametrics.d.ts +4 -0
  462. package/dist/lean-to-extension/parametrics.d.ts.map +1 -0
  463. package/dist/lean-to-extension/parametrics.js +570 -0
  464. package/dist/lean-to-extension/placement-scope.d.ts +3 -0
  465. package/dist/lean-to-extension/placement-scope.d.ts.map +1 -0
  466. package/dist/lean-to-extension/placement-scope.js +4 -0
  467. package/dist/lean-to-extension/placement-validation.d.ts +4 -0
  468. package/dist/lean-to-extension/placement-validation.d.ts.map +1 -0
  469. package/dist/lean-to-extension/placement-validation.js +324 -0
  470. package/dist/lean-to-extension/placement.d.ts +59 -0
  471. package/dist/lean-to-extension/placement.d.ts.map +1 -0
  472. package/dist/lean-to-extension/placement.js +331 -0
  473. package/dist/lean-to-extension/plan-footprint.d.ts +10 -0
  474. package/dist/lean-to-extension/plan-footprint.d.ts.map +1 -0
  475. package/dist/lean-to-extension/plan-footprint.js +27 -0
  476. package/dist/lean-to-extension/preview-geometry.d.ts +7 -0
  477. package/dist/lean-to-extension/preview-geometry.d.ts.map +1 -0
  478. package/dist/lean-to-extension/preview-geometry.js +40 -0
  479. package/dist/lean-to-extension/preview.d.ts +7 -0
  480. package/dist/lean-to-extension/preview.d.ts.map +1 -0
  481. package/dist/lean-to-extension/preview.js +20 -0
  482. package/dist/lean-to-extension/renderer.d.ts +6 -0
  483. package/dist/lean-to-extension/renderer.d.ts.map +1 -0
  484. package/dist/lean-to-extension/renderer.js +34 -0
  485. package/dist/lean-to-extension/roof-attachment.d.ts +28 -0
  486. package/dist/lean-to-extension/roof-attachment.d.ts.map +1 -0
  487. package/dist/lean-to-extension/roof-attachment.js +376 -0
  488. package/dist/lean-to-extension/schema.d.ts +2 -0
  489. package/dist/lean-to-extension/schema.d.ts.map +1 -0
  490. package/dist/lean-to-extension/schema.js +1 -0
  491. package/dist/lean-to-extension/slots.d.ts +5 -0
  492. package/dist/lean-to-extension/slots.d.ts.map +1 -0
  493. package/dist/lean-to-extension/slots.js +15 -0
  494. package/dist/lean-to-extension/system.d.ts +7 -0
  495. package/dist/lean-to-extension/system.d.ts.map +1 -0
  496. package/dist/lean-to-extension/system.js +726 -0
  497. package/dist/lean-to-extension/tool.d.ts +3 -0
  498. package/dist/lean-to-extension/tool.d.ts.map +1 -0
  499. package/dist/lean-to-extension/tool.js +580 -0
  500. package/dist/lean-to-extension/wall-target.d.ts +10 -0
  501. package/dist/lean-to-extension/wall-target.d.ts.map +1 -0
  502. package/dist/lean-to-extension/wall-target.js +29 -0
  503. package/dist/lineset/definition.d.ts.map +1 -1
  504. package/dist/lineset/definition.js +1 -0
  505. package/dist/liquid-line/definition.d.ts.map +1 -1
  506. package/dist/liquid-line/definition.js +1 -0
  507. package/dist/pipe-fitting/definition.d.ts.map +1 -1
  508. package/dist/pipe-fitting/definition.js +16 -2
  509. package/dist/pipe-fitting/floorplan.d.ts.map +1 -1
  510. package/dist/pipe-fitting/floorplan.js +4 -0
  511. package/dist/pipe-fitting/geometry.d.ts +3 -5
  512. package/dist/pipe-fitting/geometry.d.ts.map +1 -1
  513. package/dist/pipe-fitting/geometry.js +154 -21
  514. package/dist/pipe-fitting/inline-insertion.d.ts +13 -0
  515. package/dist/pipe-fitting/inline-insertion.d.ts.map +1 -0
  516. package/dist/pipe-fitting/inline-insertion.js +96 -0
  517. package/dist/pipe-fitting/parametrics.d.ts.map +1 -1
  518. package/dist/pipe-fitting/parametrics.js +17 -3
  519. package/dist/pipe-fitting/ports.d.ts.map +1 -1
  520. package/dist/pipe-fitting/ports.js +8 -1
  521. package/dist/pipe-fitting/tool.d.ts +26 -0
  522. package/dist/pipe-fitting/tool.d.ts.map +1 -1
  523. package/dist/pipe-fitting/tool.js +182 -37
  524. package/dist/pipe-segment/continuation.d.ts +22 -0
  525. package/dist/pipe-segment/continuation.d.ts.map +1 -0
  526. package/dist/pipe-segment/continuation.js +146 -0
  527. package/dist/pipe-segment/definition.d.ts.map +1 -1
  528. package/dist/pipe-segment/definition.js +23 -7
  529. package/dist/pipe-segment/floorplan.d.ts.map +1 -1
  530. package/dist/pipe-segment/floorplan.js +42 -0
  531. package/dist/pipe-segment/geometry.d.ts +2 -1
  532. package/dist/pipe-segment/geometry.d.ts.map +1 -1
  533. package/dist/pipe-segment/geometry.js +4 -1
  534. package/dist/pipe-segment/move-tool.d.ts.map +1 -1
  535. package/dist/pipe-segment/move-tool.js +25 -5
  536. package/dist/pipe-segment/parametrics.d.ts.map +1 -1
  537. package/dist/pipe-segment/parametrics.js +49 -0
  538. package/dist/pipe-segment/selection.d.ts +3 -4
  539. package/dist/pipe-segment/selection.d.ts.map +1 -1
  540. package/dist/pipe-segment/selection.js +169 -105
  541. package/dist/pipe-segment/slope.d.ts +5 -0
  542. package/dist/pipe-segment/slope.d.ts.map +1 -0
  543. package/dist/pipe-segment/slope.js +10 -0
  544. package/dist/pipe-segment/tool.d.ts.map +1 -1
  545. package/dist/pipe-segment/tool.js +325 -545
  546. package/dist/pipe-trap/tool.d.ts.map +1 -1
  547. package/dist/pipe-trap/tool.js +15 -2
  548. package/dist/procedural-item/definition.d.ts +4 -0
  549. package/dist/procedural-item/definition.d.ts.map +1 -0
  550. package/dist/procedural-item/definition.js +254 -0
  551. package/dist/procedural-item/geometry.d.ts +31 -0
  552. package/dist/procedural-item/geometry.d.ts.map +1 -0
  553. package/dist/procedural-item/geometry.js +88 -0
  554. package/dist/procedural-item/index.d.ts +3 -0
  555. package/dist/procedural-item/index.d.ts.map +1 -0
  556. package/dist/procedural-item/index.js +2 -0
  557. package/dist/procedural-item/move-session.d.ts +15 -0
  558. package/dist/procedural-item/move-session.d.ts.map +1 -0
  559. package/dist/procedural-item/move-session.js +197 -0
  560. package/dist/procedural-item/move-tool.d.ts +5 -0
  561. package/dist/procedural-item/move-tool.d.ts.map +1 -0
  562. package/dist/procedural-item/move-tool.js +193 -0
  563. package/dist/procedural-item/renderer.d.ts +5 -0
  564. package/dist/procedural-item/renderer.d.ts.map +1 -0
  565. package/dist/procedural-item/renderer.js +66 -0
  566. package/dist/ridge-vent/definition.js +1 -1
  567. package/dist/ridge-vent/panel.d.ts.map +1 -1
  568. package/dist/ridge-vent/panel.js +4 -4
  569. package/dist/ridge-vent/parametrics.js +1 -1
  570. package/dist/roof/conical-roof-placement.d.ts +36 -0
  571. package/dist/roof/conical-roof-placement.d.ts.map +1 -0
  572. package/dist/roof/conical-roof-placement.js +134 -0
  573. package/dist/roof/conical-roof.d.ts +3 -0
  574. package/dist/roof/conical-roof.d.ts.map +1 -0
  575. package/dist/roof/conical-roof.js +53 -0
  576. package/dist/roof/definition.d.ts +3 -10
  577. package/dist/roof/definition.d.ts.map +1 -1
  578. package/dist/roof/definition.js +83 -13
  579. package/dist/roof/floorplan.d.ts +3 -10
  580. package/dist/roof/floorplan.d.ts.map +1 -1
  581. package/dist/roof/floorplan.js +139 -165
  582. package/dist/roof/index.d.ts +1 -0
  583. package/dist/roof/index.d.ts.map +1 -1
  584. package/dist/roof/index.js +1 -0
  585. package/dist/roof/panel.d.ts.map +1 -1
  586. package/dist/roof/panel.js +26 -25
  587. package/dist/roof/renderer.d.ts.map +1 -1
  588. package/dist/roof/roof-footprint-source.d.ts +16 -0
  589. package/dist/roof/roof-footprint-source.d.ts.map +1 -0
  590. package/dist/roof/roof-footprint-source.js +14 -0
  591. package/dist/roof/roof-footprint.d.ts +25 -0
  592. package/dist/roof/roof-footprint.d.ts.map +1 -0
  593. package/dist/roof/roof-footprint.js +94 -0
  594. package/dist/roof/roof-placement-mode.d.ts +18 -0
  595. package/dist/roof/roof-placement-mode.d.ts.map +1 -0
  596. package/dist/roof/roof-placement-mode.js +24 -0
  597. package/dist/roof/tool.d.ts +10 -0
  598. package/dist/roof/tool.d.ts.map +1 -0
  599. package/dist/roof/tool.js +922 -0
  600. package/dist/roof-segment/definition.d.ts.map +1 -1
  601. package/dist/roof-segment/definition.js +52 -8
  602. package/dist/roof-segment/floorplan-affordances.d.ts +5 -6
  603. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  604. package/dist/roof-segment/floorplan-affordances.js +64 -18
  605. package/dist/roof-segment/floorplan.d.ts +3 -2
  606. package/dist/roof-segment/floorplan.d.ts.map +1 -1
  607. package/dist/roof-segment/floorplan.js +95 -46
  608. package/dist/roof-segment/panel.d.ts.map +1 -1
  609. package/dist/roof-segment/panel.js +122 -27
  610. package/dist/scan/definition.d.ts +2 -3
  611. package/dist/scan/definition.d.ts.map +1 -1
  612. package/dist/scan/definition.js +9 -7
  613. package/dist/scan/parametrics.d.ts.map +1 -1
  614. package/dist/scan/parametrics.js +13 -1
  615. package/dist/scan/renderer.d.ts.map +1 -1
  616. package/dist/scan/renderer.js +8 -2
  617. package/dist/shared/accessory-cursor.d.ts +7 -0
  618. package/dist/shared/accessory-cursor.d.ts.map +1 -0
  619. package/dist/shared/accessory-cursor.js +83 -0
  620. package/dist/shared/accessory-floorplan.d.ts +4 -0
  621. package/dist/shared/accessory-floorplan.d.ts.map +1 -0
  622. package/dist/shared/accessory-floorplan.js +51 -0
  623. package/dist/shared/accessory-geometry.d.ts +7 -0
  624. package/dist/shared/accessory-geometry.d.ts.map +1 -0
  625. package/dist/shared/accessory-geometry.js +79 -0
  626. package/dist/shared/accessory-placement.d.ts +10 -0
  627. package/dist/shared/accessory-placement.d.ts.map +1 -0
  628. package/dist/shared/accessory-placement.js +126 -0
  629. package/dist/shared/accessory-snapping.d.ts +5 -0
  630. package/dist/shared/accessory-snapping.d.ts.map +1 -0
  631. package/dist/shared/accessory-snapping.js +40 -0
  632. package/dist/shared/automatic-run-end-cap.d.ts +12 -0
  633. package/dist/shared/automatic-run-end-cap.d.ts.map +1 -0
  634. package/dist/shared/automatic-run-end-cap.js +169 -0
  635. package/dist/shared/block-face-host.d.ts +15 -0
  636. package/dist/shared/block-face-host.d.ts.map +1 -0
  637. package/dist/shared/block-face-host.js +36 -0
  638. package/dist/shared/connection-compatibility.d.ts +8 -0
  639. package/dist/shared/connection-compatibility.d.ts.map +1 -0
  640. package/dist/shared/connection-compatibility.js +28 -0
  641. package/dist/shared/connection-feedback.d.ts +10 -0
  642. package/dist/shared/connection-feedback.d.ts.map +1 -0
  643. package/dist/shared/connection-feedback.js +17 -0
  644. package/dist/shared/distribution-run-contract.d.ts +49 -0
  645. package/dist/shared/distribution-run-contract.d.ts.map +1 -0
  646. package/dist/shared/distribution-run-contract.js +30 -0
  647. package/dist/shared/distribution-run-tool.d.ts +117 -0
  648. package/dist/shared/distribution-run-tool.d.ts.map +1 -0
  649. package/dist/shared/distribution-run-tool.js +986 -0
  650. package/dist/shared/dormer-wall-opening-placement.d.ts +21 -0
  651. package/dist/shared/dormer-wall-opening-placement.d.ts.map +1 -0
  652. package/dist/shared/dormer-wall-opening-placement.js +101 -0
  653. package/dist/shared/duct-adapter.d.ts +10 -0
  654. package/dist/shared/duct-adapter.d.ts.map +1 -0
  655. package/dist/shared/duct-adapter.js +43 -0
  656. package/dist/shared/elbow-branch-continuation.d.ts +20 -0
  657. package/dist/shared/elbow-branch-continuation.d.ts.map +1 -0
  658. package/dist/shared/elbow-branch-continuation.js +200 -0
  659. package/dist/shared/fitting-clearance.d.ts +5 -0
  660. package/dist/shared/fitting-clearance.d.ts.map +1 -0
  661. package/dist/shared/fitting-clearance.js +11 -0
  662. package/dist/shared/fitting-deletion-cleanup.d.ts +14 -0
  663. package/dist/shared/fitting-deletion-cleanup.d.ts.map +1 -0
  664. package/dist/shared/fitting-deletion-cleanup.js +297 -0
  665. package/dist/shared/fitting-surface-support.d.ts +5 -0
  666. package/dist/shared/fitting-surface-support.d.ts.map +1 -0
  667. package/dist/shared/fitting-surface-support.js +42 -0
  668. package/dist/shared/fitting-tool-options.d.ts +4 -0
  669. package/dist/shared/fitting-tool-options.d.ts.map +1 -0
  670. package/dist/shared/fitting-tool-options.js +175 -0
  671. package/dist/shared/floor-placement.d.ts +1 -1
  672. package/dist/shared/floor-placement.d.ts.map +1 -1
  673. package/dist/shared/floor-placement.js +13 -33
  674. package/dist/shared/ghost-materials.d.ts.map +1 -1
  675. package/dist/shared/ghost-materials.js +2 -1
  676. package/dist/shared/lean-to-post-omissions.d.ts +8 -0
  677. package/dist/shared/lean-to-post-omissions.d.ts.map +1 -0
  678. package/dist/shared/lean-to-post-omissions.js +51 -0
  679. package/dist/shared/mep-fitting-actions.d.ts +5 -0
  680. package/dist/shared/mep-fitting-actions.d.ts.map +1 -0
  681. package/dist/shared/mep-fitting-actions.js +16 -0
  682. package/dist/shared/mep-presets.d.ts +11 -0
  683. package/dist/shared/mep-presets.d.ts.map +1 -0
  684. package/dist/shared/mep-presets.js +34 -0
  685. package/dist/shared/node-batch/candidates.d.ts +29 -0
  686. package/dist/shared/node-batch/candidates.d.ts.map +1 -0
  687. package/dist/shared/node-batch/candidates.js +260 -0
  688. package/dist/shared/node-batch/store.d.ts +26 -0
  689. package/dist/shared/node-batch/store.d.ts.map +1 -0
  690. package/dist/shared/node-batch/store.js +319 -0
  691. package/dist/shared/node-batch/system.d.ts +8 -0
  692. package/dist/shared/node-batch/system.d.ts.map +1 -0
  693. package/dist/shared/node-batch/system.js +569 -0
  694. package/dist/shared/node-batch/types.d.ts +99 -0
  695. package/dist/shared/node-batch/types.d.ts.map +1 -0
  696. package/dist/shared/node-batch/types.js +4 -0
  697. package/dist/shared/opening-move-history.d.ts +47 -0
  698. package/dist/shared/opening-move-history.d.ts.map +1 -0
  699. package/dist/shared/opening-move-history.js +18 -0
  700. package/dist/shared/opening-move-wall-gate.d.ts +55 -0
  701. package/dist/shared/opening-move-wall-gate.d.ts.map +1 -0
  702. package/dist/shared/opening-move-wall-gate.js +44 -0
  703. package/dist/shared/panel-fields.d.ts +15 -0
  704. package/dist/shared/panel-fields.d.ts.map +1 -0
  705. package/dist/shared/panel-fields.js +31 -0
  706. package/dist/shared/path-point-affordance.d.ts +2 -2
  707. package/dist/shared/path-point-affordance.d.ts.map +1 -1
  708. package/dist/shared/path-point-affordance.js +30 -6
  709. package/dist/shared/placeholder-geometry.d.ts.map +1 -1
  710. package/dist/shared/placeholder-geometry.js +4 -0
  711. package/dist/shared/ports.d.ts +20 -3
  712. package/dist/shared/ports.d.ts.map +1 -1
  713. package/dist/shared/ports.js +148 -7
  714. package/dist/shared/primitive-uv.d.ts +17 -0
  715. package/dist/shared/primitive-uv.d.ts.map +1 -0
  716. package/dist/shared/primitive-uv.js +107 -0
  717. package/dist/shared/reducer-size.d.ts +2 -0
  718. package/dist/shared/reducer-size.d.ts.map +1 -0
  719. package/dist/shared/reducer-size.js +12 -0
  720. package/dist/shared/resting-surface-plan.d.ts +3 -0
  721. package/dist/shared/resting-surface-plan.d.ts.map +1 -0
  722. package/dist/shared/resting-surface-plan.js +28 -0
  723. package/dist/shared/ridge-snap.js +1 -1
  724. package/dist/shared/roof-surface.d.ts.map +1 -1
  725. package/dist/shared/roof-surface.js +17 -2
  726. package/dist/shared/run-cursor.d.ts +22 -0
  727. package/dist/shared/run-cursor.d.ts.map +1 -0
  728. package/dist/shared/run-cursor.js +19 -0
  729. package/dist/shared/run-direction-feedback.d.ts +20 -0
  730. package/dist/shared/run-direction-feedback.d.ts.map +1 -0
  731. package/dist/shared/run-direction-feedback.js +139 -0
  732. package/dist/shared/run-hanger-controls.d.ts +7 -0
  733. package/dist/shared/run-hanger-controls.d.ts.map +1 -0
  734. package/dist/shared/run-hanger-controls.js +44 -0
  735. package/dist/shared/run-hanger-inspector.d.ts +5 -0
  736. package/dist/shared/run-hanger-inspector.d.ts.map +1 -0
  737. package/dist/shared/run-hanger-inspector.js +43 -0
  738. package/dist/shared/run-hanger-mode.d.ts +11 -0
  739. package/dist/shared/run-hanger-mode.d.ts.map +1 -0
  740. package/dist/shared/run-hanger-mode.js +32 -0
  741. package/dist/shared/run-hanger-system.d.ts +3 -0
  742. package/dist/shared/run-hanger-system.d.ts.map +1 -0
  743. package/dist/shared/run-hanger-system.js +39 -0
  744. package/dist/shared/run-hangers.d.ts +25 -0
  745. package/dist/shared/run-hangers.d.ts.map +1 -0
  746. package/dist/shared/run-hangers.js +261 -0
  747. package/dist/shared/run-port-snap.d.ts +11 -0
  748. package/dist/shared/run-port-snap.d.ts.map +1 -0
  749. package/dist/shared/run-port-snap.js +19 -0
  750. package/dist/shared/run-screen-direction.d.ts +5 -0
  751. package/dist/shared/run-screen-direction.d.ts.map +1 -0
  752. package/dist/shared/run-screen-direction.js +24 -0
  753. package/dist/shared/selection-handles.d.ts +4 -0
  754. package/dist/shared/selection-handles.d.ts.map +1 -1
  755. package/dist/shared/selection-handles.js +10 -0
  756. package/dist/shared/slot-paint.d.ts +8 -1
  757. package/dist/shared/slot-paint.d.ts.map +1 -1
  758. package/dist/shared/slot-paint.js +120 -27
  759. package/dist/shared/surface-paint.d.ts +1 -2
  760. package/dist/shared/surface-paint.d.ts.map +1 -1
  761. package/dist/shared/surface-paint.js +9 -20
  762. package/dist/shared/system-check-panel.d.ts +6 -0
  763. package/dist/shared/system-check-panel.d.ts.map +1 -0
  764. package/dist/shared/system-check-panel.js +62 -0
  765. package/dist/shared/system-checks.d.ts +9 -0
  766. package/dist/shared/system-checks.d.ts.map +1 -0
  767. package/dist/shared/system-checks.js +131 -0
  768. package/dist/shared/wall-attach-target.d.ts +14 -2
  769. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  770. package/dist/shared/wall-attach-target.js +108 -4
  771. package/dist/shared/wall-opening-clearance.d.ts +19 -0
  772. package/dist/shared/wall-opening-clearance.d.ts.map +1 -0
  773. package/dist/shared/wall-opening-clearance.js +28 -0
  774. package/dist/shared/wall-run-move.d.ts +17 -0
  775. package/dist/shared/wall-run-move.d.ts.map +1 -0
  776. package/dist/shared/wall-run-move.js +56 -0
  777. package/dist/shelf/definition.d.ts.map +1 -1
  778. package/dist/shelf/definition.js +2 -1
  779. package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
  780. package/dist/shelf/floorplan-affordances.js +5 -3
  781. package/dist/shelf/floorplan-move.d.ts.map +1 -1
  782. package/dist/shelf/floorplan-move.js +3 -2
  783. package/dist/shelf/geometry.d.ts.map +1 -1
  784. package/dist/shelf/geometry.js +2 -10
  785. package/dist/shelf/parametrics.js +4 -4
  786. package/dist/site/renderer.d.ts.map +1 -1
  787. package/dist/site/renderer.js +40 -28
  788. package/dist/site/terrain-geometry.d.ts +1 -1
  789. package/dist/site/terrain-geometry.d.ts.map +1 -1
  790. package/dist/site/terrain-geometry.js +35 -9
  791. package/dist/site/terrain-mesh.d.ts +5 -0
  792. package/dist/site/terrain-mesh.d.ts.map +1 -1
  793. package/dist/site/terrain-mesh.js +63 -34
  794. package/dist/skylight/definition.js +1 -1
  795. package/dist/skylight/panel.js +6 -6
  796. package/dist/skylight/parametrics.js +2 -2
  797. package/dist/slab/definition.d.ts.map +1 -1
  798. package/dist/slab/definition.js +6 -1
  799. package/dist/slab/dependency-tracker.d.ts +3 -0
  800. package/dist/slab/dependency-tracker.d.ts.map +1 -0
  801. package/dist/slab/dependency-tracker.js +104 -0
  802. package/dist/slab/floorplan-affordances.d.ts +8 -8
  803. package/dist/slab/geometry.d.ts.map +1 -1
  804. package/dist/slab/geometry.js +16 -2
  805. package/dist/slab/panel.js +1 -1
  806. package/dist/slab/parametrics.js +1 -1
  807. package/dist/slab/system.d.ts.map +1 -1
  808. package/dist/slab/system.js +8 -64
  809. package/dist/solar-panel/definition.js +1 -1
  810. package/dist/solar-panel/panel.js +2 -2
  811. package/dist/solar-panel/parametrics.js +2 -2
  812. package/dist/spawn/panel.js +1 -1
  813. package/dist/stair/panel.d.ts.map +1 -1
  814. package/dist/stair/panel.js +23 -16
  815. package/dist/stair/stair-type.d.ts +18 -0
  816. package/dist/stair/stair-type.d.ts.map +1 -0
  817. package/dist/stair/stair-type.js +25 -0
  818. package/dist/stair-segment/panel.d.ts.map +1 -1
  819. package/dist/stair-segment/panel.js +45 -6
  820. package/dist/turbine-vent/definition.d.ts.map +1 -1
  821. package/dist/turbine-vent/definition.js +8 -5
  822. package/dist/turbine-vent/geometry.d.ts.map +1 -1
  823. package/dist/turbine-vent/geometry.js +48 -18
  824. package/dist/turbine-vent/paint.d.ts +4 -0
  825. package/dist/turbine-vent/paint.d.ts.map +1 -0
  826. package/dist/turbine-vent/paint.js +35 -0
  827. package/dist/turbine-vent/panel.js +1 -1
  828. package/dist/turbine-vent/parametrics.js +2 -2
  829. package/dist/turbine-vent/renderer.d.ts.map +1 -1
  830. package/dist/turbine-vent/renderer.js +31 -9
  831. package/dist/unit/definition.d.ts +10 -0
  832. package/dist/unit/definition.d.ts.map +1 -0
  833. package/dist/unit/definition.js +38 -0
  834. package/dist/unit/index.d.ts +2 -0
  835. package/dist/unit/index.d.ts.map +1 -0
  836. package/dist/unit/index.js +1 -0
  837. package/dist/unit/parametrics.d.ts +3 -0
  838. package/dist/unit/parametrics.d.ts.map +1 -0
  839. package/dist/unit/parametrics.js +4 -0
  840. package/dist/unit/schema.d.ts +2 -0
  841. package/dist/unit/schema.d.ts.map +1 -0
  842. package/dist/unit/schema.js +1 -0
  843. package/dist/unit/unit-panel.d.ts +5 -0
  844. package/dist/unit/unit-panel.d.ts.map +1 -0
  845. package/dist/unit/unit-panel.js +61 -0
  846. package/dist/wall/curve-eligibility.d.ts +3 -0
  847. package/dist/wall/curve-eligibility.d.ts.map +1 -0
  848. package/dist/wall/curve-eligibility.js +10 -0
  849. package/dist/wall/curve-tool.d.ts.map +1 -1
  850. package/dist/wall/curve-tool.js +8 -11
  851. package/dist/wall/definition.d.ts +1 -1
  852. package/dist/wall/definition.d.ts.map +1 -1
  853. package/dist/wall/definition.js +36 -13
  854. package/dist/wall/floorplan-affordances.d.ts +1 -0
  855. package/dist/wall/floorplan-affordances.d.ts.map +1 -1
  856. package/dist/wall/floorplan-affordances.js +46 -7
  857. package/dist/wall/floorplan-move.d.ts +3 -4
  858. package/dist/wall/floorplan-move.d.ts.map +1 -1
  859. package/dist/wall/floorplan-move.js +122 -9
  860. package/dist/wall/floorplan.d.ts.map +1 -1
  861. package/dist/wall/floorplan.js +19 -23
  862. package/dist/wall/move-shared.d.ts.map +1 -1
  863. package/dist/wall/move-shared.js +10 -7
  864. package/dist/wall/paint.d.ts.map +1 -1
  865. package/dist/wall/paint.js +2 -0
  866. package/dist/wall/panel.d.ts.map +1 -1
  867. package/dist/wall/panel.js +10 -17
  868. package/dist/wall/parametrics.js +2 -2
  869. package/dist/wall/pointer-transparency.d.ts +128 -0
  870. package/dist/wall/pointer-transparency.d.ts.map +1 -0
  871. package/dist/wall/pointer-transparency.js +147 -0
  872. package/dist/wall/renderer.d.ts.map +1 -1
  873. package/dist/wall/renderer.js +65 -8
  874. package/dist/wall/selection-hit-owner.d.ts +53 -0
  875. package/dist/wall/selection-hit-owner.d.ts.map +1 -0
  876. package/dist/wall/selection-hit-owner.js +79 -0
  877. package/dist/wall/system.d.ts +2 -0
  878. package/dist/wall/system.d.ts.map +1 -1
  879. package/dist/wall/system.js +66 -25
  880. package/dist/wall/tool.d.ts.map +1 -1
  881. package/dist/wall/tool.js +5 -0
  882. package/dist/wall/treatment-level-data.d.ts +6 -1
  883. package/dist/wall/treatment-level-data.d.ts.map +1 -1
  884. package/dist/wall/treatment-level-data.js +82 -5
  885. package/dist/wall/treatments.d.ts +1 -0
  886. package/dist/wall/treatments.d.ts.map +1 -1
  887. package/dist/wall/treatments.js +5 -0
  888. package/dist/wall/wall-batch-system.d.ts +38 -6
  889. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  890. package/dist/wall/wall-batch-system.js +122 -25
  891. package/dist/wall/wall-batch.js +2 -2
  892. package/dist/window/definition.d.ts +2 -1
  893. package/dist/window/definition.d.ts.map +1 -1
  894. package/dist/window/definition.js +51 -24
  895. package/dist/window/floorplan-move.d.ts.map +1 -1
  896. package/dist/window/floorplan-move.js +1 -1
  897. package/dist/window/move-tool.d.ts +7 -5
  898. package/dist/window/move-tool.d.ts.map +1 -1
  899. package/dist/window/move-tool.js +344 -58
  900. package/dist/window/panel.d.ts.map +1 -1
  901. package/dist/window/panel.js +8 -6
  902. package/dist/window/parametrics.js +2 -2
  903. package/dist/window/renderer.d.ts.map +1 -1
  904. package/dist/window/renderer.js +5 -7
  905. package/dist/window/tool.d.ts.map +1 -1
  906. package/dist/window/tool.js +227 -13
  907. package/dist/zone/definition.d.ts.map +1 -1
  908. package/dist/zone/definition.js +7 -1
  909. package/dist/zone/floorplan-affordances.d.ts +12 -12
  910. package/dist/zone/floorplan.d.ts +1 -3
  911. package/dist/zone/floorplan.d.ts.map +1 -1
  912. package/dist/zone/floorplan.js +43 -28
  913. package/dist/zone/quantities-panel.d.ts.map +1 -1
  914. package/dist/zone/quantities-panel.js +33 -29
  915. package/dist/zone/renderer.d.ts.map +1 -1
  916. package/dist/zone/renderer.js +20 -6
  917. package/dist/zone/unit-membership.d.ts +12 -0
  918. package/dist/zone/unit-membership.d.ts.map +1 -0
  919. package/dist/zone/unit-membership.js +22 -0
  920. package/package.json +16 -8
  921. package/dist/dormer/panel-window-section.d.ts +0 -14
  922. package/dist/dormer/panel-window-section.d.ts.map +0 -1
  923. package/dist/dormer/panel-window-section.js +0 -59
  924. package/dist/dormer/window-assembly.d.ts +0 -22
  925. package/dist/dormer/window-assembly.d.ts.map +0 -1
  926. package/dist/dormer/window-assembly.js +0 -111
  927. package/dist/dormer/window-frame.d.ts +0 -24
  928. package/dist/dormer/window-frame.d.ts.map +0 -1
  929. package/dist/dormer/window-frame.js +0 -100
@@ -0,0 +1,986 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { emitter, sceneRegistry, useScene } from '@pascal-app/core';
4
+ import { CursorSphere, clearPlacementSurface, DimensionPill, getGridEventScreenProjection, isAngleSnapActive, isGridSnapActive, isMagneticSnapActive, markToolCancelConsumed, publishPlacementSurface, triggerSFX, useEditor, useInteractionScope, } from '@pascal-app/editor';
5
+ import { Html } from '@react-three/drei';
6
+ import { useThree } from '@react-three/fiber';
7
+ import { useCallback, useEffect, useRef, useState } from 'react';
8
+ import { createPortal } from 'react-dom';
9
+ import { Vector3 } from 'three';
10
+ import { clearDrawAlignment } from './draw-alignment';
11
+ import { resolveRunCursorPlane } from './run-cursor';
12
+ import { RunDirectionFeedback, run3DDirectionCandidates, runHorizontalDirectionCandidates, } from './run-direction-feedback';
13
+ import { findScreenPort } from './run-port-snap';
14
+ import { chooseScreenDirection, screenDirectionScore } from './run-screen-direction';
15
+ export function shouldLockRunWallSurface(target, connection) {
16
+ return target?.kind === 'wall' && !connection.port && !connection.body;
17
+ }
18
+ export function isSameRunWallSurface(target, hit) {
19
+ return (hit?.kind === 'wall' &&
20
+ hit.hostId === target.hostId &&
21
+ hit.face === 'side' &&
22
+ hit.side === target.side);
23
+ }
24
+ const UP = [0, 1, 0];
25
+ const X_AXIS = [1, 0, 0];
26
+ const Z_AXIS = [0, 0, 1];
27
+ function dotRun(a, b) {
28
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
29
+ }
30
+ function crossRun(a, b) {
31
+ return [
32
+ a[1] * b[2] - a[2] * b[1],
33
+ a[2] * b[0] - a[0] * b[2],
34
+ a[0] * b[1] - a[1] * b[0],
35
+ ];
36
+ }
37
+ function normalizeRun(vector, fallback) {
38
+ const length = Math.hypot(vector[0], vector[1], vector[2]);
39
+ return length < 1e-9
40
+ ? [...fallback]
41
+ : [vector[0] / length, vector[1] / length, vector[2] / length];
42
+ }
43
+ /** Build a stable 2D drawing frame for a floor, wall, ceiling, or sloped face. */
44
+ export function createRunSurfaceFrame(origin, surfaceNormal = UP) {
45
+ const normal = normalizeRun(surfaceNormal, UP);
46
+ // Prefer the building's vertical axis for walls and sloped surfaces. For a
47
+ // horizontal floor/ceiling this deliberately falls back to world X so the
48
+ // frame remains stable and matches the existing floor grid orientation.
49
+ const horizontal = Math.abs(dotRun(normal, UP)) > 0.98;
50
+ const tangent = horizontal
51
+ ? [...X_AXIS]
52
+ : normalizeRun(crossRun(UP, normal), X_AXIS);
53
+ const bitangent = horizontal
54
+ ? [...Z_AXIS]
55
+ : normalizeRun(crossRun(normal, tangent), Z_AXIS);
56
+ return {
57
+ origin: [origin[0], origin[1], origin[2]],
58
+ normal,
59
+ tangent,
60
+ bitangent,
61
+ };
62
+ }
63
+ export function projectRunPointToSurface(point, frame) {
64
+ const offset = [
65
+ point[0] - frame.origin[0],
66
+ point[1] - frame.origin[1],
67
+ point[2] - frame.origin[2],
68
+ ];
69
+ const distance = dotRun(offset, frame.normal);
70
+ return [
71
+ point[0] - frame.normal[0] * distance,
72
+ point[1] - frame.normal[1] * distance,
73
+ point[2] - frame.normal[2] * distance,
74
+ ];
75
+ }
76
+ export function snapRunPointToSurface(point, frame, step) {
77
+ const projected = projectRunPointToSurface(point, frame);
78
+ if (step <= 0)
79
+ return projected;
80
+ const offset = [
81
+ projected[0] - frame.origin[0],
82
+ projected[1] - frame.origin[1],
83
+ projected[2] - frame.origin[2],
84
+ ];
85
+ const u = snapRunValue(dotRun(offset, frame.tangent), step);
86
+ const v = snapRunValue(dotRun(offset, frame.bitangent), step);
87
+ return [
88
+ frame.origin[0] + frame.tangent[0] * u + frame.bitangent[0] * v,
89
+ frame.origin[1] + frame.tangent[1] * u + frame.bitangent[1] * v,
90
+ frame.origin[2] + frame.tangent[2] * u + frame.bitangent[2] * v,
91
+ ];
92
+ }
93
+ export function projectRunToSurfaceAngleLock(from, raw, frame, sourceDirection = null) {
94
+ const fromOffset = [
95
+ from[0] - frame.origin[0],
96
+ from[1] - frame.origin[1],
97
+ from[2] - frame.origin[2],
98
+ ];
99
+ const rawOffset = [raw[0] - from[0], raw[1] - from[1], raw[2] - from[2]];
100
+ const rawU = dotRun(rawOffset, frame.tangent);
101
+ const rawV = dotRun(rawOffset, frame.bitangent);
102
+ const sourceU = sourceDirection ? dotRun(sourceDirection, frame.tangent) : 0;
103
+ const sourceV = sourceDirection ? dotRun(sourceDirection, frame.bitangent) : 0;
104
+ const sourceAngle = sourceDirection && Math.hypot(sourceU, sourceV) > 1e-6
105
+ ? Math.atan2(sourceV, sourceU)
106
+ : Math.atan2(rawV, rawU);
107
+ const angle = Math.round(sourceAngle / ANGLE_STEP_RAD) * ANGLE_STEP_RAD;
108
+ const distance = Math.max(0, rawU * Math.cos(angle) + rawV * Math.sin(angle));
109
+ const u = dotRun(fromOffset, frame.tangent) + Math.cos(angle) * distance;
110
+ const v = dotRun(fromOffset, frame.bitangent) + Math.sin(angle) * distance;
111
+ return [
112
+ frame.origin[0] + frame.tangent[0] * u + frame.bitangent[0] * v,
113
+ frame.origin[1] + frame.tangent[1] * u + frame.bitangent[1] * v,
114
+ frame.origin[2] + frame.tangent[2] * u + frame.bitangent[2] * v,
115
+ ];
116
+ }
117
+ const ANGLE_STEP_RAD = Math.PI / 4;
118
+ const ALT_PIXELS_PER_METER = 100;
119
+ export const RUN_PREVIEW_OPACITY = 0.55;
120
+ export const RUN_SNAP_CURSOR_COLOR = '#22c55e';
121
+ export function runSectionHalfSizeM(nominalInches) {
122
+ return (nominalInches * 0.0254) / 2;
123
+ }
124
+ export function snapRunValue(value, step) {
125
+ if (step <= 0)
126
+ return value;
127
+ return Math.round(value / step) * step;
128
+ }
129
+ export function runDistanceSquared(a, b) {
130
+ const dx = a[0] - b[0];
131
+ const dy = a[1] - b[1];
132
+ const dz = a[2] - b[2];
133
+ return dx * dx + dy * dy + dz * dz;
134
+ }
135
+ export function projectRunToAngleLock(from, raw, sourceDirection = null) {
136
+ const dx = raw[0] - from[0];
137
+ const dz = raw[2] - from[2];
138
+ const length = Math.hypot(dx, dz);
139
+ if (length < 1e-4)
140
+ return [...from];
141
+ if (!sourceDirection) {
142
+ const angle = Math.round(Math.atan2(dz, dx) / ANGLE_STEP_RAD) * ANGLE_STEP_RAD;
143
+ const distance = Math.max(0, dx * Math.cos(angle) + dz * Math.sin(angle));
144
+ return [from[0] + Math.cos(angle) * distance, from[1], from[2] + Math.sin(angle) * distance];
145
+ }
146
+ const candidates = runHorizontalDirectionCandidates(sourceDirection);
147
+ let winner = candidates[0];
148
+ let winningProjection = Number.NEGATIVE_INFINITY;
149
+ for (const candidate of candidates) {
150
+ const projection = dx * candidate[0] + dz * candidate[2];
151
+ if (projection > winningProjection) {
152
+ winner = candidate;
153
+ winningProjection = projection;
154
+ }
155
+ }
156
+ const distance = Math.max(0, winningProjection);
157
+ return [from[0] + winner[0] * distance, from[1], from[2] + winner[2] * distance];
158
+ }
159
+ function dotRunVector(a, b) {
160
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
161
+ }
162
+ function normalizedRunVector(vector) {
163
+ const length = Math.hypot(vector[0], vector[1], vector[2]);
164
+ return length < 1e-9 ? null : [vector[0] / length, vector[1] / length, vector[2] / length];
165
+ }
166
+ export function snapRunLength(from, point, step) {
167
+ const delta = [point[0] - from[0], point[1] - from[1], point[2] - from[2]];
168
+ const length = Math.hypot(...delta);
169
+ if (step <= 0 || length < 1e-9)
170
+ return point;
171
+ const scale = snapRunValue(length, step) / length;
172
+ return [from[0] + delta[0] * scale, from[1] + delta[1] * scale, from[2] + delta[2] * scale];
173
+ }
174
+ export function projectRunToDirection(from, raw, direction) {
175
+ const distance = Math.max(0, dotRun([raw[0] - from[0], raw[1] - from[1], raw[2] - from[2]], direction));
176
+ return [
177
+ from[0] + direction[0] * distance,
178
+ from[1] + direction[1] * distance,
179
+ from[2] + direction[2] * distance,
180
+ ];
181
+ }
182
+ export function projectRunToCameraDirection(from, ray, sourceDirection, minimumDistance, gridStep, candidates = run3DDirectionCandidates(sourceDirection), surfaceFrame, screen) {
183
+ const rayDirection = normalizedRunVector(ray.direction);
184
+ if (!rayDirection)
185
+ return null;
186
+ const fromRayOrigin = [
187
+ ray.origin[0] - from[0],
188
+ ray.origin[1] - from[1],
189
+ ray.origin[2] - from[2],
190
+ ];
191
+ let winner = null;
192
+ let winningAim = Number.NEGATIVE_INFINITY;
193
+ const projectedCandidates = [];
194
+ const scores = [];
195
+ for (const direction of candidates) {
196
+ const parallel = dotRunVector(rayDirection, direction);
197
+ const denominator = 1 - parallel * parallel;
198
+ const projectedDistance = Math.abs(denominator) < 1e-9
199
+ ? minimumDistance
200
+ : (dotRunVector(fromRayOrigin, direction) -
201
+ parallel * dotRunVector(fromRayOrigin, rayDirection)) /
202
+ denominator;
203
+ const distance = Math.max(minimumDistance, snapRunValue(Math.max(projectedDistance, minimumDistance), gridStep));
204
+ const point = [
205
+ from[0] + direction[0] * distance,
206
+ from[1] + direction[1] * distance,
207
+ from[2] + direction[2] * distance,
208
+ ];
209
+ if (surfaceFrame &&
210
+ runDistanceSquared(point, projectRunPointToSurface(point, surfaceFrame)) > 1e-8) {
211
+ continue;
212
+ }
213
+ const aim = normalizedRunVector([
214
+ point[0] - ray.origin[0],
215
+ point[1] - ray.origin[1],
216
+ point[2] - ray.origin[2],
217
+ ]);
218
+ if (!aim)
219
+ continue;
220
+ if (screen) {
221
+ const origin = screen.project(from);
222
+ const tip = screen.project(from.map((value, i) => value + direction[i]));
223
+ scores.push(origin && tip ? screenDirectionScore(origin, tip, screen.pointer) : Infinity);
224
+ projectedCandidates.push({ point, direction });
225
+ }
226
+ const aimDot = dotRunVector(rayDirection, aim);
227
+ if (aimDot > winningAim) {
228
+ winningAim = aimDot;
229
+ winner = { point, direction };
230
+ }
231
+ }
232
+ if (screen) {
233
+ const previous = projectedCandidates.findIndex((candidate) => screen.previous && dotRunVector(candidate.direction, screen.previous) > 0.9999);
234
+ return projectedCandidates[chooseScreenDirection(scores, previous)] ?? null;
235
+ }
236
+ return winner;
237
+ }
238
+ export function stepNominalRunSize(sizes, current, direction) {
239
+ let nearest = 0;
240
+ for (let index = 1; index < sizes.length; index++) {
241
+ if (Math.abs(sizes[index] - current) < Math.abs(sizes[nearest] - current))
242
+ nearest = index;
243
+ }
244
+ return sizes[Math.min(sizes.length - 1, Math.max(0, nearest + direction))] ?? current;
245
+ }
246
+ function wallSurfaceBounds(hostId) {
247
+ const wall = useScene.getState().nodes[hostId];
248
+ if (wall?.type !== 'wall') {
249
+ return { minU: 0, maxU: 0, minV: 0, maxV: 0 };
250
+ }
251
+ return {
252
+ minU: 0,
253
+ maxU: Math.hypot(wall.end[0] - wall.start[0], wall.end[1] - wall.start[1]),
254
+ minV: 0,
255
+ maxV: Math.max(0, wall.height ?? 0),
256
+ };
257
+ }
258
+ function stableWallFrame(frame, hostId, activeLevelId) {
259
+ const wall = useScene.getState().nodes[hostId];
260
+ if (wall?.type !== 'wall')
261
+ return frame;
262
+ const origin = new Vector3(wall.start[0], 0, wall.start[1]);
263
+ const ownerLevel = wall.parentId ? sceneRegistry.nodes.get(wall.parentId) : null;
264
+ const activeLevel = activeLevelId ? sceneRegistry.nodes.get(activeLevelId) : null;
265
+ if (ownerLevel)
266
+ ownerLevel.localToWorld(origin);
267
+ if (activeLevel)
268
+ activeLevel.worldToLocal(origin);
269
+ return {
270
+ ...frame,
271
+ origin: projectRunPointToSurface(origin.toArray(), frame),
272
+ };
273
+ }
274
+ function publishRunSurface(target, point, activeLevelId) {
275
+ if (!target) {
276
+ clearPlacementSurface();
277
+ return;
278
+ }
279
+ const building = activeLevelId ? sceneRegistry.nodes.get(activeLevelId) : null;
280
+ const worldPoint = new Vector3(...point);
281
+ const worldAnchor = new Vector3(...target.frame.origin);
282
+ const worldNormalPoint = new Vector3(target.frame.origin[0] + target.frame.normal[0], target.frame.origin[1] + target.frame.normal[1], target.frame.origin[2] + target.frame.normal[2]);
283
+ if (building) {
284
+ building.localToWorld(worldPoint);
285
+ building.localToWorld(worldAnchor);
286
+ building.localToWorld(worldNormalPoint);
287
+ }
288
+ const worldNormal = worldNormalPoint.sub(worldAnchor).normalize();
289
+ publishPlacementSurface(worldPoint, worldNormal, 'fixed-plane', worldAnchor);
290
+ }
291
+ function surfacePointFromEvent(event, activeLevelId) {
292
+ const source = event.surfaceLocalPosition ?? event.localPosition;
293
+ const point = [source[0], source[1], source[2]];
294
+ const frame = createRunSurfaceFrame(point, event.surfaceNormal ?? UP);
295
+ const planeDistance = dotRun(point, frame.normal);
296
+ frame.origin = frame.normal.map((value) => value * planeDistance);
297
+ const floorLevelId = event.surfaceHit?.levelId ?? activeLevelId;
298
+ const wallNode = event.surfaceHit?.hostId
299
+ ? useScene.getState().nodes[event.surfaceHit.hostId]
300
+ : undefined;
301
+ // The selected level can legitimately remain on the ground floor while the
302
+ // cursor is over a wall on another storey. Resolve the wall's owning level
303
+ // from the hit node so the wall target cannot be downgraded to a floor target.
304
+ const wallLevelId = wallNode?.type === 'wall' ? wallNode.parentId : undefined;
305
+ const target = event.surfaceHit?.kind === 'wall' && event.surfaceHit.face === 'side' && wallLevelId
306
+ ? {
307
+ kind: 'wall',
308
+ levelId: wallLevelId,
309
+ hostId: event.surfaceHit.hostId,
310
+ side: event.surfaceHit.side ?? 'front',
311
+ frame: stableWallFrame(frame, event.surfaceHit.hostId, activeLevelId),
312
+ bounds: wallSurfaceBounds(event.surfaceHit.hostId),
313
+ }
314
+ : floorLevelId
315
+ ? {
316
+ kind: event.surfaceHit?.kind === 'ceiling' || frame.normal[1] < -0.98
317
+ ? 'ceiling'
318
+ : Math.abs(frame.normal[1]) > 0.98
319
+ ? 'floor'
320
+ : 'surface',
321
+ hostId: event.surfaceHit?.hostId,
322
+ levelId: floorLevelId,
323
+ frame,
324
+ }
325
+ : null;
326
+ return {
327
+ point,
328
+ frame: target?.frame ?? frame,
329
+ isHorizontal: event.surfaceNormal == null || Math.abs(frame.normal[1]) > 0.98,
330
+ target,
331
+ };
332
+ }
333
+ export function useDistributionRunTool(config) {
334
+ const { camera, gl } = useThree();
335
+ const initialStartRef = useRef(config.initialStart ? [...config.initialStart] : null);
336
+ const initialConnectionRef = useRef(config.initialConnection ?? { port: null, body: null });
337
+ const [start, setStart] = useState(initialStartRef.current);
338
+ const [cursor, setCursor] = useState(initialStartRef.current);
339
+ const [snapTarget, setSnapTarget] = useState(null);
340
+ const [snapScreen, setSnapScreen] = useState(null);
341
+ const [endConnection, setEndConnection] = useState({
342
+ port: null,
343
+ body: null,
344
+ });
345
+ const [altActive, setAltActive] = useState(false);
346
+ const [directionMode, setDirectionMode] = useState('free');
347
+ const [lengthInput, setLengthInput] = useState('');
348
+ const [validationMessage, setValidationMessage] = useState(null);
349
+ const configRef = useRef(config);
350
+ configRef.current = config;
351
+ const startRef = useRef(start);
352
+ startRef.current = start;
353
+ const startConnectionRef = useRef(initialConnectionRef.current);
354
+ const altAnchorRef = useRef(null);
355
+ const lastPointerRef = useRef(null);
356
+ const refreshCursorRef = useRef(() => { });
357
+ const lastClientYRef = useRef(null);
358
+ const lastResolvedRef = useRef(null);
359
+ const lockedWallTargetRef = useRef(null);
360
+ const forcedDirectionRef = useRef(null);
361
+ const hoveredDirectionRef = useRef(null);
362
+ const lengthInputRef = useRef('');
363
+ useEffect(() => {
364
+ if (!config.active)
365
+ return;
366
+ const toolName = config.toolName;
367
+ useInteractionScope.getState().begin({ kind: 'drafting', tool: toolName });
368
+ return () => {
369
+ useInteractionScope
370
+ .getState()
371
+ .endIf((scope) => scope.kind === 'drafting' && scope.tool === toolName);
372
+ clearPlacementSurface();
373
+ };
374
+ }, [config.active, config.toolName]);
375
+ const refreshCursor = useCallback(() => refreshCursorRef.current(), []);
376
+ const updateLengthInput = useCallback((value) => {
377
+ const normalized = value.replace(',', '.').replace(/[^0-9.]/g, '');
378
+ const firstDot = normalized.indexOf('.');
379
+ const cleaned = firstDot < 0
380
+ ? normalized
381
+ : `${normalized.slice(0, firstDot + 1)}${normalized.slice(firstDot + 1).replace(/\./g, '')}`;
382
+ lengthInputRef.current = cleaned.slice(0, 12);
383
+ setLengthInput(lengthInputRef.current);
384
+ refreshCursorRef.current();
385
+ }, []);
386
+ useEffect(() => {
387
+ if (!config.active)
388
+ return;
389
+ const applyTypedLength = (resolved) => {
390
+ const currentStart = startRef.current;
391
+ const typed = Number.parseFloat(lengthInputRef.current);
392
+ if (!currentStart ||
393
+ !Number.isFinite(typed) ||
394
+ typed <= 0 ||
395
+ resolved.port ||
396
+ resolved.body) {
397
+ return resolved;
398
+ }
399
+ const direction = normalizedRunVector([
400
+ resolved.point[0] - currentStart[0],
401
+ resolved.point[1] - currentStart[1],
402
+ resolved.point[2] - currentStart[2],
403
+ ]);
404
+ if (!direction)
405
+ return resolved;
406
+ return {
407
+ ...resolved,
408
+ point: [
409
+ currentStart[0] + direction[0] * typed,
410
+ currentStart[1] + direction[1] * typed,
411
+ currentStart[2] + direction[2] * typed,
412
+ ],
413
+ snapped: null,
414
+ directionMode: resolved.directionMode,
415
+ };
416
+ };
417
+ const resolvePoint = (event) => {
418
+ const adapter = configRef.current;
419
+ const hit = surfacePointFromEvent(event, adapter.levelId);
420
+ const currentStart = startRef.current;
421
+ const previous = lastResolvedRef.current;
422
+ const lockedWallTarget = currentStart ? lockedWallTargetRef.current : null;
423
+ const lockedWallHit = lockedWallTarget && isSameRunWallSurface(lockedWallTarget, event.surfaceHit);
424
+ const working = lockedWallTarget
425
+ ? {
426
+ ...lockedWallTarget.frame,
427
+ origin: lockedWallTarget.frame.origin.map((value, index) => value +
428
+ lockedWallTarget.frame.normal[index] *
429
+ (adapter.surfaceClearance?.(lockedWallTarget) ?? 0)),
430
+ }
431
+ : !event.surfaceHit && previous?.surfaceTarget?.kind === 'wall' && currentStart
432
+ ? createRunSurfaceFrame(currentStart, UP)
433
+ : (previous?.frame ?? (currentStart ? createRunSurfaceFrame(currentStart) : null));
434
+ const hasSurface = !!event.surfaceHit || !working || !event.localRay;
435
+ const target = lockedWallTarget ?? (hasSurface ? hit.target : null);
436
+ const hitForCursor = lockedWallTarget
437
+ ? lockedWallHit
438
+ ? { point: hit.point, frame: lockedWallTarget.frame }
439
+ : null
440
+ : hasSurface
441
+ ? { point: hit.point, frame: hit.frame }
442
+ : null;
443
+ const resolved = resolveRunCursorPlane({
444
+ hit: hitForCursor,
445
+ working,
446
+ ray: event.localRay,
447
+ fallback: previous?.point ?? currentStart ?? hit.point,
448
+ clearance: adapter.surfaceClearance?.(target) ?? 0,
449
+ });
450
+ const bypass = event.nativeEvent?.altKey === true;
451
+ const gridStep = !bypass && isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
452
+ const angleLocked = !bypass && (isAngleSnapActive() || isGridSnapActive());
453
+ let point = currentStart
454
+ ? resolved.point
455
+ : snapRunPointToSurface(resolved.point, resolved.frame, gridStep);
456
+ const forcedDirection = forcedDirectionRef.current;
457
+ if (currentStart && forcedDirection) {
458
+ point = projectRunToDirection(currentStart, point, forcedDirection);
459
+ }
460
+ if (currentStart && angleLocked && !forcedDirection) {
461
+ const from = projectRunPointToSurface(currentStart, resolved.frame);
462
+ if (runDistanceSquared(from, currentStart) < 1e-6) {
463
+ point = projectRunToSurfaceAngleLock(currentStart, point, resolved.frame);
464
+ }
465
+ }
466
+ if (currentStart && gridStep > 0) {
467
+ point = snapRunLength(currentStart, point, gridStep);
468
+ }
469
+ const sample = { frame: resolved.frame, surfaceTarget: target };
470
+ const native = (event.nativeEvent ?? {});
471
+ const screenProjection = getGridEventScreenProjection(event);
472
+ const pointer = screenProjection?.pointer ?? [native.clientX ?? NaN, native.clientY ?? NaN];
473
+ const rect = gl.domElement.getBoundingClientRect();
474
+ const level = adapter.levelId ? sceneRegistry.nodes.get(adapter.levelId) : null;
475
+ const origin = camera.getWorldPosition(new Vector3());
476
+ const projectConnection = (candidate) => {
477
+ if (screenProjection) {
478
+ const [a, b, c, d, e, f] = screenProjection.localToScreen;
479
+ return {
480
+ x: a * candidate[0] + c * candidate[2] + e,
481
+ y: b * candidate[0] + d * candidate[2] + f,
482
+ depth: 0,
483
+ };
484
+ }
485
+ const world = new Vector3(...candidate);
486
+ if (level)
487
+ level.localToWorld(world);
488
+ const projected = world.clone().project(camera);
489
+ if (projected.z < -1 || projected.z > 1)
490
+ return null;
491
+ if (event.surfaceHit &&
492
+ world.distanceTo(origin) > new Vector3(...event.position).distanceTo(origin) + 0.03)
493
+ return null;
494
+ return {
495
+ x: rect.left + ((projected.x + 1) * rect.width) / 2,
496
+ y: rect.top + ((1 - projected.y) * rect.height) / 2,
497
+ depth: world.distanceTo(origin),
498
+ };
499
+ };
500
+ const acceptsConnection = (candidate) => {
501
+ const screen = projectConnection(candidate);
502
+ return !!screen && Math.hypot(screen.x - pointer[0], screen.y - pointer[1]) <= 12;
503
+ };
504
+ const resolveConnection = (candidate) => {
505
+ if (bypass || !(isGridSnapActive() || isMagneticSnapActive() || isAngleSnapActive()))
506
+ return null;
507
+ const source = startConnectionRef.current.port;
508
+ const hit = findScreenPort(adapter.getPorts(), pointer, projectConnection, source);
509
+ if (hit) {
510
+ return {
511
+ frame: createRunSurfaceFrame([...hit.port.position]),
512
+ surfaceTarget: null,
513
+ point: [...hit.port.position],
514
+ snapped: [...hit.port.position],
515
+ snapScreen: hit.screen,
516
+ directionMode: 'snap',
517
+ port: hit.port,
518
+ body: null,
519
+ };
520
+ }
521
+ const body = adapter.findBody(candidate, target);
522
+ if (body && acceptsConnection(body.point) && body.nodeId !== source?.nodeId) {
523
+ return {
524
+ ...sample,
525
+ point: body.point,
526
+ snapped: body.point,
527
+ directionMode: 'snap',
528
+ port: null,
529
+ body,
530
+ };
531
+ }
532
+ return null;
533
+ };
534
+ const connection = resolveConnection(resolved.point);
535
+ if (connection)
536
+ return connection;
537
+ // Rank displayed directions before a surface projection discards height.
538
+ if (currentStart && event.localRay && !bypass && (forcedDirection || angleLocked)) {
539
+ const source = startConnectionRef.current.port?.direction ?? null;
540
+ const candidates = forcedDirection
541
+ ? [forcedDirection]
542
+ : source
543
+ ? run3DDirectionCandidates(source)
544
+ : runHorizontalDirectionCandidates(null);
545
+ const directionHit = projectRunToCameraDirection(currentStart, event.localRay, source ?? X_AXIS, adapter.minimumSegmentLength ?? 0.05, gridStep, candidates, (target?.kind === 'wall' || target?.kind === 'ceiling') && !forcedDirection
546
+ ? resolved.frame
547
+ : undefined, !forcedDirection && event.nativeEvent
548
+ ? {
549
+ project: (candidate) => {
550
+ const level = adapter.levelId ? sceneRegistry.nodes.get(adapter.levelId) : null;
551
+ const world = new Vector3(...candidate);
552
+ if (level)
553
+ level.localToWorld(world);
554
+ world.project(camera);
555
+ if (world.z < -1 || world.z > 1)
556
+ return null;
557
+ const rect = gl.domElement.getBoundingClientRect();
558
+ return [
559
+ rect.left + ((world.x + 1) * rect.width) / 2,
560
+ rect.top + ((1 - world.y) * rect.height) / 2,
561
+ ];
562
+ },
563
+ pointer: [event.nativeEvent.clientX, event.nativeEvent.clientY],
564
+ previous: hoveredDirectionRef.current,
565
+ }
566
+ : undefined);
567
+ if (directionHit) {
568
+ hoveredDirectionRef.current = directionHit.direction;
569
+ const directionConnection = resolveConnection(directionHit.point);
570
+ if (directionConnection)
571
+ return directionConnection;
572
+ return {
573
+ point: Math.abs(directionHit.direction[1]) < 1e-6 && target?.kind !== 'ceiling'
574
+ ? (adapter.resolveFreeEnd?.(currentStart, directionHit.point, startConnectionRef.current) ?? directionHit.point)
575
+ : directionHit.point,
576
+ frame: event.surfaceHit && !forcedDirection
577
+ ? resolved.frame
578
+ : createRunSurfaceFrame(currentStart),
579
+ surfaceTarget: forcedDirection ||
580
+ (Math.abs(directionHit.direction[1]) > 1e-6 && target?.kind === 'floor')
581
+ ? null
582
+ : target,
583
+ snapped: null,
584
+ directionMode: 'angle',
585
+ port: null,
586
+ body: null,
587
+ };
588
+ }
589
+ }
590
+ if (currentStart && target?.kind !== 'ceiling' && Math.abs(resolved.frame.normal[1]) > 0.98) {
591
+ point = adapter.resolveFreeEnd?.(currentStart, point, startConnectionRef.current) ?? point;
592
+ }
593
+ return {
594
+ ...sample,
595
+ point,
596
+ snapped: null,
597
+ directionMode: angleLocked ? 'angle' : 'free',
598
+ port: null,
599
+ body: null,
600
+ };
601
+ };
602
+ const resolveVerticalPoint = (clientY) => {
603
+ const anchor = altAnchorRef.current;
604
+ const currentStart = startRef.current;
605
+ if (!anchor || !currentStart)
606
+ return null;
607
+ const step = isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
608
+ const delta = snapRunValue((anchor.clientY - clientY) / ALT_PIXELS_PER_METER, step);
609
+ const y = anchor.baseY + delta;
610
+ return [currentStart[0], y, currentStart[2]];
611
+ };
612
+ const updateCursor = (resolved) => {
613
+ if (!resolved.frame && lastResolvedRef.current?.frame)
614
+ resolved = {
615
+ ...resolved,
616
+ frame: { ...lastResolvedRef.current.frame, origin: resolved.point },
617
+ surfaceTarget: lockedWallTargetRef.current,
618
+ };
619
+ lastResolvedRef.current = resolved;
620
+ const currentStart = startRef.current;
621
+ const minimumLength = configRef.current.minimumSegmentLength ?? 0.05;
622
+ const length = currentStart
623
+ ? Math.hypot(resolved.point[0] - currentStart[0], resolved.point[1] - currentStart[1], resolved.point[2] - currentStart[2])
624
+ : 0;
625
+ const typed = lengthInputRef.current;
626
+ setValidationMessage(currentStart &&
627
+ typed &&
628
+ (!Number.isFinite(Number.parseFloat(typed)) || Number.parseFloat(typed) <= 0)
629
+ ? 'Enter a positive length'
630
+ : currentStart && length < minimumLength
631
+ ? `Run must be at least ${minimumLength.toFixed(2)} m`
632
+ : null);
633
+ setCursor(resolved.point);
634
+ setSnapTarget(resolved.snapped);
635
+ setSnapScreen(resolved.snapScreen ?? null);
636
+ setEndConnection({
637
+ port: resolved.port,
638
+ body: resolved.port ? null : resolved.body,
639
+ });
640
+ setDirectionMode(resolved.directionMode);
641
+ if (resolved.frame)
642
+ publishRunSurface({
643
+ kind: 'surface',
644
+ levelId: configRef.current.levelId,
645
+ frame: resolved.frame,
646
+ }, resolved.point, configRef.current.levelId);
647
+ };
648
+ const commit = (end, connection) => {
649
+ const currentStart = startRef.current;
650
+ if (!currentStart)
651
+ return;
652
+ if (lengthInputRef.current && !(Number(lengthInputRef.current) > 0))
653
+ return;
654
+ const minimumLength = configRef.current.minimumSegmentLength ?? 0.05;
655
+ const length = Math.hypot(end[0] - currentStart[0], end[1] - currentStart[1], end[2] - currentStart[2]);
656
+ if (length < minimumLength) {
657
+ return;
658
+ }
659
+ const capturedTarget = lastResolvedRef.current?.surfaceTarget ?? null;
660
+ const clearance = configRef.current.surfaceClearance?.(capturedTarget) ?? 0;
661
+ const surfaceTarget = capturedTarget?.kind === 'wall' &&
662
+ [currentStart, end].some((point) => {
663
+ const projected = projectRunPointToSurface(point, capturedTarget.frame);
664
+ return Math.abs(Math.sqrt(runDistanceSquared(point, projected)) - clearance) > 1e-4;
665
+ })
666
+ ? null
667
+ : capturedTarget;
668
+ const result = configRef.current.commit({
669
+ start: currentStart,
670
+ end,
671
+ startConnection: startConnectionRef.current,
672
+ endConnection: connection,
673
+ surfaceTarget,
674
+ });
675
+ if (!result) {
676
+ setValidationMessage('Fitting clearance is too small for this connection');
677
+ return;
678
+ }
679
+ const lockedWallTarget = lockedWallTargetRef.current;
680
+ if (lockedWallTarget) {
681
+ const offset = result.nextStart.map((value, index) => value - lockedWallTarget.frame.origin[index]);
682
+ const clearance = configRef.current.surfaceClearance?.(lockedWallTarget) ?? 0;
683
+ if (Math.abs(dotRun(offset, lockedWallTarget.frame.normal) - clearance) > 1e-4) {
684
+ lockedWallTargetRef.current = null;
685
+ lastResolvedRef.current = {
686
+ point: result.nextStart,
687
+ frame: createRunSurfaceFrame(result.nextStart),
688
+ surfaceTarget: null,
689
+ snapped: null,
690
+ directionMode: 'free',
691
+ port: null,
692
+ body: null,
693
+ };
694
+ clearPlacementSurface();
695
+ }
696
+ }
697
+ triggerSFX('sfx:item-place');
698
+ startRef.current = result.nextStart;
699
+ setStart(result.nextStart);
700
+ setSnapTarget(null);
701
+ setSnapScreen(null);
702
+ setEndConnection({ port: null, body: null });
703
+ lengthInputRef.current = '';
704
+ setLengthInput('');
705
+ setValidationMessage(null);
706
+ startConnectionRef.current = result.nextConnection;
707
+ forcedDirectionRef.current = null;
708
+ hoveredDirectionRef.current = null;
709
+ altAnchorRef.current = null;
710
+ setAltActive(false);
711
+ };
712
+ const onMove = (event) => {
713
+ lastPointerRef.current = event;
714
+ const clientY = event.nativeEvent?.clientY;
715
+ if (typeof clientY === 'number')
716
+ lastClientYRef.current = clientY;
717
+ if (altAnchorRef.current && typeof clientY === 'number') {
718
+ const point = resolveVerticalPoint(clientY);
719
+ if (point) {
720
+ clearDrawAlignment();
721
+ updateCursor({
722
+ point,
723
+ snapped: null,
724
+ port: null,
725
+ body: null,
726
+ directionMode: 'vertical',
727
+ });
728
+ return;
729
+ }
730
+ }
731
+ updateCursor(applyTypedLength(resolvePoint(event)));
732
+ };
733
+ const onClick = (event) => {
734
+ event.nativeEvent?.stopPropagation?.();
735
+ const currentStart = startRef.current;
736
+ if (altAnchorRef.current && currentStart) {
737
+ const clientY = event.nativeEvent?.clientY ?? lastClientYRef.current;
738
+ if (typeof clientY === 'number') {
739
+ const point = resolveVerticalPoint(clientY);
740
+ if (point && Math.abs(point[1] - currentStart[1]) >= 1e-4) {
741
+ commit(point, { port: null, body: null });
742
+ }
743
+ }
744
+ return;
745
+ }
746
+ const resolved = applyTypedLength(resolvePoint(event));
747
+ updateCursor(resolved);
748
+ if (!currentStart) {
749
+ const connection = {
750
+ port: resolved.port,
751
+ body: resolved.port ? null : resolved.body,
752
+ };
753
+ if (shouldLockRunWallSurface(resolved.surfaceTarget, connection)) {
754
+ lockedWallTargetRef.current = resolved.surfaceTarget;
755
+ }
756
+ triggerSFX('sfx:grid-snap');
757
+ startConnectionRef.current = connection;
758
+ configRef.current.inheritFromConnection?.(connection);
759
+ startRef.current = resolved.point;
760
+ setStart(resolved.point);
761
+ setCursor(resolved.point);
762
+ setSnapTarget(resolved.snapped);
763
+ setSnapScreen(resolved.snapScreen ?? null);
764
+ setEndConnection({ port: null, body: null });
765
+ return;
766
+ }
767
+ const typedResolved = applyTypedLength(resolved);
768
+ commit(typedResolved.point, {
769
+ port: resolved.port,
770
+ body: resolved.port ? null : resolved.body,
771
+ });
772
+ };
773
+ const onKeyDown = (event) => {
774
+ const target = event.target;
775
+ const tag = target?.tagName;
776
+ const isLengthField = target ? target.closest('[data-run-length-input]') !== null : false;
777
+ if ((tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || tag === 'BUTTON') &&
778
+ !isLengthField)
779
+ return;
780
+ if (event.key === 'Escape' && startRef.current) {
781
+ event.preventDefault();
782
+ event.stopImmediatePropagation();
783
+ onCancel();
784
+ useEditor.getState().armToolMode({ mode: 'select' });
785
+ return;
786
+ }
787
+ if (event.key === 'Alt') {
788
+ const currentStart = startRef.current;
789
+ if (!currentStart || lastClientYRef.current === null || altAnchorRef.current)
790
+ return;
791
+ event.preventDefault();
792
+ altAnchorRef.current = {
793
+ clientY: lastClientYRef.current,
794
+ baseY: currentStart[1],
795
+ };
796
+ setAltActive(true);
797
+ return;
798
+ }
799
+ if (event.key === 'Tab' &&
800
+ startRef.current &&
801
+ !event.altKey &&
802
+ !event.metaKey &&
803
+ !event.ctrlKey) {
804
+ event.preventDefault();
805
+ event.stopImmediatePropagation();
806
+ const source = startConnectionRef.current.port?.direction;
807
+ const candidates = source
808
+ ? run3DDirectionCandidates(source)
809
+ : runHorizontalDirectionCandidates(null);
810
+ const current = forcedDirectionRef.current ?? hoveredDirectionRef.current;
811
+ const index = candidates.findIndex((direction) => current && dotRunVector(direction, current) > 0.9999);
812
+ forcedDirectionRef.current =
813
+ candidates[(index + (event.shiftKey ? candidates.length - 1 : 1)) % candidates.length];
814
+ refreshCursorRef.current();
815
+ return;
816
+ }
817
+ if (startRef.current && isLengthField && /^[0-9.,]$/.test(event.key)) {
818
+ event.stopImmediatePropagation();
819
+ return;
820
+ }
821
+ if (startRef.current && !isLengthField && /^[0-9.,]$/.test(event.key)) {
822
+ event.preventDefault();
823
+ event.stopImmediatePropagation();
824
+ updateLengthInput(`${lengthInputRef.current}${event.key}`);
825
+ return;
826
+ }
827
+ if (startRef.current && event.key === 'Enter') {
828
+ event.preventDefault();
829
+ event.stopImmediatePropagation();
830
+ const resolved = lastResolvedRef.current;
831
+ if (resolved) {
832
+ const typedResolved = applyTypedLength(resolved);
833
+ commit(typedResolved.point, {
834
+ port: typedResolved.port,
835
+ body: typedResolved.port ? null : typedResolved.body,
836
+ });
837
+ }
838
+ return;
839
+ }
840
+ configRef.current.onShortcut?.(event, startRef.current);
841
+ };
842
+ const onKeyUp = (event) => {
843
+ if (event.key !== 'Alt' || !altAnchorRef.current)
844
+ return;
845
+ event.preventDefault();
846
+ altAnchorRef.current = null;
847
+ setAltActive(false);
848
+ setDirectionMode('free');
849
+ };
850
+ const onCancel = () => {
851
+ lockedWallTargetRef.current = null;
852
+ clearDrawAlignment();
853
+ if (!startRef.current)
854
+ return;
855
+ markToolCancelConsumed();
856
+ startRef.current = null;
857
+ setStart(null);
858
+ setCursor(null);
859
+ setSnapTarget(null);
860
+ setSnapScreen(null);
861
+ setEndConnection({ port: null, body: null });
862
+ lengthInputRef.current = '';
863
+ setLengthInput('');
864
+ setValidationMessage(null);
865
+ startConnectionRef.current = { port: null, body: null };
866
+ forcedDirectionRef.current = null;
867
+ hoveredDirectionRef.current = null;
868
+ lastPointerRef.current = null;
869
+ clearPlacementSurface();
870
+ lastResolvedRef.current = null;
871
+ altAnchorRef.current = null;
872
+ setAltActive(false);
873
+ };
874
+ refreshCursorRef.current = () => {
875
+ if (lastPointerRef.current)
876
+ updateCursor(applyTypedLength(resolvePoint(lastPointerRef.current)));
877
+ else if (lastResolvedRef.current)
878
+ updateCursor(applyTypedLength(lastResolvedRef.current));
879
+ };
880
+ const unsubscribeSnapping = useEditor.subscribe((state, previous) => {
881
+ const modeChanged = state.snappingModeByContext !== previous.snappingModeByContext;
882
+ if (!modeChanged && state.gridSnapStep === previous.gridSnapStep)
883
+ return;
884
+ if (modeChanged) {
885
+ forcedDirectionRef.current = null;
886
+ hoveredDirectionRef.current = null;
887
+ }
888
+ refreshCursorRef.current();
889
+ });
890
+ emitter.on('grid:click', onClick);
891
+ emitter.on('grid:move', onMove);
892
+ emitter.on('tool:cancel', onCancel);
893
+ window.addEventListener('keydown', onKeyDown, true);
894
+ window.addEventListener('keyup', onKeyUp);
895
+ return () => {
896
+ unsubscribeSnapping();
897
+ emitter.off('grid:click', onClick);
898
+ emitter.off('grid:move', onMove);
899
+ emitter.off('tool:cancel', onCancel);
900
+ window.removeEventListener('keydown', onKeyDown, true);
901
+ window.removeEventListener('keyup', onKeyUp);
902
+ altAnchorRef.current = null;
903
+ lastPointerRef.current = null;
904
+ lockedWallTargetRef.current = null;
905
+ refreshCursorRef.current = () => { };
906
+ clearPlacementSurface();
907
+ clearDrawAlignment();
908
+ };
909
+ }, [camera, gl, config.active, updateLengthInput]);
910
+ return {
911
+ refreshCursor,
912
+ start,
913
+ cursor,
914
+ snapTarget,
915
+ snapScreen,
916
+ altActive,
917
+ directionMode,
918
+ lengthInput,
919
+ validationMessage,
920
+ onLengthInputChange: updateLengthInput,
921
+ onDirectionSelect: (direction) => {
922
+ forcedDirectionRef.current = direction;
923
+ setDirectionMode('angle');
924
+ refreshCursorRef.current();
925
+ },
926
+ startConnection: startConnectionRef.current,
927
+ endConnection,
928
+ surfaceTarget: lastResolvedRef.current?.surfaceTarget ?? null,
929
+ };
930
+ }
931
+ export function DistributionRunCursor({ cursor, start, snapTarget, snapScreen, altActive, unit, extraParts = [], cursorRef, directionMode, startDirection, lengthInput, validationMessage, onLengthInputChange, onDirectionSelect, }) {
932
+ const lengthFieldRef = useRef(null);
933
+ useEffect(() => {
934
+ if (start)
935
+ lengthFieldRef.current?.focus();
936
+ }, [start]);
937
+ if (!cursor)
938
+ return null;
939
+ const parts = [
940
+ ...(start
941
+ ? [
942
+ {
943
+ key: 'length',
944
+ prefix: 'L',
945
+ value: Math.hypot(cursor[0] - start[0], cursor[1] - start[1], cursor[2] - start[2]),
946
+ },
947
+ ]
948
+ : []),
949
+ {
950
+ key: 'x',
951
+ prefix: 'X',
952
+ value: start ? cursor[0] - start[0] : cursor[0],
953
+ signed: !!start,
954
+ },
955
+ {
956
+ key: 'y',
957
+ prefix: 'Y',
958
+ value: start ? cursor[1] - start[1] : cursor[1],
959
+ signed: !!start,
960
+ },
961
+ {
962
+ key: 'z',
963
+ prefix: 'Z',
964
+ value: start ? cursor[2] - start[2] : cursor[2],
965
+ signed: !!start,
966
+ },
967
+ ...extraParts,
968
+ ];
969
+ const primary = start ? (altActive ? 'y' : 'length') : undefined;
970
+ const elevated = cursor[1] > 0.001;
971
+ const ground = [cursor[0], 0, cursor[2]];
972
+ return (_jsxs(_Fragment, { children: [snapScreen && (_jsx(Html, { style: { pointerEvents: 'none' }, children: createPortal(_jsx("div", { style: {
973
+ position: 'fixed',
974
+ left: snapScreen.x,
975
+ top: snapScreen.y,
976
+ pointerEvents: 'none',
977
+ zIndex: 110,
978
+ }, children: _jsx("div", { className: "absolute h-5 w-5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-emerald-500 bg-emerald-500/20 ring-2 ring-background" }) }), document.body) })), start && (_jsx(RunDirectionFeedback, { cursor: cursor, mode: directionMode, snapped: !!snapTarget, sourceDirection: startDirection ?? null, start: start, onDirectionSelect: onDirectionSelect })), _jsx(CursorSphere, { color: snapTarget ? RUN_SNAP_CURSOR_COLOR : undefined, dotAtTip: elevated || undefined, height: elevated ? cursor[1] : undefined, position: elevated ? ground : cursor, ref: cursorRef }), _jsx("group", { position: cursor, children: _jsx(Html, { center: true, position: [0, 1.45, 0], style: { pointerEvents: 'none', userSelect: 'none' }, zIndexRange: [100, 0], children: _jsxs("div", { className: "flex flex-col items-center gap-1", children: [_jsx(DimensionPill, { parts: parts, primary: primary, unit: unit }), start ? (_jsxs("label", { className: "rounded-full border border-border/60 bg-background/90 px-3 py-1 text-[11px] tabular-nums text-muted-foreground shadow-sm backdrop-blur", children: ["Length:", ' ', _jsx("input", { className: "w-20 bg-transparent text-center text-foreground outline-none", "data-run-length-input": true, inputMode: "decimal", onKeyDown: (event) => {
979
+ if (event.key === 'Backspace' ||
980
+ event.key === 'Delete' ||
981
+ event.key === 'ArrowLeft' ||
982
+ event.key === 'ArrowRight') {
983
+ event.stopPropagation();
984
+ }
985
+ }, onChange: (event) => onLengthInputChange?.(event.target.value), onPointerDown: (event) => event.stopPropagation(), placeholder: "type a length", ref: lengthFieldRef, style: { pointerEvents: 'auto' }, type: "text", value: lengthInput ?? '' }), ' ', "m", _jsx("span", { className: "ml-2", children: "Tab: direction" })] })) : null, validationMessage ? (_jsx("div", { className: "rounded-full border border-red-500/50 bg-red-500/10 px-3 py-1 text-[11px] text-red-700 shadow-sm backdrop-blur dark:text-red-300", children: validationMessage })) : null] }) }) })] }));
986
+ }