@pascal-app/nodes 1.0.3 → 1.0.4

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 (708) hide show
  1. package/dist/block/definition.d.ts.map +1 -1
  2. package/dist/block/definition.js +18 -3
  3. package/dist/block/floorplan.d.ts +11 -1
  4. package/dist/block/floorplan.d.ts.map +1 -1
  5. package/dist/block/floorplan.js +81 -13
  6. package/dist/block/geometry.d.ts +2 -2
  7. package/dist/block/geometry.d.ts.map +1 -1
  8. package/dist/block/geometry.js +39 -24
  9. package/dist/block/hosted-edit.d.ts.map +1 -1
  10. package/dist/block/hosted-edit.js +25 -0
  11. package/dist/block/material-slots.d.ts +1 -3
  12. package/dist/block/material-slots.d.ts.map +1 -1
  13. package/dist/block/material-slots.js +1 -11
  14. package/dist/block/paint.d.ts.map +1 -1
  15. package/dist/block/paint.js +4 -10
  16. package/dist/block/panel.d.ts.map +1 -1
  17. package/dist/block/panel.js +8 -3
  18. package/dist/block/selection.d.ts.map +1 -1
  19. package/dist/block/selection.js +2 -2
  20. package/dist/box-vent/definition.d.ts.map +1 -1
  21. package/dist/box-vent/definition.js +2 -5
  22. package/dist/box-vent/panel.d.ts.map +1 -1
  23. package/dist/box-vent/panel.js +5 -28
  24. package/dist/cabinet/countertop-layout.d.ts +13 -2
  25. package/dist/cabinet/countertop-layout.d.ts.map +1 -1
  26. package/dist/cabinet/definition.d.ts.map +1 -1
  27. package/dist/cabinet/definition.js +1 -2
  28. package/dist/cabinet/floorplan.d.ts.map +1 -1
  29. package/dist/cabinet/floorplan.js +125 -28
  30. package/dist/cabinet/geometry/shared.d.ts +1 -2
  31. package/dist/cabinet/geometry/shared.d.ts.map +1 -1
  32. package/dist/cabinet/geometry/shared.js +1 -2
  33. package/dist/cabinet/run-layout.d.ts.map +1 -1
  34. package/dist/cabinet/run-layout.js +8 -5
  35. package/dist/cabinet/run-ops.d.ts +13 -2
  36. package/dist/cabinet/run-ops.d.ts.map +1 -1
  37. package/dist/cabinet/tool.d.ts.map +1 -1
  38. package/dist/cabinet/tool.js +22 -24
  39. package/dist/cabinet/wall-snap.d.ts.map +1 -1
  40. package/dist/cabinet/wall-snap.js +8 -8
  41. package/dist/ceiling/boundary-editor.d.ts.map +1 -1
  42. package/dist/ceiling/boundary-editor.js +5 -3
  43. package/dist/ceiling/definition.d.ts +4 -4
  44. package/dist/ceiling/definition.d.ts.map +1 -1
  45. package/dist/ceiling/definition.js +15 -15
  46. package/dist/ceiling/floorplan-affordances.d.ts +84 -4
  47. package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
  48. package/dist/ceiling/floorplan-affordances.js +0 -1
  49. package/dist/ceiling/floorplan-move.d.ts.map +1 -1
  50. package/dist/ceiling/floorplan-move.js +0 -1
  51. package/dist/ceiling/floorplan.d.ts +1 -1
  52. package/dist/ceiling/floorplan.d.ts.map +1 -1
  53. package/dist/ceiling/floorplan.js +2 -1
  54. package/dist/ceiling/height-bounds.d.ts +19 -0
  55. package/dist/ceiling/height-bounds.d.ts.map +1 -0
  56. package/dist/ceiling/height-bounds.js +24 -0
  57. package/dist/ceiling/hole-editor.d.ts.map +1 -1
  58. package/dist/ceiling/hole-editor.js +3 -4
  59. package/dist/ceiling/materials.d.ts +1 -1
  60. package/dist/ceiling/materials.d.ts.map +1 -1
  61. package/dist/ceiling/materials.js +10 -3
  62. package/dist/ceiling/paint.d.ts +2 -8
  63. package/dist/ceiling/paint.d.ts.map +1 -1
  64. package/dist/ceiling/paint.js +121 -24
  65. package/dist/ceiling/panel.d.ts.map +1 -1
  66. package/dist/ceiling/panel.js +40 -23
  67. package/dist/ceiling/renderer.d.ts.map +1 -1
  68. package/dist/ceiling/renderer.js +41 -5
  69. package/dist/chimney/move-tool.d.ts.map +1 -1
  70. package/dist/chimney/move-tool.js +8 -2
  71. package/dist/chimney/paint.d.ts.map +1 -1
  72. package/dist/chimney/paint.js +3 -10
  73. package/dist/column/definition.d.ts.map +1 -1
  74. package/dist/column/definition.js +24 -2
  75. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  76. package/dist/column/floorplan-affordances.js +5 -0
  77. package/dist/column/floorplan.d.ts +1 -1
  78. package/dist/column/floorplan.d.ts.map +1 -1
  79. package/dist/column/floorplan.js +47 -2
  80. package/dist/column/hosted-resize.d.ts +101 -2
  81. package/dist/column/hosted-resize.d.ts.map +1 -1
  82. package/dist/column/panel.d.ts.map +1 -1
  83. package/dist/column/panel.js +147 -146
  84. package/dist/column/renderer.d.ts.map +1 -1
  85. package/dist/column/renderer.js +6 -4
  86. package/dist/column/surface.d.ts.map +1 -1
  87. package/dist/column/surface.js +7 -0
  88. package/dist/construction-dimension/floorplan.js +7 -3
  89. package/dist/cupola/definition.d.ts.map +1 -1
  90. package/dist/cupola/definition.js +2 -8
  91. package/dist/cupola/panel.d.ts.map +1 -1
  92. package/dist/cupola/panel.js +5 -23
  93. package/dist/door/definition.d.ts.map +1 -1
  94. package/dist/door/definition.js +12 -3
  95. package/dist/door/door-math.d.ts +5 -10
  96. package/dist/door/door-math.d.ts.map +1 -1
  97. package/dist/door/door-math.js +14 -15
  98. package/dist/door/floorplan-move.d.ts.map +1 -1
  99. package/dist/door/floorplan-move.js +3 -1
  100. package/dist/door/floorplan.d.ts.map +1 -1
  101. package/dist/door/floorplan.js +55 -21
  102. package/dist/door/mechanism.d.ts +4 -0
  103. package/dist/door/mechanism.d.ts.map +1 -0
  104. package/dist/door/mechanism.js +24 -0
  105. package/dist/door/move-tool.d.ts.map +1 -1
  106. package/dist/door/move-tool.js +72 -48
  107. package/dist/door/paint.d.ts.map +1 -1
  108. package/dist/door/paint.js +3 -0
  109. package/dist/door/panel.d.ts.map +1 -1
  110. package/dist/door/panel.js +34 -259
  111. package/dist/door/placement.d.ts +45 -0
  112. package/dist/door/placement.d.ts.map +1 -0
  113. package/dist/door/placement.js +51 -0
  114. package/dist/door/preview.d.ts.map +1 -1
  115. package/dist/door/preview.js +2 -0
  116. package/dist/door/renderer.d.ts.map +1 -1
  117. package/dist/door/renderer.js +3 -2
  118. package/dist/door/tool.d.ts.map +1 -1
  119. package/dist/door/tool.js +92 -21
  120. package/dist/dormer/csg-geometry.d.ts.map +1 -1
  121. package/dist/dormer/csg-geometry.js +2 -0
  122. package/dist/dormer/paint.d.ts.map +1 -1
  123. package/dist/dormer/paint.js +2 -5
  124. package/dist/dormer/panel.d.ts.map +1 -1
  125. package/dist/dormer/panel.js +4 -14
  126. package/dist/downspout/definition.d.ts.map +1 -1
  127. package/dist/downspout/definition.js +2 -2
  128. package/dist/duct-fitting/definition.d.ts.map +1 -1
  129. package/dist/duct-fitting/definition.js +2 -1
  130. package/dist/duct-fitting/geometry.d.ts.map +1 -1
  131. package/dist/duct-fitting/geometry.js +1 -1
  132. package/dist/duct-fitting/move-tool.d.ts.map +1 -1
  133. package/dist/duct-fitting/move-tool.js +8 -2
  134. package/dist/duct-segment/definition.d.ts.map +1 -1
  135. package/dist/duct-segment/definition.js +2 -2
  136. package/dist/duct-segment/geometry.d.ts.map +1 -1
  137. package/dist/duct-segment/geometry.js +1 -1
  138. package/dist/duct-segment/move-tool.d.ts.map +1 -1
  139. package/dist/duct-segment/move-tool.js +8 -2
  140. package/dist/elevator/definition.d.ts.map +1 -1
  141. package/dist/elevator/definition.js +1 -2
  142. package/dist/elevator/panel.d.ts.map +1 -1
  143. package/dist/elevator/panel.js +5 -27
  144. package/dist/elevator/parametrics.js +1 -1
  145. package/dist/elevator/renderer.d.ts.map +1 -1
  146. package/dist/elevator/renderer.js +3 -4
  147. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  148. package/dist/eyebrow-vent/definition.js +2 -5
  149. package/dist/eyebrow-vent/paint.d.ts.map +1 -1
  150. package/dist/eyebrow-vent/paint.js +3 -6
  151. package/dist/eyebrow-vent/panel.d.ts.map +1 -1
  152. package/dist/eyebrow-vent/panel.js +5 -23
  153. package/dist/fence/actions/move-endpoint.d.ts +1 -1
  154. package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
  155. package/dist/fence/actions/move-endpoint.js +2 -1
  156. package/dist/fence/definition.d.ts +2 -1
  157. package/dist/fence/definition.d.ts.map +1 -1
  158. package/dist/fence/definition.js +83 -28
  159. package/dist/fence/drafting.d.ts +36 -0
  160. package/dist/fence/drafting.d.ts.map +1 -0
  161. package/dist/fence/drafting.js +210 -0
  162. package/dist/fence/feature-tool.d.ts +4 -0
  163. package/dist/fence/feature-tool.d.ts.map +1 -0
  164. package/dist/fence/feature-tool.js +140 -0
  165. package/dist/fence/features.d.ts +2 -0
  166. package/dist/fence/features.d.ts.map +1 -0
  167. package/dist/fence/features.js +12 -0
  168. package/dist/fence/floorplan-affordances.d.ts.map +1 -1
  169. package/dist/fence/floorplan-affordances.js +2 -1
  170. package/dist/fence/floorplan.d.ts +2 -3
  171. package/dist/fence/floorplan.d.ts.map +1 -1
  172. package/dist/fence/floorplan.js +131 -71
  173. package/dist/fence/geometry-parts.d.ts +50 -0
  174. package/dist/fence/geometry-parts.d.ts.map +1 -0
  175. package/dist/fence/geometry-parts.js +1144 -0
  176. package/dist/fence/geometry.d.ts +2 -3
  177. package/dist/fence/geometry.d.ts.map +1 -1
  178. package/dist/fence/geometry.js +84 -7
  179. package/dist/fence/index.d.ts +1 -0
  180. package/dist/fence/index.d.ts.map +1 -1
  181. package/dist/fence/index.js +1 -0
  182. package/dist/fence/inspector-editors.d.ts +15 -0
  183. package/dist/fence/inspector-editors.d.ts.map +1 -1
  184. package/dist/fence/inspector-editors.js +128 -3
  185. package/dist/fence/lift.d.ts.map +1 -1
  186. package/dist/fence/lift.js +5 -2
  187. package/dist/fence/move-tool.js +2 -1
  188. package/dist/fence/panel-model.d.ts +4 -0
  189. package/dist/fence/panel-model.d.ts.map +1 -0
  190. package/dist/fence/panel-model.js +12 -0
  191. package/dist/fence/parametrics.d.ts +0 -12
  192. package/dist/fence/parametrics.d.ts.map +1 -1
  193. package/dist/fence/parametrics.js +185 -18
  194. package/dist/fence/system.d.ts.map +1 -1
  195. package/dist/fence/system.js +141 -31
  196. package/dist/fence/tool.d.ts.map +1 -1
  197. package/dist/fence/tool.js +256 -47
  198. package/dist/fence-feature/actions.d.ts +7 -0
  199. package/dist/fence-feature/actions.d.ts.map +1 -0
  200. package/dist/fence-feature/actions.js +26 -0
  201. package/dist/fence-feature/definition.d.ts +4 -0
  202. package/dist/fence-feature/definition.d.ts.map +1 -0
  203. package/dist/fence-feature/definition.js +112 -0
  204. package/dist/fence-feature/floorplan-affordances.d.ts +3 -0
  205. package/dist/fence-feature/floorplan-affordances.d.ts.map +1 -0
  206. package/dist/fence-feature/floorplan-affordances.js +37 -0
  207. package/dist/fence-feature/floorplan.d.ts +4 -0
  208. package/dist/fence-feature/floorplan.d.ts.map +1 -0
  209. package/dist/fence-feature/floorplan.js +120 -0
  210. package/dist/fence-feature/geometry.d.ts +5 -0
  211. package/dist/fence-feature/geometry.d.ts.map +1 -0
  212. package/dist/fence-feature/geometry.js +43 -0
  213. package/dist/fence-feature/handles.d.ts +5 -0
  214. package/dist/fence-feature/handles.d.ts.map +1 -0
  215. package/dist/fence-feature/handles.js +84 -0
  216. package/dist/fence-feature/inspector.d.ts +6 -0
  217. package/dist/fence-feature/inspector.d.ts.map +1 -0
  218. package/dist/fence-feature/inspector.js +214 -0
  219. package/dist/fence-feature/interaction.d.ts +3 -0
  220. package/dist/fence-feature/interaction.d.ts.map +1 -0
  221. package/dist/fence-feature/interaction.js +41 -0
  222. package/dist/fence-feature/move-session.d.ts +9 -0
  223. package/dist/fence-feature/move-session.d.ts.map +1 -0
  224. package/dist/fence-feature/move-session.js +48 -0
  225. package/dist/fence-feature/move-tool.d.ts +5 -0
  226. package/dist/fence-feature/move-tool.d.ts.map +1 -0
  227. package/dist/fence-feature/move-tool.js +58 -0
  228. package/dist/fence-feature/pick-target.d.ts +7 -0
  229. package/dist/fence-feature/pick-target.d.ts.map +1 -0
  230. package/dist/fence-feature/pick-target.js +52 -0
  231. package/dist/floor-opening/definition.d.ts +3 -0
  232. package/dist/floor-opening/definition.d.ts.map +1 -0
  233. package/dist/floor-opening/definition.js +41 -0
  234. package/dist/floor-opening/floorplan.d.ts +156 -0
  235. package/dist/floor-opening/floorplan.d.ts.map +1 -0
  236. package/dist/floor-opening/floorplan.js +63 -0
  237. package/dist/gutter/definition.d.ts.map +1 -1
  238. package/dist/gutter/definition.js +2 -2
  239. package/dist/imported-mesh/definition.d.ts.map +1 -1
  240. package/dist/imported-mesh/definition.js +2 -0
  241. package/dist/imported-mesh/geometry.d.ts +1 -1
  242. package/dist/imported-mesh/geometry.d.ts.map +1 -1
  243. package/dist/imported-mesh/geometry.js +40 -12
  244. package/dist/index.d.ts +13 -2
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +20 -2
  247. package/dist/item/authored-face-host.d.ts +10 -0
  248. package/dist/item/authored-face-host.d.ts.map +1 -0
  249. package/dist/item/authored-face-host.js +87 -0
  250. package/dist/item/authored-params.d.ts +15 -0
  251. package/dist/item/authored-params.d.ts.map +1 -0
  252. package/dist/item/authored-params.js +72 -0
  253. package/dist/item/definition.d.ts +2 -2
  254. package/dist/item/definition.d.ts.map +1 -1
  255. package/dist/item/definition.js +33 -4
  256. package/dist/item/floorplan.d.ts +1 -1
  257. package/dist/item/floorplan.d.ts.map +1 -1
  258. package/dist/item/floorplan.js +35 -5
  259. package/dist/item/index.d.ts +1 -0
  260. package/dist/item/index.d.ts.map +1 -1
  261. package/dist/item/index.js +1 -0
  262. package/dist/item/model-loader.d.ts +2 -0
  263. package/dist/item/model-loader.d.ts.map +1 -1
  264. package/dist/item/model-loader.js +55 -23
  265. package/dist/item/move-tool.js +4 -4
  266. package/dist/item/paint.d.ts.map +1 -1
  267. package/dist/item/paint.js +5 -24
  268. package/dist/item/panel.d.ts +1 -3
  269. package/dist/item/panel.d.ts.map +1 -1
  270. package/dist/item/panel.js +20 -24
  271. package/dist/item/placement-notice.d.ts +14 -0
  272. package/dist/item/placement-notice.d.ts.map +1 -0
  273. package/dist/item/placement-notice.js +38 -0
  274. package/dist/item/plan-symbols.d.ts +67 -0
  275. package/dist/item/plan-symbols.d.ts.map +1 -0
  276. package/dist/item/plan-symbols.js +407 -0
  277. package/dist/item/renderer.d.ts +10 -0
  278. package/dist/item/renderer.d.ts.map +1 -1
  279. package/dist/item/renderer.js +64 -38
  280. package/dist/item/script-param-defaults.d.ts +12 -0
  281. package/dist/item/script-param-defaults.d.ts.map +1 -0
  282. package/dist/item/script-param-defaults.js +34 -0
  283. package/dist/lean-to-extension/definition.d.ts.map +1 -1
  284. package/dist/lean-to-extension/definition.js +1 -2
  285. package/dist/lean-to-extension/geometry.d.ts.map +1 -1
  286. package/dist/lean-to-extension/geometry.js +1 -1
  287. package/dist/lean-to-extension/layout.d.ts.map +1 -1
  288. package/dist/lean-to-extension/layout.js +2 -3
  289. package/dist/lean-to-extension/placement-validation.d.ts.map +1 -1
  290. package/dist/lean-to-extension/placement-validation.js +5 -5
  291. package/dist/lean-to-extension/tool.d.ts.map +1 -1
  292. package/dist/lean-to-extension/tool.js +5 -5
  293. package/dist/lineset/move-tool.d.ts.map +1 -1
  294. package/dist/lineset/move-tool.js +8 -2
  295. package/dist/liquid-line/move-tool.d.ts.map +1 -1
  296. package/dist/liquid-line/move-tool.js +8 -2
  297. package/dist/measurement/definition.js +1 -1
  298. package/dist/pipe-fitting/move-tool.d.ts.map +1 -1
  299. package/dist/pipe-fitting/move-tool.js +8 -2
  300. package/dist/pipe-segment/move-tool.d.ts.map +1 -1
  301. package/dist/pipe-segment/move-tool.js +8 -2
  302. package/dist/procedural-item/animation.d.ts +8 -0
  303. package/dist/procedural-item/animation.d.ts.map +1 -0
  304. package/dist/procedural-item/animation.js +116 -0
  305. package/dist/procedural-item/definition.d.ts.map +1 -1
  306. package/dist/procedural-item/definition.js +74 -8
  307. package/dist/procedural-item/geometry.d.ts +5 -1
  308. package/dist/procedural-item/geometry.d.ts.map +1 -1
  309. package/dist/procedural-item/geometry.js +239 -15
  310. package/dist/procedural-item/renderer.d.ts.map +1 -1
  311. package/dist/procedural-item/renderer.js +272 -23
  312. package/dist/ridge-vent/panel.d.ts.map +1 -1
  313. package/dist/ridge-vent/panel.js +5 -23
  314. package/dist/ridge-vent/renderer.d.ts.map +1 -1
  315. package/dist/ridge-vent/renderer.js +9 -8
  316. package/dist/roof/definition.d.ts.map +1 -1
  317. package/dist/roof/definition.js +4 -1
  318. package/dist/roof/floorplan.d.ts +8 -0
  319. package/dist/roof/floorplan.d.ts.map +1 -1
  320. package/dist/roof/floorplan.js +194 -18
  321. package/dist/roof/panel-model.d.ts.map +1 -1
  322. package/dist/roof/panel-model.js +10 -6
  323. package/dist/roof/panel.d.ts.map +1 -1
  324. package/dist/roof/panel.js +3 -10
  325. package/dist/roof/renderer.d.ts.map +1 -1
  326. package/dist/roof/renderer.js +5 -2
  327. package/dist/roof-segment/panel.d.ts.map +1 -1
  328. package/dist/roof-segment/panel.js +5 -24
  329. package/dist/roof-segment/renderer.d.ts.map +1 -1
  330. package/dist/roof-segment/renderer.js +17 -8
  331. package/dist/separator/definition.d.ts +3 -0
  332. package/dist/separator/definition.d.ts.map +1 -0
  333. package/dist/separator/definition.js +39 -0
  334. package/dist/separator/renderer.d.ts +5 -0
  335. package/dist/separator/renderer.d.ts.map +1 -0
  336. package/dist/separator/renderer.js +36 -0
  337. package/dist/shared/duct-body-paint.d.ts +0 -4
  338. package/dist/shared/duct-body-paint.d.ts.map +1 -1
  339. package/dist/shared/duct-body-paint.js +1 -5
  340. package/dist/shared/item-interaction-actions.d.ts +6 -0
  341. package/dist/shared/item-interaction-actions.d.ts.map +1 -0
  342. package/dist/shared/item-interaction-actions.js +27 -0
  343. package/dist/shared/item-interactions.d.ts +9 -0
  344. package/dist/shared/item-interactions.d.ts.map +1 -0
  345. package/dist/shared/item-interactions.js +74 -0
  346. package/dist/shared/item-light-placement.d.ts +2 -0
  347. package/dist/shared/item-light-placement.d.ts.map +1 -0
  348. package/dist/shared/item-light-placement.js +3 -0
  349. package/dist/shared/move-roof-tool.js +2 -1
  350. package/dist/shared/node-batch/batchable.d.ts +12 -0
  351. package/dist/shared/node-batch/batchable.d.ts.map +1 -0
  352. package/dist/shared/node-batch/batchable.js +41 -0
  353. package/dist/shared/node-batch/candidates.d.ts +7 -5
  354. package/dist/shared/node-batch/candidates.d.ts.map +1 -1
  355. package/dist/shared/node-batch/candidates.js +43 -59
  356. package/dist/shared/node-batch/release.d.ts +8 -0
  357. package/dist/shared/node-batch/release.d.ts.map +1 -0
  358. package/dist/shared/node-batch/release.js +16 -0
  359. package/dist/shared/node-batch/system.d.ts.map +1 -1
  360. package/dist/shared/node-batch/system.js +17 -12
  361. package/dist/shared/node-batch/types.d.ts +4 -1
  362. package/dist/shared/node-batch/types.d.ts.map +1 -1
  363. package/dist/shared/opening-documentation.d.ts +13 -1
  364. package/dist/shared/opening-documentation.d.ts.map +1 -1
  365. package/dist/shared/opening-documentation.js +245 -59
  366. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  367. package/dist/shared/opening-guides-runtime.js +17 -14
  368. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  369. package/dist/shared/opening-placement-dimensions.js +3 -3
  370. package/dist/shared/opening-plane-offset.d.ts +23 -0
  371. package/dist/shared/opening-plane-offset.d.ts.map +1 -0
  372. package/dist/shared/opening-plane-offset.js +24 -0
  373. package/dist/shared/polygon-centroid-move.d.ts.map +1 -1
  374. package/dist/shared/polygon-centroid-move.js +4 -1
  375. package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
  376. package/dist/shared/polygon-vertex-affordance.js +19 -15
  377. package/dist/shared/run-hangers.d.ts.map +1 -1
  378. package/dist/shared/run-hangers.js +5 -4
  379. package/dist/shared/scripted-opening-handles.d.ts +18 -0
  380. package/dist/shared/scripted-opening-handles.d.ts.map +1 -0
  381. package/dist/shared/scripted-opening-handles.js +53 -0
  382. package/dist/shared/scripted-opening.d.ts +25 -0
  383. package/dist/shared/scripted-opening.d.ts.map +1 -0
  384. package/dist/shared/scripted-opening.js +72 -0
  385. package/dist/shared/slot-paint.d.ts +14 -2
  386. package/dist/shared/slot-paint.d.ts.map +1 -1
  387. package/dist/shared/slot-paint.js +29 -29
  388. package/dist/shared/surface-paint.d.ts.map +1 -1
  389. package/dist/shared/surface-paint.js +2 -5
  390. package/dist/shared/swap-preview-material.d.ts +11 -0
  391. package/dist/shared/swap-preview-material.d.ts.map +1 -0
  392. package/dist/shared/swap-preview-material.js +16 -0
  393. package/dist/shared/system-checks.d.ts.map +1 -1
  394. package/dist/shared/system-checks.js +5 -3
  395. package/dist/shared/wall-attach-target.d.ts +3 -10
  396. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  397. package/dist/shared/wall-attach-target.js +3 -63
  398. package/dist/shared/wall-opening-ceiling.d.ts +5 -15
  399. package/dist/shared/wall-opening-ceiling.d.ts.map +1 -1
  400. package/dist/shared/wall-opening-ceiling.js +10 -18
  401. package/dist/shelf/definition.d.ts.map +1 -1
  402. package/dist/shelf/definition.js +1 -1
  403. package/dist/shelf/geometry.d.ts.map +1 -1
  404. package/dist/shelf/geometry.js +1 -2
  405. package/dist/shelf/paint.d.ts.map +1 -1
  406. package/dist/shelf/paint.js +4 -10
  407. package/dist/site/line-ribbon.d.ts +31 -0
  408. package/dist/site/line-ribbon.d.ts.map +1 -0
  409. package/dist/site/line-ribbon.js +117 -0
  410. package/dist/site/lot-mask.d.ts +18 -0
  411. package/dist/site/lot-mask.d.ts.map +1 -0
  412. package/dist/site/lot-mask.js +35 -0
  413. package/dist/site/panel.d.ts +10 -0
  414. package/dist/site/panel.d.ts.map +1 -0
  415. package/dist/site/panel.js +155 -0
  416. package/dist/site/parametrics.d.ts +7 -0
  417. package/dist/site/parametrics.d.ts.map +1 -1
  418. package/dist/site/parametrics.js +8 -0
  419. package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
  420. package/dist/site/recessed-slab-ground-holes.js +5 -2
  421. package/dist/site/renderer.d.ts.map +1 -1
  422. package/dist/site/renderer.js +150 -19
  423. package/dist/site/setbacks.d.ts +33 -0
  424. package/dist/site/setbacks.d.ts.map +1 -0
  425. package/dist/site/setbacks.js +204 -0
  426. package/dist/site/terrain-geometry.d.ts +28 -1
  427. package/dist/site/terrain-geometry.d.ts.map +1 -1
  428. package/dist/site/terrain-geometry.js +78 -4
  429. package/dist/site/terrain-holes.d.ts +15 -0
  430. package/dist/site/terrain-holes.d.ts.map +1 -0
  431. package/dist/site/terrain-holes.js +74 -0
  432. package/dist/site/terrain-mesh.d.ts +9 -2
  433. package/dist/site/terrain-mesh.d.ts.map +1 -1
  434. package/dist/site/terrain-mesh.js +36 -9
  435. package/dist/site/terrain-renderer.d.ts +9 -2
  436. package/dist/site/terrain-renderer.d.ts.map +1 -1
  437. package/dist/site/terrain-renderer.js +14 -4
  438. package/dist/slab/boundary-editor.d.ts +1 -1
  439. package/dist/slab/boundary-editor.d.ts.map +1 -1
  440. package/dist/slab/boundary-editor.js +13 -13
  441. package/dist/slab/definition.d.ts.map +1 -1
  442. package/dist/slab/definition.js +19 -3
  443. package/dist/slab/dependency-tracker.d.ts.map +1 -1
  444. package/dist/slab/dependency-tracker.js +67 -7
  445. package/dist/slab/elevation-limit.d.ts.map +1 -1
  446. package/dist/slab/elevation-limit.js +2 -2
  447. package/dist/slab/floorplan-affordances.d.ts +176 -4
  448. package/dist/slab/floorplan-affordances.d.ts.map +1 -1
  449. package/dist/slab/floorplan-affordances.js +0 -1
  450. package/dist/slab/floorplan-move.d.ts.map +1 -1
  451. package/dist/slab/floorplan-move.js +3 -4
  452. package/dist/slab/floorplan.d.ts +7 -0
  453. package/dist/slab/floorplan.d.ts.map +1 -1
  454. package/dist/slab/floorplan.js +22 -5
  455. package/dist/slab/geometry.d.ts.map +1 -1
  456. package/dist/slab/geometry.js +186 -76
  457. package/dist/slab/move-tool.js +7 -6
  458. package/dist/slab/paint.d.ts +18 -5
  459. package/dist/slab/paint.d.ts.map +1 -1
  460. package/dist/slab/paint.js +458 -9
  461. package/dist/slab/panel.d.ts.map +1 -1
  462. package/dist/slab/panel.js +28 -9
  463. package/dist/slab/placement-ownership.d.ts +2 -1
  464. package/dist/slab/placement-ownership.d.ts.map +1 -1
  465. package/dist/slab/placement-ownership.js +2 -2
  466. package/dist/slab/surface-split.d.ts +24 -0
  467. package/dist/slab/surface-split.d.ts.map +1 -0
  468. package/dist/slab/surface-split.js +389 -0
  469. package/dist/slab/tool.d.ts.map +1 -1
  470. package/dist/slab/tool.js +3 -3
  471. package/dist/stair/baluster-geometry.d.ts +21 -0
  472. package/dist/stair/baluster-geometry.d.ts.map +1 -0
  473. package/dist/stair/baluster-geometry.js +74 -0
  474. package/dist/stair/baluster-guard.d.ts +50 -0
  475. package/dist/stair/baluster-guard.d.ts.map +1 -0
  476. package/dist/stair/baluster-guard.js +71 -0
  477. package/dist/stair/boards-guard.d.ts +37 -0
  478. package/dist/stair/boards-guard.d.ts.map +1 -0
  479. package/dist/stair/boards-guard.js +61 -0
  480. package/dist/stair/cable-guard.d.ts +39 -0
  481. package/dist/stair/cable-guard.d.ts.map +1 -0
  482. package/dist/stair/cable-guard.js +105 -0
  483. package/dist/stair/construction-controls.d.ts +15 -0
  484. package/dist/stair/construction-controls.d.ts.map +1 -0
  485. package/dist/stair/construction-controls.js +29 -0
  486. package/dist/stair/continuous-railings.d.ts +10 -0
  487. package/dist/stair/continuous-railings.d.ts.map +1 -0
  488. package/dist/stair/continuous-railings.js +159 -0
  489. package/dist/stair/definition.d.ts.map +1 -1
  490. package/dist/stair/definition.js +16 -37
  491. package/dist/stair/documentation.d.ts +1 -1
  492. package/dist/stair/documentation.d.ts.map +1 -1
  493. package/dist/stair/documentation.js +10 -17
  494. package/dist/stair/floorplan-affordances.d.ts.map +1 -1
  495. package/dist/stair/floorplan-affordances.js +9 -25
  496. package/dist/stair/floorplan.d.ts +1 -23
  497. package/dist/stair/floorplan.d.ts.map +1 -1
  498. package/dist/stair/floorplan.js +102 -86
  499. package/dist/stair/glass-guard.d.ts +72 -0
  500. package/dist/stair/glass-guard.d.ts.map +1 -0
  501. package/dist/stair/glass-guard.js +167 -0
  502. package/dist/stair/guard-path.d.ts +119 -0
  503. package/dist/stair/guard-path.d.ts.map +1 -0
  504. package/dist/stair/guard-path.js +208 -0
  505. package/dist/stair/materials.d.ts +11 -0
  506. package/dist/stair/materials.d.ts.map +1 -0
  507. package/dist/stair/materials.js +51 -0
  508. package/dist/stair/metal-guard.d.ts +38 -0
  509. package/dist/stair/metal-guard.d.ts.map +1 -0
  510. package/dist/stair/metal-guard.js +79 -0
  511. package/dist/stair/paint.d.ts +32 -0
  512. package/dist/stair/paint.d.ts.map +1 -1
  513. package/dist/stair/paint.js +75 -36
  514. package/dist/stair/panel.d.ts.map +1 -1
  515. package/dist/stair/panel.js +154 -17
  516. package/dist/stair/parametrics.d.ts +1 -1
  517. package/dist/stair/parametrics.d.ts.map +1 -1
  518. package/dist/stair/parametrics.js +32 -15
  519. package/dist/stair/plan-entry.d.ts +31 -0
  520. package/dist/stair/plan-entry.d.ts.map +1 -0
  521. package/dist/stair/plan-entry.js +325 -0
  522. package/dist/stair/post-and-rail-guard.d.ts +31 -0
  523. package/dist/stair/post-and-rail-guard.d.ts.map +1 -0
  524. package/dist/stair/post-and-rail-guard.js +63 -0
  525. package/dist/stair/railing-controls.d.ts +9 -0
  526. package/dist/stair/railing-controls.d.ts.map +1 -0
  527. package/dist/stair/railing-controls.js +49 -0
  528. package/dist/stair/renderer.d.ts.map +1 -1
  529. package/dist/stair/renderer.js +259 -259
  530. package/dist/stair/use-stair-render-data.d.ts +317 -0
  531. package/dist/stair/use-stair-render-data.d.ts.map +1 -0
  532. package/dist/stair/use-stair-render-data.js +73 -0
  533. package/dist/stair-segment/definition.d.ts.map +1 -1
  534. package/dist/stair-segment/definition.js +51 -10
  535. package/dist/stair-segment/panel.d.ts.map +1 -1
  536. package/dist/stair-segment/panel.js +36 -42
  537. package/dist/stair-segment/parametrics.d.ts +1 -1
  538. package/dist/stair-segment/parametrics.d.ts.map +1 -1
  539. package/dist/stair-segment/parametrics.js +21 -8
  540. package/dist/stair-segment/renderer.d.ts.map +1 -1
  541. package/dist/stair-segment/renderer.js +16 -28
  542. package/dist/turbine-vent/definition.d.ts.map +1 -1
  543. package/dist/turbine-vent/definition.js +2 -5
  544. package/dist/turbine-vent/paint.d.ts.map +1 -1
  545. package/dist/turbine-vent/paint.js +2 -5
  546. package/dist/turbine-vent/panel.d.ts.map +1 -1
  547. package/dist/turbine-vent/panel.js +5 -23
  548. package/dist/unit/unit-panel.d.ts.map +1 -1
  549. package/dist/unit/unit-panel.js +6 -1
  550. package/dist/wall/actions.d.ts.map +1 -1
  551. package/dist/wall/actions.js +7 -2
  552. package/dist/wall/construction-dimensions.js +8 -5
  553. package/dist/wall/contextual-dimensions.js +4 -4
  554. package/dist/wall/curtain-wall-materials.d.ts +1 -1
  555. package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
  556. package/dist/wall/curtain-wall-materials.js +2 -2
  557. package/dist/wall/curve-tool.d.ts.map +1 -1
  558. package/dist/wall/curve-tool.js +4 -0
  559. package/dist/wall/definition.d.ts.map +1 -1
  560. package/dist/wall/definition.js +41 -17
  561. package/dist/wall/floorplan-move.d.ts +1 -1
  562. package/dist/wall/floorplan-move.d.ts.map +1 -1
  563. package/dist/wall/floorplan-move.js +20 -83
  564. package/dist/wall/floorplan-tool.d.ts.map +1 -1
  565. package/dist/wall/floorplan-tool.js +10 -11
  566. package/dist/wall/floorplan.d.ts +3 -1
  567. package/dist/wall/floorplan.d.ts.map +1 -1
  568. package/dist/wall/floorplan.js +184 -21
  569. package/dist/wall/measurement.d.ts.map +1 -1
  570. package/dist/wall/measurement.js +5 -5
  571. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  572. package/dist/wall/move-endpoint-tool.js +20 -7
  573. package/dist/wall/move-shared.d.ts.map +1 -1
  574. package/dist/wall/move-shared.js +11 -7
  575. package/dist/wall/move-tool.d.ts.map +1 -1
  576. package/dist/wall/move-tool.js +118 -148
  577. package/dist/wall/paint.d.ts +26 -15
  578. package/dist/wall/paint.d.ts.map +1 -1
  579. package/dist/wall/paint.js +306 -117
  580. package/dist/wall/panel-model.d.ts +18 -0
  581. package/dist/wall/panel-model.d.ts.map +1 -1
  582. package/dist/wall/panel-model.js +77 -19
  583. package/dist/wall/panel.d.ts.map +1 -1
  584. package/dist/wall/panel.js +217 -41
  585. package/dist/wall/parametrics.d.ts.map +1 -1
  586. package/dist/wall/parametrics.js +3 -0
  587. package/dist/wall/rectangle-command.d.ts +111 -12
  588. package/dist/wall/rectangle-command.d.ts.map +1 -1
  589. package/dist/wall/rectangle-tool.d.ts.map +1 -1
  590. package/dist/wall/rectangle-tool.js +26 -8
  591. package/dist/wall/renderer.d.ts.map +1 -1
  592. package/dist/wall/renderer.js +4 -2
  593. package/dist/wall/split-floorplan-layer.d.ts.map +1 -1
  594. package/dist/wall/split-floorplan-layer.js +7 -7
  595. package/dist/wall/split-session.d.ts.map +1 -1
  596. package/dist/wall/split-session.js +7 -1
  597. package/dist/wall/system.d.ts.map +1 -1
  598. package/dist/wall/system.js +36 -4
  599. package/dist/wall/tool.d.ts.map +1 -1
  600. package/dist/wall/tool.js +105 -49
  601. package/dist/wall/treatment-level-data.d.ts +3 -2
  602. package/dist/wall/treatment-level-data.d.ts.map +1 -1
  603. package/dist/wall/treatment-level-data.js +17 -13
  604. package/dist/wall/treatments.d.ts +10 -10
  605. package/dist/wall/treatments.d.ts.map +1 -1
  606. package/dist/wall/treatments.js +67 -54
  607. package/dist/wall/wall-batch-system.d.ts +7 -0
  608. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  609. package/dist/wall/wall-batch-system.js +35 -3
  610. package/dist/wall/wall-batch.d.ts +6 -0
  611. package/dist/wall/wall-batch.d.ts.map +1 -1
  612. package/dist/wall/wall-batch.js +7 -1
  613. package/dist/window/definition.d.ts.map +1 -1
  614. package/dist/window/definition.js +12 -4
  615. package/dist/window/floorplan-move.d.ts.map +1 -1
  616. package/dist/window/floorplan-move.js +3 -1
  617. package/dist/window/floorplan.d.ts.map +1 -1
  618. package/dist/window/floorplan.js +145 -60
  619. package/dist/window/mechanism.d.ts +4 -0
  620. package/dist/window/mechanism.d.ts.map +1 -0
  621. package/dist/window/mechanism.js +20 -0
  622. package/dist/window/move-tool.d.ts.map +1 -1
  623. package/dist/window/move-tool.js +79 -48
  624. package/dist/window/paint.d.ts.map +1 -1
  625. package/dist/window/paint.js +3 -0
  626. package/dist/window/panel.d.ts.map +1 -1
  627. package/dist/window/panel.js +32 -88
  628. package/dist/window/placement.d.ts +23 -0
  629. package/dist/window/placement.d.ts.map +1 -0
  630. package/dist/window/placement.js +66 -0
  631. package/dist/window/preview.d.ts.map +1 -1
  632. package/dist/window/preview.js +2 -0
  633. package/dist/window/renderer.d.ts.map +1 -1
  634. package/dist/window/renderer.js +3 -2
  635. package/dist/window/tool.d.ts.map +1 -1
  636. package/dist/window/tool.js +96 -24
  637. package/dist/window/window-math.d.ts +6 -14
  638. package/dist/window/window-math.d.ts.map +1 -1
  639. package/dist/window/window-math.js +14 -20
  640. package/dist/zone/contextual-dimensions.d.ts.map +1 -1
  641. package/dist/zone/contextual-dimensions.js +6 -28
  642. package/dist/zone/definition.d.ts.map +1 -1
  643. package/dist/zone/definition.js +3 -3
  644. package/dist/zone/floorplan-affordances.d.ts +200 -0
  645. package/dist/zone/floorplan-affordances.d.ts.map +1 -1
  646. package/dist/zone/floorplan.d.ts +1 -1
  647. package/dist/zone/floorplan.d.ts.map +1 -1
  648. package/dist/zone/floorplan.js +93 -53
  649. package/dist/zone/quantities-panel.d.ts.map +1 -1
  650. package/dist/zone/quantities-panel.js +3 -14
  651. package/dist/zone/quick-measurement.d.ts +2 -2
  652. package/dist/zone/quick-measurement.d.ts.map +1 -1
  653. package/dist/zone/quick-measurement.js +6 -5
  654. package/dist/zone/renderer.d.ts +1 -1
  655. package/dist/zone/renderer.d.ts.map +1 -1
  656. package/dist/zone/renderer.js +58 -146
  657. package/dist/zone/room-clear-dimensions.js +3 -3
  658. package/dist/zone/room-documentation.d.ts.map +1 -1
  659. package/dist/zone/room-documentation.js +2 -6
  660. package/package.json +11 -11
  661. package/dist/block/slots.d.ts +0 -4
  662. package/dist/block/slots.d.ts.map +0 -1
  663. package/dist/block/slots.js +0 -17
  664. package/dist/cabinet/slots.d.ts +0 -4
  665. package/dist/cabinet/slots.d.ts.map +0 -1
  666. package/dist/cabinet/slots.js +0 -24
  667. package/dist/ceiling/slots.d.ts +0 -6
  668. package/dist/ceiling/slots.d.ts.map +0 -1
  669. package/dist/ceiling/slots.js +0 -7
  670. package/dist/column/slots.d.ts +0 -9
  671. package/dist/column/slots.d.ts.map +0 -1
  672. package/dist/column/slots.js +0 -19
  673. package/dist/door/slots.d.ts +0 -9
  674. package/dist/door/slots.d.ts.map +0 -1
  675. package/dist/door/slots.js +0 -20
  676. package/dist/elevator/slots.d.ts +0 -8
  677. package/dist/elevator/slots.d.ts.map +0 -1
  678. package/dist/elevator/slots.js +0 -17
  679. package/dist/fence/slots.d.ts +0 -10
  680. package/dist/fence/slots.d.ts.map +0 -1
  681. package/dist/fence/slots.js +0 -23
  682. package/dist/item/__fixtures__/main-floorplan.d.ts +0 -26
  683. package/dist/item/__fixtures__/main-floorplan.d.ts.map +0 -1
  684. package/dist/item/__fixtures__/main-floorplan.js +0 -297
  685. package/dist/lean-to-extension/slots.d.ts +0 -5
  686. package/dist/lean-to-extension/slots.d.ts.map +0 -1
  687. package/dist/lean-to-extension/slots.js +0 -15
  688. package/dist/shelf/slots.d.ts +0 -9
  689. package/dist/shelf/slots.d.ts.map +0 -1
  690. package/dist/shelf/slots.js +0 -30
  691. package/dist/slab/slots.d.ts +0 -10
  692. package/dist/slab/slots.d.ts.map +0 -1
  693. package/dist/slab/slots.js +0 -20
  694. package/dist/stair/floor-stack.d.ts +0 -10
  695. package/dist/stair/floor-stack.d.ts.map +0 -1
  696. package/dist/stair/floor-stack.js +0 -115
  697. package/dist/stair/slots.d.ts +0 -7
  698. package/dist/stair/slots.d.ts.map +0 -1
  699. package/dist/stair/slots.js +0 -13
  700. package/dist/wall/drawing-mode.d.ts +0 -12
  701. package/dist/wall/drawing-mode.d.ts.map +0 -1
  702. package/dist/wall/drawing-mode.js +0 -38
  703. package/dist/wall/slots.d.ts +0 -10
  704. package/dist/wall/slots.d.ts.map +0 -1
  705. package/dist/wall/slots.js +0 -92
  706. package/dist/window/slots.d.ts +0 -5
  707. package/dist/window/slots.d.ts.map +0 -1
  708. package/dist/window/slots.js +0 -11
@@ -0,0 +1,37 @@
1
+ /**
2
+ * One coherent board-infill deck guard laid out along a rail path, as oriented
3
+ * boxes — the AWC Deck Construction Guide (DCA 6) solid-board guard in metres: a
4
+ * 4x4 post at each end (and every bay ≤ 4 ft between), a flat 2x6 cap over them,
5
+ * and a stack of 1x6 boards running flat along the path between the nosing line
6
+ * and the cap, each course held off the one below by a consistent gap. Every
7
+ * member — the cap and every board course — follows the same path and gets a
8
+ * fitting block at a real plan corner, so the courses read as one connected
9
+ * panel that turns cleanly rather than butting open-ended at a corner.
10
+ *
11
+ * It shares the path sampling, corner finding and newel stations in
12
+ * `guard-path.ts` with the baluster and post-and-rail guards, so a straight
13
+ * flight, a chained L/U landing turn, a winder, a curved or spiral sweep and an
14
+ * integrated top landing all read as the same guard; only the sections and the
15
+ * horizontal board infill differ. Pure data — no Three.js, no React.
16
+ *
17
+ * `reach` runs the members that far past the top vertex along the final slope to
18
+ * die into a post standing there; `topPost: false` then omits the top post.
19
+ * `postThrough` runs the posts past the cap with a small cap of their own.
20
+ */
21
+ import { type GuardBox, type GuardRail, type Vec3 } from './guard-path';
22
+ export type BoardsGuardOptions = {
23
+ railHeight: number;
24
+ /** Metres between posts along the run; omit (or Infinity) for ends only. */
25
+ postSpacing?: number;
26
+ topPost?: boolean;
27
+ postThrough?: boolean;
28
+ /** Metres the members run past the top vertex, along the final slope. */
29
+ reach?: number;
30
+ };
31
+ /** The board guard's members, bottom-to-top: a stack of 1x6 board courses held
32
+ * off the nosing line by `BOARD_GAP`, then the flat 2x6 cap. Each is a rail that
33
+ * follows the path, so a corner gets a fitting block per course. Shared with the
34
+ * flight connector so a bridge carries the same courses as the guards it joins. */
35
+ export declare function boardsGuardRails(railHeight: number): GuardRail[];
36
+ export declare function buildBoardsGuard(points: Vec3[], options: BoardsGuardOptions): GuardBox[];
37
+ //# sourceMappingURL=boards-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boards-guard.d.ts","sourceRoot":"","sources":["../../src/stair/boards-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAE,MAAM,cAAc,CAAA;AAE1F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAcD;;;mFAGmF;AACnF,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CAWhE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,QAAQ,EAAE,CAqBxF"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * One coherent board-infill deck guard laid out along a rail path, as oriented
3
+ * boxes — the AWC Deck Construction Guide (DCA 6) solid-board guard in metres: a
4
+ * 4x4 post at each end (and every bay ≤ 4 ft between), a flat 2x6 cap over them,
5
+ * and a stack of 1x6 boards running flat along the path between the nosing line
6
+ * and the cap, each course held off the one below by a consistent gap. Every
7
+ * member — the cap and every board course — follows the same path and gets a
8
+ * fitting block at a real plan corner, so the courses read as one connected
9
+ * panel that turns cleanly rather than butting open-ended at a corner.
10
+ *
11
+ * It shares the path sampling, corner finding and newel stations in
12
+ * `guard-path.ts` with the baluster and post-and-rail guards, so a straight
13
+ * flight, a chained L/U landing turn, a winder, a curved or spiral sweep and an
14
+ * integrated top landing all read as the same guard; only the sections and the
15
+ * horizontal board infill differ. Pure data — no Three.js, no React.
16
+ *
17
+ * `reach` runs the members that far past the top vertex along the final slope to
18
+ * die into a post standing there; `topPost: false` then omits the top post.
19
+ * `postThrough` runs the posts past the cap with a small cap of their own.
20
+ */
21
+ import { buildGuardChassis } from './guard-path';
22
+ // Dressed deck lumber, in metres.
23
+ const POST = 0.0889; // 4x4
24
+ const POST_EMBED = 0.05; // the post foot runs this far below the nosing line
25
+ const CAP_W = 0.1397; // 2x6 cap, laid flat
26
+ const CAP_T = 0.0381;
27
+ const BOARD_W = 0.019; // 1x6 board on the flat: thin across the run
28
+ const BOARD_D = 0.1397; // its vertical face height
29
+ const BOARD_GAP = 0.0889; // clear gap below the lowest board and between courses
30
+ const POST_ABOVE_CAP = 0.0762; // a through-post stands this far above the cap…
31
+ const POST_CAP_T = 0.0254; // …under a 1 in cap of its own
32
+ const POST_CAP_OVERHANG = 0.0508;
33
+ /** The board guard's members, bottom-to-top: a stack of 1x6 board courses held
34
+ * off the nosing line by `BOARD_GAP`, then the flat 2x6 cap. Each is a rail that
35
+ * follows the path, so a corner gets a fitting block per course. Shared with the
36
+ * flight connector so a bridge carries the same courses as the guards it joins. */
37
+ export function boardsGuardRails(railHeight) {
38
+ const rails = [];
39
+ const capUnderside = railHeight - CAP_T;
40
+ for (let bottom = BOARD_GAP; bottom + BOARD_D <= capUnderside + 1e-6; bottom += BOARD_D + BOARD_GAP)
41
+ rails.push({ y: bottom + BOARD_D / 2, across: BOARD_W, vertical: BOARD_D });
42
+ rails.push({ y: railHeight - CAP_T / 2, across: CAP_W, vertical: CAP_T });
43
+ return rails;
44
+ }
45
+ export function buildBoardsGuard(points, options) {
46
+ const { railHeight } = options;
47
+ const chassis = buildGuardChassis(points, options, boardsGuardRails(railHeight), {
48
+ width: POST,
49
+ embed: POST_EMBED,
50
+ top: -CAP_T,
51
+ throughTop: POST_ABOVE_CAP,
52
+ capThickness: POST_CAP_T,
53
+ capOverhang: POST_CAP_OVERHANG,
54
+ }, {});
55
+ if (!chassis)
56
+ return [];
57
+ const { path, boxes } = chassis;
58
+ if (path.kind === 'pivot')
59
+ return boxes;
60
+ return boxes;
61
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * One coherent cable guard laid out along a rail path, as oriented boxes — the
3
+ * modern metal cable rail in metres: a slim square post at each end (and every
4
+ * bay ≤ 4 ft between), a flat cap rail following the path over them, and
5
+ * slender round cables run as straight spans from post to post, with a short
6
+ * swage sleeve where each cable dies into a terminal post. It shares the path
7
+ * sampling, corner finding and newel/picket stations in `guard-path.ts` with
8
+ * the baluster and deck post-and-rail guards, so a straight flight, a chained
9
+ * L/U landing turn, a winder, a curved or spiral sweep and an integrated top
10
+ * landing all read as the same cable rail; only the sections and the infill
11
+ * differ. Pure data — no Three.js, no React.
12
+ *
13
+ * The cables are the physical intent of a cable rail, not a fiction: real cable
14
+ * is pulled taut, so on a curved or spiral sweep it cannot follow the arc. Each
15
+ * cable level is therefore a run of straight chords between consecutive posts
16
+ * (the posts are the support stations, spaced by run and so independent of the
17
+ * tread count), while the cap rail follows the curve. On a straight flight the
18
+ * collinear posts make those chords read as one line.
19
+ *
20
+ * `reach` runs the cap and the top cables that far past the top vertex along
21
+ * the final slope to die into a post standing there; `topPost: false` then
22
+ * omits the top post. `postThrough` runs the posts past the cap with a small
23
+ * cap of their own.
24
+ */
25
+ import { type GuardBox, type GuardRail, type Vec3 } from './guard-path';
26
+ export type CableGuardOptions = {
27
+ railHeight: number;
28
+ /** Metres between posts along the run; omit (or Infinity) for ends only. */
29
+ postSpacing?: number;
30
+ topPost?: boolean;
31
+ postThrough?: boolean;
32
+ /** Metres the rails run past the top vertex, along the final slope. */
33
+ reach?: number;
34
+ };
35
+ /** The cable guard's single flat cap rail. Shared with the flight connector so
36
+ * a bridge between flights carries the same cap as the guards it joins. */
37
+ export declare function cableGuardRails(railHeight: number): GuardRail[];
38
+ export declare function buildCableGuard(points: Vec3[], options: CableGuardOptions): GuardBox[];
39
+ //# sourceMappingURL=cable-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cable-guard.d.ts","sourceRoot":"","sources":["../../src/stair/cable-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,SAAS,EAGd,KAAK,IAAI,EACV,MAAM,cAAc,CAAA;AAErB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAiBD;2EAC2E;AAC3E,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,CAE/D;AAUD,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,QAAQ,EAAE,CAkDtF"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * One coherent cable guard laid out along a rail path, as oriented boxes — the
3
+ * modern metal cable rail in metres: a slim square post at each end (and every
4
+ * bay ≤ 4 ft between), a flat cap rail following the path over them, and
5
+ * slender round cables run as straight spans from post to post, with a short
6
+ * swage sleeve where each cable dies into a terminal post. It shares the path
7
+ * sampling, corner finding and newel/picket stations in `guard-path.ts` with
8
+ * the baluster and deck post-and-rail guards, so a straight flight, a chained
9
+ * L/U landing turn, a winder, a curved or spiral sweep and an integrated top
10
+ * landing all read as the same cable rail; only the sections and the infill
11
+ * differ. Pure data — no Three.js, no React.
12
+ *
13
+ * The cables are the physical intent of a cable rail, not a fiction: real cable
14
+ * is pulled taut, so on a curved or spiral sweep it cannot follow the arc. Each
15
+ * cable level is therefore a run of straight chords between consecutive posts
16
+ * (the posts are the support stations, spaced by run and so independent of the
17
+ * tread count), while the cap rail follows the curve. On a straight flight the
18
+ * collinear posts make those chords read as one line.
19
+ *
20
+ * `reach` runs the cap and the top cables that far past the top vertex along
21
+ * the final slope to die into a post standing there; `topPost: false` then
22
+ * omits the top post. `postThrough` runs the posts past the cap with a small
23
+ * cap of their own.
24
+ */
25
+ import { add, barBox, buildGuardChassis, scale, sub, } from './guard-path';
26
+ // Dressed metal cable rail, in metres.
27
+ const POST = 0.0508; // a 2 in slim square post
28
+ const POST_EMBED = 0.05; // the post foot runs this far below the nosing line
29
+ const CAP_W = 0.0635; // a flat 2½ in cap over the posts
30
+ const CAP_T = 0.0381;
31
+ const CABLE_D = 0.0095; // 3⁄8 in round cable
32
+ const CABLE_PITCH = 0.0762; // 3 in on centre (IRC-style infill limit)
33
+ const CABLE_BOTTOM = 0.0762; // the lowest cable sits this far over the nosing line
34
+ const CABLE_CLEAR = 0.025; // the top cable stays this far under the cap underside
35
+ const SLEEVE_D = 0.019; // a 3⁄4 in swage sleeve at a cable's terminal post
36
+ const SLEEVE_LEN = 0.05;
37
+ const POST_ABOVE_CAP = 0.0762; // a through-post stands this far above the cap…
38
+ const POST_CAP_T = 0.0254; // …under a 1 in cap of its own
39
+ const POST_CAP_OVERHANG = 0.0381;
40
+ /** The cable guard's single flat cap rail. Shared with the flight connector so
41
+ * a bridge between flights carries the same cap as the guards it joins. */
42
+ export function cableGuardRails(railHeight) {
43
+ return [{ y: railHeight - CAP_T / 2, across: CAP_W, vertical: CAP_T }];
44
+ }
45
+ /** Cable centreline heights off the nosing line, bottom-to-top. */
46
+ function cableLevels(railHeight) {
47
+ const top = railHeight - CAP_T - CABLE_CLEAR - CABLE_D / 2;
48
+ const levels = [];
49
+ for (let y = CABLE_BOTTOM; y <= top + 1e-9; y += CABLE_PITCH)
50
+ levels.push(y);
51
+ return levels;
52
+ }
53
+ export function buildCableGuard(points, options) {
54
+ const { railHeight } = options;
55
+ const chassis = buildGuardChassis(points, options, cableGuardRails(railHeight), {
56
+ width: POST,
57
+ embed: POST_EMBED,
58
+ top: -CAP_T,
59
+ throughTop: POST_ABOVE_CAP,
60
+ capThickness: POST_CAP_T,
61
+ capOverhang: POST_CAP_OVERHANG,
62
+ }, { cornerPosts: true });
63
+ if (!chassis)
64
+ return [];
65
+ const { path, boxes } = chassis;
66
+ if (path.kind === 'pivot')
67
+ return boxes;
68
+ const { railPoints, isCorner, postPositions } = path;
69
+ // Cables: a run of straight chords between consecutive posts at each level,
70
+ // with a swage sleeve where the terminal posts anchor the ends.
71
+ const levels = cableLevels(railHeight);
72
+ for (const y of levels) {
73
+ for (let i = 1; i < postPositions.length; i++) {
74
+ const cable = barBox(add(postPositions[i - 1], [0, y, 0]), add(postPositions[i], [0, y, 0]), CABLE_D, CABLE_D);
75
+ if (cable)
76
+ boxes.push({ ...cable, round: true });
77
+ }
78
+ for (let i = 1; i < postPositions.length - 1; i++) {
79
+ const post = postPositions[i];
80
+ if (railPoints.some((point, index) => isCorner(index) && Math.hypot(...sub(point, post)) < 1e-6)) {
81
+ boxes.push(terminalSleeve(post, postPositions[i - 1], y));
82
+ boxes.push(terminalSleeve(post, postPositions[i + 1], y));
83
+ }
84
+ }
85
+ if (postPositions.length >= 2) {
86
+ boxes.push(terminalSleeve(postPositions[0], postPositions[1], y));
87
+ boxes.push(terminalSleeve(postPositions.at(-1), postPositions.at(-2), y));
88
+ }
89
+ }
90
+ return boxes;
91
+ }
92
+ /** A short round sleeve sitting at `post` at height `y`, pointing along the
93
+ * cable toward `toward` — the swage fitting that terminates a cable. */
94
+ function terminalSleeve(post, toward, y) {
95
+ const along = sub(toward, post);
96
+ const length = Math.hypot(along[0], along[1], along[2]);
97
+ const unit = length > 1e-6 ? scale(along, 1 / length) : [0, 0, 1];
98
+ const base = add(post, [0, y, 0]);
99
+ return {
100
+ center: add(base, scale(unit, SLEEVE_LEN / 2)),
101
+ size: [SLEEVE_D, SLEEVE_D, SLEEVE_LEN],
102
+ direction: unit,
103
+ round: true,
104
+ };
105
+ }
@@ -0,0 +1,15 @@
1
+ import { StairConstruction, type StairNode, type StairSegmentNode } from '@pascal-app/core';
2
+ export declare function StairConstructionControls({ node, inherited, onChange, }: {
3
+ node: StairNode | StairSegmentNode;
4
+ inherited?: StairConstruction;
5
+ onChange: (construction: StairConstruction | undefined) => void;
6
+ }): import("react").JSX.Element;
7
+ export declare function StairConstructionField({ node, onUpdate, }: {
8
+ node: StairNode;
9
+ onUpdate: (patch: Partial<StairNode>) => void;
10
+ }): import("react").JSX.Element;
11
+ export declare function StairSegmentConstructionField({ node, onUpdate, }: {
12
+ node: StairSegmentNode;
13
+ onUpdate: (patch: Partial<StairSegmentNode>) => void;
14
+ }): import("react").JSX.Element;
15
+ //# sourceMappingURL=construction-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construction-controls.d.ts","sourceRoot":"","sources":["../../src/stair/construction-controls.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,gBAAgB,EAEtB,MAAM,kBAAkB,CAAA;AAYzB,wBAAgB,yBAAyB,CAAC,EACxC,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,SAAS,GAAG,gBAAgB,CAAA;IAClC,SAAS,CAAC,EAAE,iBAAiB,CAAA;IAC7B,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,GAAG,SAAS,KAAK,IAAI,CAAA;CAChE,+BAwGA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,IAAI,CAAA;CAC9C,+BAOA;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,gBAAgB,CAAA;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;CACrD,+BAYA"}
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { StairConstruction, useScene, } from '@pascal-app/core';
4
+ import { MetricControl, SelectControl, ToggleControl } from '@pascal-app/editor';
5
+ const OPTIONS = [
6
+ { label: 'Original', value: 'original' },
7
+ { label: 'Solid', value: 'solid' },
8
+ { label: 'Waist', value: 'waist' },
9
+ { label: 'Open', value: 'open' },
10
+ { label: 'Side stringers', value: 'side-stringers' },
11
+ { label: 'Center stringer', value: 'center-stringer' },
12
+ ];
13
+ export function StairConstructionControls({ node, inherited, onChange, }) {
14
+ const effective = node.construction ?? inherited;
15
+ const update = (patch) => onChange(StairConstruction.parse({ ...effective, ...patch }));
16
+ return (_jsxs("div", { className: "space-y-3", children: [_jsx(SelectControl, { label: "Body", value: node.construction?.mode ?? 'original', options: OPTIONS.map((option) => option.value === 'original' && inherited ? { ...option, label: 'Inherit' } : option), onChange: (mode) => mode === 'original'
17
+ ? onChange(undefined)
18
+ : update({ mode: mode }) }), effective ? (_jsxs(_Fragment, { children: [effective.mode === 'waist' ? (_jsx(MetricControl, { label: "Waist thickness", min: 0.001, value: effective.waistThickness, onChange: (waistThickness) => update({ waistThickness }), unit: "m", step: 0.01, precision: 3 })) : null, _jsx(MetricControl, { label: "Tread thickness", min: 0.001, value: effective.treadThickness, onChange: (treadThickness) => update({ treadThickness }), unit: "m", step: 0.01, precision: 3 }), _jsx(MetricControl, { label: "Nosing", min: 0, value: effective.nosing, onChange: (nosing) => update({ nosing }), unit: "m", step: 0.005, precision: 3 }), _jsx(MetricControl, { label: "Tread finish", min: 0, value: effective.finishThickness, onChange: (finishThickness) => update({ finishThickness }), unit: "m", step: 0.005, precision: 3 }), effective.mode === 'solid' || effective.mode === 'waist' ? null : (_jsxs(_Fragment, { children: [_jsx(ToggleControl, { label: "Closed risers", checked: effective.closedRisers, onChange: (closedRisers) => update({ closedRisers }) }), effective.closedRisers ? (_jsx(MetricControl, { label: "Riser thickness", min: 0.001, value: effective.riserThickness, onChange: (riserThickness) => update({ riserThickness }), unit: "m", step: 0.005, precision: 3 })) : null] })), effective.mode === 'side-stringers' || effective.mode === 'center-stringer' ? (_jsxs(_Fragment, { children: [_jsx(MetricControl, { label: "Stringer width", min: 0.001, value: effective.stringerWidth, onChange: (stringerWidth) => update({ stringerWidth }), unit: "m", step: 0.01, precision: 3 }), _jsx(MetricControl, { label: "Stringer depth", min: 0.001, value: effective.stringerDepth, onChange: (stringerDepth) => update({ stringerDepth }), unit: "m", step: 0.01, precision: 3 })] })) : null] })) : null] }));
19
+ }
20
+ export function StairConstructionField({ node, onUpdate, }) {
21
+ return (_jsx(StairConstructionControls, { node: node, onChange: (construction) => onUpdate({ construction }) }));
22
+ }
23
+ export function StairSegmentConstructionField({ node, onUpdate, }) {
24
+ const inherited = useScene((state) => {
25
+ const parent = node.parentId ? state.nodes[node.parentId] : undefined;
26
+ return parent?.type === 'stair' ? parent.construction : undefined;
27
+ });
28
+ return (_jsx(StairConstructionControls, { node: node, inherited: inherited, onChange: (construction) => onUpdate({ construction }) }));
29
+ }
@@ -0,0 +1,10 @@
1
+ import { type StairNode } from '@pascal-app/core';
2
+ import * as THREE from 'three';
3
+ import type { StairRenderData } from './use-stair-render-data';
4
+ export declare function ContinuousStairRailings({ stair, material, guard, renderData, }: {
5
+ stair: StairNode;
6
+ material: THREE.Material;
7
+ guard?: boolean;
8
+ renderData: StairRenderData;
9
+ }): import("react").JSX.Element;
10
+ //# sourceMappingURL=continuous-railings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuous-railings.d.ts","sourceRoot":"","sources":["../../src/stair/continuous-railings.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAA;AAGzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AA2J9D,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,QAAQ,EACR,KAAY,EACZ,UAAU,GACX,EAAE;IACD,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAA;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,eAAe,CAAA;CAC5B,+BA0EA"}
@@ -0,0 +1,159 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { resolveStairHandrailPaths, resolveStairRailPaths, resolveStairWalkInside, useScene, } from '@pascal-app/core';
4
+ import { getStairRailingMaterial, useViewer } from '@pascal-app/viewer';
5
+ import { useEffect, useMemo } from 'react';
6
+ import * as THREE from 'three';
7
+ import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
8
+ import { guardBoxGeometry, metricBox, metricCylinder } from './baluster-geometry';
9
+ import { buildBalusterGuard } from './baluster-guard';
10
+ import { buildBoardsGuard } from './boards-guard';
11
+ import { buildCableGuard } from './cable-guard';
12
+ import { buildGlassGuard } from './glass-guard';
13
+ import { GUARD_PICKET_PITCH, GUARD_POST_SPACING } from './guard-path';
14
+ import { resolveStairSlotMaterial } from './materials';
15
+ import { buildMetalGuard } from './metal-guard';
16
+ import { buildPostAndRailGuard } from './post-and-rail-guard';
17
+ function bar(a, b, width, depth, round = false) {
18
+ const direction = b.clone().sub(a), length = direction.length();
19
+ if (length < 1e-8)
20
+ return null;
21
+ const geometry = round ? metricCylinder(width, length) : metricBox(length, depth, width);
22
+ if (round) {
23
+ geometry.applyQuaternion(new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), direction.clone().normalize()));
24
+ }
25
+ else {
26
+ const x = direction.normalize(), z = new THREE.Vector3().crossVectors(x, new THREE.Vector3(0, 1, 0)).normalize();
27
+ if (z.lengthSq() < 1e-8)
28
+ z.set(0, 0, 1);
29
+ const y = new THREE.Vector3().crossVectors(z, x).normalize();
30
+ geometry.applyMatrix4(new THREE.Matrix4().makeBasis(x, y, z));
31
+ }
32
+ geometry.translate((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2);
33
+ return geometry;
34
+ }
35
+ /** One flat glass pane as a plumb-edged parallelogram of real thickness, with
36
+ * metre UVs on every face (E-009). Built in a local frame (x along the chord, y
37
+ * vertical, z the thickness) then yawed to the chord heading and set at its
38
+ * inset foot, so the pane's edges stay plumb through a sloping flight. */
39
+ function glassPanelGeometry(panel) {
40
+ const { run, rise, bottom, top, thickness } = panel;
41
+ const shape = new THREE.Shape()
42
+ .moveTo(0, bottom)
43
+ .lineTo(run, rise + bottom)
44
+ .lineTo(run, rise + top)
45
+ .lineTo(0, top)
46
+ .closePath();
47
+ const geometry = new THREE.ExtrudeGeometry(shape, { depth: thickness, bevelEnabled: false });
48
+ const position = geometry.getAttribute('position'), normal = geometry.getAttribute('normal'), uv = geometry.getAttribute('uv');
49
+ for (let i = 0; i < position.count; i++) {
50
+ const n = new THREE.Vector3(normal.getX(i), normal.getY(i), normal.getZ(i));
51
+ const axis = Math.abs(n.x) < 0.99 ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0);
52
+ const u = axis.addScaledVector(n, -axis.dot(n)).normalize(), v = new THREE.Vector3().crossVectors(n, u).normalize();
53
+ const point = new THREE.Vector3(position.getX(i), position.getY(i), position.getZ(i));
54
+ uv.setXY(i, point.dot(u), point.dot(v));
55
+ }
56
+ geometry.translate(0, 0, -thickness / 2);
57
+ geometry.rotateY(-panel.yaw);
58
+ geometry.translate(panel.start[0], panel.start[1], panel.start[2]);
59
+ return geometry;
60
+ }
61
+ function buildRails(stair, paths, handrails, guard, insideWalk) {
62
+ const parts = [], infill = [];
63
+ const add = (geometry, glass = false) => {
64
+ if (geometry)
65
+ (glass ? infill : parts).push(geometry);
66
+ };
67
+ const style = stair.railingStyle ?? 'balusters', height = stair.railingHeight;
68
+ for (const path of guard ? paths : []) {
69
+ // The chassis guards (balusters, post-and-rail, cable, boards, glass, metal)
70
+ // share the path chassis, so the winder/continuous run reads as the same
71
+ // guard as the per-flight one. Cable then spans straight chords between the
72
+ // shared posts, not along the curve, so a sweep stays physically honest;
73
+ // boards run a stack of flat courses along the path; glass hangs one rigid
74
+ // flat pane per bay between the posts, point-fixed by clamps; metal stands
75
+ // slim posts on baseplates with slender plumb balusters between its rails.
76
+ const common = {
77
+ railHeight: height,
78
+ postSpacing: GUARD_POST_SPACING,
79
+ topPost: stair.railingTopPost !== false,
80
+ postThrough: stair.railingPostThrough === true,
81
+ reach: stair.railingTopReach ?? 0,
82
+ };
83
+ if (style === 'glass') {
84
+ const { frame, panels } = buildGlassGuard(path.points, { ...common, insideWalk });
85
+ for (const box of frame)
86
+ add(guardBoxGeometry(box));
87
+ for (const panel of panels)
88
+ add(glassPanelGeometry(panel), true);
89
+ continue;
90
+ }
91
+ const boxes = style === 'post-and-rail'
92
+ ? buildPostAndRailGuard(path.points, common)
93
+ : style === 'cable'
94
+ ? buildCableGuard(path.points, common)
95
+ : style === 'boards'
96
+ ? buildBoardsGuard(path.points, common)
97
+ : style === 'metal'
98
+ ? buildMetalGuard(path.points, common)
99
+ : buildBalusterGuard(path.points, { ...common, pickets: GUARD_PICKET_PITCH });
100
+ for (const box of boxes)
101
+ add(guardBoxGeometry(box));
102
+ }
103
+ const guardCount = parts.reduce((sum, geometry) => sum + (geometry.index?.count ?? geometry.getAttribute('position').count), 0);
104
+ const config = stair.handrail;
105
+ for (const path of config ? handrails : []) {
106
+ const points = path.points.map((point) => new THREE.Vector3(...point));
107
+ for (let i = 1; i < points.length; i++) {
108
+ const a = points[i - 1], b = points[i], direction = b.clone().sub(a);
109
+ if (direction.length() < 1e-8)
110
+ continue;
111
+ add(bar(a
112
+ .clone()
113
+ .add(new THREE.Vector3(0, config.height, 0)), b
114
+ .clone()
115
+ .add(new THREE.Vector3(0, config.height, 0)), config.diameter, config.diameter, true));
116
+ }
117
+ }
118
+ const merge = (geometries) => {
119
+ if (!geometries.length)
120
+ return null;
121
+ for (const geometry of geometries) {
122
+ if (!geometry.hasAttribute('uv2'))
123
+ geometry.setAttribute('uv2', geometry.getAttribute('uv').clone());
124
+ }
125
+ const result = mergeGeometries(geometries, false);
126
+ for (const geometry of geometries)
127
+ geometry.dispose();
128
+ return result;
129
+ };
130
+ const handrailCount = parts.reduce((sum, geometry) => sum + (geometry.index?.count ?? geometry.getAttribute('position').count), 0) - guardCount;
131
+ const metal = merge(parts);
132
+ if (metal)
133
+ metal.userData.pascalIfcParts = [
134
+ ...(guardCount ? [{ start: 0, count: guardCount, role: 'railing' }] : []),
135
+ ...(handrailCount ? [{ start: guardCount, count: handrailCount, role: 'handrail' }] : []),
136
+ ];
137
+ return [metal, merge(infill)];
138
+ }
139
+ export function ContinuousStairRailings({ stair, material, guard = true, renderData, }) {
140
+ const { stair: resolvedStair, nodes: effective } = renderData;
141
+ const sceneMaterials = useScene((state) => state.materials);
142
+ const shading = useViewer((state) => state.shading), textures = useViewer((state) => state.textures), colorPreset = useViewer((state) => state.colorPreset);
143
+ const paths = useMemo(() => (guard ? resolveStairRailPaths(resolvedStair, effective) : []), [resolvedStair, effective, guard]);
144
+ const handrails = useMemo(() => (resolvedStair.handrail ? resolveStairHandrailPaths(resolvedStair, effective) : []), [resolvedStair, effective]);
145
+ const insideWalk = useMemo(() => guard && resolvedStair.railingStyle === 'glass'
146
+ ? resolveStairWalkInside(resolvedStair, effective)
147
+ : undefined, [resolvedStair, effective, guard]);
148
+ const geometry = useMemo(() => buildRails(stair, paths, handrails, guard, insideWalk), [stair, paths, handrails, guard, insideWalk]);
149
+ useEffect(() => () => {
150
+ for (const part of geometry)
151
+ part?.dispose();
152
+ }, [geometry]);
153
+ const glass = useMemo(() => resolveStairSlotMaterial(stair, 'infill', 'library:preset-glass', getStairRailingMaterial(stair, shading, textures, colorPreset), sceneMaterials, shading, textures), [stair, shading, textures, colorPreset, sceneMaterials]);
154
+ return (_jsxs("group", { name: "stair-continuous-railing", userData: { pascalIfcRole: 'railing' }, children: [geometry[0] ? (_jsx("mesh", { dispose: null, name: "stair-railing", geometry: geometry[0], material: material, castShadow: true, receiveShadow: true, userData: {
155
+ slotId: 'railing',
156
+ pascalIfcRole: 'railing',
157
+ pascalIfcParts: geometry[0].userData.pascalIfcParts,
158
+ } })) : null, geometry[1] ? (_jsx("mesh", { dispose: null, name: "stair-railing-infill", geometry: geometry[1], material: glass, castShadow: true, receiveShadow: true, userData: { slotId: 'infill', pascalIfcRole: 'railing' } })) : null] }));
159
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/stair/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAQpB,MAAM,kBAAkB,CAAA;AAuZzB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGpC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAkH5D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/stair/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAWpB,MAAM,kBAAkB,CAAA;AAiYzB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEpC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,OAAO,SAAS,CAkH5D,CAAA"}
@@ -1,10 +1,8 @@
1
- import { resolveStairTotalRise, StairNode as StairNodeSchema, stairFootprintAABB, useScene, } from '@pascal-app/core';
2
- const MIN_CURVED_RISE = 0.3;
3
- const MIN_CURVED_WIDTH = 0.4;
4
- const MIN_CURVED_INNER_RADIUS_SPIRAL = 0.05;
5
- const MIN_CURVED_INNER_RADIUS_CURVED = 0.2;
6
- const MIN_CURVED_SWEEP = Math.PI / 12;
7
- const MAX_CURVED_SWEEP = Math.PI * 2 - 0.05;
1
+ import { planStairSweepEdit, resolveStairTotalRise, resolveStairWinder, StairNode as StairNodeSchema, stairFootprintAABB, stairSlots, useScene, } from '@pascal-app/core';
2
+ const MIN_CURVED_RISE = 0.001;
3
+ const MIN_CURVED_WIDTH = 0.001;
4
+ const MIN_CURVED_INNER_RADIUS_SPIRAL = 0.001;
5
+ const MIN_CURVED_INNER_RADIUS_CURVED = 0.001;
8
6
  const CURVED_RISE_OFFSET = 0.35;
9
7
  const CURVED_WIDTH_HANDLE_OFFSET = 0.5;
10
8
  const CURVED_RADIAL_OFFSET = 0.16;
@@ -22,7 +20,7 @@ const STAIR_ROTATE_CORNER_OFFSET = 0.4;
22
20
  const STAIR_ROTATE_RING_OFFSET = 0.08;
23
21
  const STAIR_MOVE_FRONT_OFFSET = 0.35;
24
22
  function readTotalRise(node) {
25
- return Math.max(resolveStairTotalRise(node, useScene.getState().nodes), 0.1);
23
+ return Math.max(resolveStairTotalRise(node, useScene.getState().nodes), 0.001);
26
24
  }
27
25
  function readCurvedStairGeometry(node) {
28
26
  const isSpiral = node.stairType === 'spiral';
@@ -84,12 +82,13 @@ function readStraightStairMoveBounds(node, sceneApi) {
84
82
  if (!transform)
85
83
  return;
86
84
  const halfWidth = segment.width / 2;
87
- const corners = [
88
- [-halfWidth, 0],
89
- [halfWidth, 0],
90
- [-halfWidth, segment.length],
91
- [halfWidth, segment.length],
92
- ];
85
+ const corners = resolveStairWinder(segment)?.footprint ??
86
+ [
87
+ [-halfWidth, 0],
88
+ [halfWidth, 0],
89
+ [-halfWidth, segment.length],
90
+ [halfWidth, segment.length],
91
+ ];
93
92
  for (const [x, z] of corners) {
94
93
  const [rx, rz] = rotateLocalXZ(x, z, transform.rotation);
95
94
  minX = Math.min(minX, transform.position[0] + rx);
@@ -204,26 +203,7 @@ function curvedSweepHandle(end) {
204
203
  kind: 'arc-resize',
205
204
  axis: 'angular',
206
205
  end,
207
- apply: (initial, delta) => {
208
- const initialSweep = initial.sweepAngle ?? Math.PI / 2;
209
- const initialRotation = initial.rotation ?? 0;
210
- const sweepSign = Math.sign(initialSweep) || 1;
211
- // END handle: cursor angle delta IS the sweep delta.
212
- // START handle: cursor angle delta is the negation of the sweep delta.
213
- const sweepDelta = end === 'end' ? delta : -delta;
214
- const targetSweep = initialSweep + sweepDelta;
215
- const clampedAbs = Math.min(MAX_CURVED_SWEEP, Math.max(MIN_CURVED_SWEEP, Math.abs(targetSweep)));
216
- const newSweep = sweepSign * clampedAbs;
217
- const appliedDelta = newSweep - initialSweep;
218
- // Re-orient the stair so the OPPOSITE edge stays world-fixed:
219
- // END fixed-start: ΔR = −ΔS / 2
220
- // START fixed-end : ΔR = +ΔS / 2
221
- const rotationShift = end === 'end' ? -appliedDelta / 2 : appliedDelta / 2;
222
- return {
223
- sweepAngle: newSweep,
224
- rotation: initialRotation + rotationShift,
225
- };
226
- },
206
+ apply: (initial, delta) => planStairSweepEdit(initial, delta, end),
227
207
  placement: {
228
208
  position: (n) => {
229
209
  const g = readCurvedStairGeometry(n);
@@ -331,14 +311,13 @@ function stairHandles(node) {
331
311
  handles.push(stairRotateHandle(), stairMoveHandle());
332
312
  return handles;
333
313
  }
334
- import { computeStairSegmentFloorStackTransforms, getStairFloorPlacedFootprints, } from './floor-stack';
314
+ import { computeStairSegmentFloorStackTransforms, getStairFloorPlacedFootprints, } from '@pascal-app/core';
335
315
  import { buildStairFloorplan } from './floorplan';
336
316
  import { curvedStairInnerRadiusAffordance, curvedStairSweepAffordance, curvedStairWidthAffordance, segmentLengthAffordance, segmentWidthAffordance, stairRotateAffordance, } from './floorplan-affordances';
337
317
  import { stairFloorplanMoveTarget } from './floorplan-move';
338
318
  import { stairPaint } from './paint';
339
319
  import { stairParametrics } from './parametrics';
340
320
  import { StairNode } from './schema';
341
- import { stairSlots } from './slots';
342
321
  /**
343
322
  * Stair — Stage A. Composite node like roof: owns overall framing,
344
323
  * `stair-segment` children own per-flight geometry. Wrap-exports the
@@ -346,7 +325,7 @@ import { stairSlots } from './slots';
346
325
  */
347
326
  export const stairDefinition = {
348
327
  kind: 'stair',
349
- schemaVersion: 1,
328
+ schemaVersion: 2,
350
329
  schema: StairNode,
351
330
  category: 'structure',
352
331
  extensions: {
@@ -1,5 +1,5 @@
1
1
  import { type FloorplanGeometry, type GeometryContext, type StairNode } from '@pascal-app/core';
2
- import type { FloorplanStairArrowEntry, FloorplanStairEntry } from '@pascal-app/editor';
2
+ import type { FloorplanStairArrowEntry, FloorplanStairEntry } from './plan-entry';
3
3
  export type StairPlanDirection = 'up' | 'down';
4
4
  export declare function resolveStairPlanDirection(stair: StairNode, activeLevelId: string | null | undefined): StairPlanDirection;
5
5
  export declare function resolveStraightStairDirectionArrow(entry: FloorplanStairEntry, direction: StairPlanDirection): FloorplanStairArrowEntry | null;
@@ -1 +1 @@
1
- {"version":3,"file":"documentation.d.ts","sourceRoot":"","sources":["../../src/stair/documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAGpB,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EAEpB,MAAM,oBAAoB,CAAA;AAgB3B,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAAA;AAE9C,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,kBAAkB,CAUpB;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,kBAAkB,GAC5B,wBAAwB,GAAG,IAAI,CA0BjC;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,eAAe,GACnB,iBAAiB,EAAE,CAYrB"}
1
+ {"version":3,"file":"documentation.d.ts","sourceRoot":"","sources":["../../src/stair/documentation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAKpB,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AAOzB,OAAO,KAAK,EACV,wBAAwB,EACxB,mBAAmB,EAEpB,MAAM,cAAc,CAAA;AAUrB,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAAA;AAE9C,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,kBAAkB,CAUpB;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,kBAAkB,GAC5B,wBAAwB,GAAG,IAAI,CA0BjC;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,mBAAmB,EAC1B,GAAG,EAAE,eAAe,GACnB,iBAAiB,EAAE,CAYrB"}