@pascal-app/nodes 1.0.6 → 1.0.7

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 (566) hide show
  1. package/README.md +1 -0
  2. package/dist/beam/actions/move-endpoint.d.ts +24 -0
  3. package/dist/beam/actions/move-endpoint.d.ts.map +1 -0
  4. package/dist/beam/actions/move-endpoint.js +54 -0
  5. package/dist/beam/definition.d.ts +14 -0
  6. package/dist/beam/definition.d.ts.map +1 -0
  7. package/dist/beam/definition.js +173 -0
  8. package/dist/beam/draft-settings.d.ts +17 -0
  9. package/dist/beam/draft-settings.d.ts.map +1 -0
  10. package/dist/beam/draft-settings.js +81 -0
  11. package/dist/beam/drafting.d.ts +35 -0
  12. package/dist/beam/drafting.d.ts.map +1 -0
  13. package/dist/beam/drafting.js +103 -0
  14. package/dist/beam/floorplan-affordances.d.ts +8 -0
  15. package/dist/beam/floorplan-affordances.d.ts.map +1 -0
  16. package/dist/beam/floorplan-affordances.js +40 -0
  17. package/dist/beam/floorplan-move.d.ts +11 -0
  18. package/dist/beam/floorplan-move.d.ts.map +1 -0
  19. package/dist/beam/floorplan-move.js +54 -0
  20. package/dist/beam/floorplan.d.ts +11 -0
  21. package/dist/beam/floorplan.d.ts.map +1 -0
  22. package/dist/beam/floorplan.js +91 -0
  23. package/dist/beam/geometry.d.ts +19 -0
  24. package/dist/beam/geometry.d.ts.map +1 -0
  25. package/dist/beam/geometry.js +63 -0
  26. package/dist/beam/index.d.ts +3 -0
  27. package/dist/beam/index.d.ts.map +1 -0
  28. package/dist/beam/index.js +2 -0
  29. package/dist/beam/move-endpoint-tool.d.ts +21 -0
  30. package/dist/beam/move-endpoint-tool.d.ts.map +1 -0
  31. package/dist/beam/move-endpoint-tool.js +49 -0
  32. package/dist/beam/move-tool.d.ts +12 -0
  33. package/dist/beam/move-tool.d.ts.map +1 -0
  34. package/dist/beam/move-tool.js +114 -0
  35. package/dist/beam/panel-model.d.ts +28 -0
  36. package/dist/beam/panel-model.d.ts.map +1 -0
  37. package/dist/beam/panel-model.js +123 -0
  38. package/dist/beam/panel.d.ts +13 -0
  39. package/dist/beam/panel.d.ts.map +1 -0
  40. package/dist/beam/panel.js +107 -0
  41. package/dist/beam/parametrics.d.ts +3 -0
  42. package/dist/beam/parametrics.d.ts.map +1 -0
  43. package/dist/beam/parametrics.js +4 -0
  44. package/dist/beam/renderer.d.ts +13 -0
  45. package/dist/beam/renderer.d.ts.map +1 -0
  46. package/dist/beam/renderer.js +36 -0
  47. package/dist/beam/schema.d.ts +2 -0
  48. package/dist/beam/schema.d.ts.map +1 -0
  49. package/dist/beam/schema.js +1 -0
  50. package/dist/beam/tool.d.ts +13 -0
  51. package/dist/beam/tool.d.ts.map +1 -0
  52. package/dist/beam/tool.js +152 -0
  53. package/dist/box-vent/panel.d.ts.map +1 -1
  54. package/dist/box-vent/panel.js +8 -7
  55. package/dist/cabinet/batchable.d.ts +10 -0
  56. package/dist/cabinet/batchable.d.ts.map +1 -0
  57. package/dist/cabinet/batchable.js +12 -0
  58. package/dist/cabinet/compartment-card.d.ts.map +1 -1
  59. package/dist/cabinet/compartment-card.js +142 -46
  60. package/dist/cabinet/countertop-layout.d.ts +5 -0
  61. package/dist/cabinet/countertop-layout.d.ts.map +1 -1
  62. package/dist/cabinet/definition.d.ts.map +1 -1
  63. package/dist/cabinet/definition.js +3 -0
  64. package/dist/cabinet/dimension-input.d.ts +6 -0
  65. package/dist/cabinet/dimension-input.d.ts.map +1 -0
  66. package/dist/cabinet/dimension-input.js +8 -0
  67. package/dist/cabinet/essential-controls.d.ts.map +1 -1
  68. package/dist/cabinet/essential-controls.js +82 -17
  69. package/dist/cabinet/index.d.ts +1 -1
  70. package/dist/cabinet/index.d.ts.map +1 -1
  71. package/dist/cabinet/index.js +1 -1
  72. package/dist/cabinet/kitchen-catalog.d.ts +17 -4
  73. package/dist/cabinet/kitchen-catalog.d.ts.map +1 -1
  74. package/dist/cabinet/kitchen-catalog.js +45 -7
  75. package/dist/cabinet/kitchen-collection.d.ts.map +1 -1
  76. package/dist/cabinet/kitchen-collection.js +21 -5
  77. package/dist/cabinet/kitchen-module-actions.d.ts.map +1 -1
  78. package/dist/cabinet/kitchen-module-actions.js +107 -14
  79. package/dist/cabinet/neighbor-placement.d.ts +10 -0
  80. package/dist/cabinet/neighbor-placement.d.ts.map +1 -1
  81. package/dist/cabinet/panel.d.ts.map +1 -1
  82. package/dist/cabinet/panel.js +127 -50
  83. package/dist/cabinet/run-finishing.d.ts +5 -0
  84. package/dist/cabinet/run-finishing.d.ts.map +1 -1
  85. package/dist/cabinet/run-ops.d.ts +5 -0
  86. package/dist/cabinet/run-ops.d.ts.map +1 -1
  87. package/dist/cabinet/run-panel.d.ts.map +1 -1
  88. package/dist/cabinet/run-panel.js +203 -52
  89. package/dist/cabinet/tool.d.ts.map +1 -1
  90. package/dist/cabinet/tool.js +8 -5
  91. package/dist/ceiling/build-up-section.d.ts +7 -0
  92. package/dist/ceiling/build-up-section.d.ts.map +1 -0
  93. package/dist/ceiling/build-up-section.js +57 -0
  94. package/dist/ceiling/definition.d.ts.map +1 -1
  95. package/dist/ceiling/definition.js +3 -1
  96. package/dist/ceiling/floorplan-affordances.d.ts +112 -0
  97. package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
  98. package/dist/ceiling/materials.d.ts +5 -0
  99. package/dist/ceiling/materials.d.ts.map +1 -1
  100. package/dist/ceiling/materials.js +17 -0
  101. package/dist/ceiling/panel-model.d.ts +13 -0
  102. package/dist/ceiling/panel-model.d.ts.map +1 -0
  103. package/dist/ceiling/panel-model.js +49 -0
  104. package/dist/ceiling/panel.d.ts.map +1 -1
  105. package/dist/ceiling/panel.js +82 -18
  106. package/dist/ceiling/renderer.d.ts.map +1 -1
  107. package/dist/ceiling/renderer.js +10 -4
  108. package/dist/ceiling/tool.d.ts.map +1 -1
  109. package/dist/ceiling/tool.js +24 -4
  110. package/dist/chimney/panel.d.ts.map +1 -1
  111. package/dist/chimney/panel.js +113 -41
  112. package/dist/column/definition.d.ts.map +1 -1
  113. package/dist/column/definition.js +3 -0
  114. package/dist/column/floorplan.d.ts.map +1 -1
  115. package/dist/column/floorplan.js +17 -0
  116. package/dist/column/hosted-resize.d.ts +28 -1
  117. package/dist/column/hosted-resize.d.ts.map +1 -1
  118. package/dist/column/panel.d.ts.map +1 -1
  119. package/dist/column/panel.js +125 -37
  120. package/dist/column/post-options.d.ts +10 -0
  121. package/dist/column/post-options.d.ts.map +1 -0
  122. package/dist/column/post-options.js +71 -0
  123. package/dist/column/post-placement.d.ts +78 -0
  124. package/dist/column/post-placement.d.ts.map +1 -0
  125. package/dist/column/post-placement.js +157 -0
  126. package/dist/column/post-section.d.ts +17 -0
  127. package/dist/column/post-section.d.ts.map +1 -0
  128. package/dist/column/post-section.js +95 -0
  129. package/dist/column/post-tool.d.ts +11 -0
  130. package/dist/column/post-tool.d.ts.map +1 -0
  131. package/dist/column/post-tool.js +94 -0
  132. package/dist/column/tool.d.ts +3 -10
  133. package/dist/column/tool.d.ts.map +1 -1
  134. package/dist/column/tool.js +13 -1
  135. package/dist/cupola/panel.d.ts.map +1 -1
  136. package/dist/cupola/panel.js +14 -7
  137. package/dist/door/actions.d.ts +7 -0
  138. package/dist/door/actions.d.ts.map +1 -0
  139. package/dist/door/actions.js +32 -0
  140. package/dist/door/contextual-dimensions.d.ts.map +1 -1
  141. package/dist/door/contextual-dimensions.js +11 -1
  142. package/dist/door/definition.d.ts.map +1 -1
  143. package/dist/door/definition.js +34 -7
  144. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  145. package/dist/door/floorplan-affordances.js +5 -2
  146. package/dist/door/floorplan-move.d.ts.map +1 -1
  147. package/dist/door/floorplan-move.js +28 -6
  148. package/dist/door/floorplan.d.ts +2 -0
  149. package/dist/door/floorplan.d.ts.map +1 -1
  150. package/dist/door/floorplan.js +89 -16
  151. package/dist/door/move-tool.d.ts.map +1 -1
  152. package/dist/door/move-tool.js +60 -16
  153. package/dist/door/paint.d.ts +2 -7
  154. package/dist/door/paint.d.ts.map +1 -1
  155. package/dist/door/paint.js +26 -2
  156. package/dist/door/panel.d.ts.map +1 -1
  157. package/dist/door/panel.js +242 -90
  158. package/dist/door/parametrics.js +1 -1
  159. package/dist/door/placement.d.ts.map +1 -1
  160. package/dist/door/placement.js +9 -2
  161. package/dist/door/swing.d.ts +22 -0
  162. package/dist/door/swing.d.ts.map +1 -0
  163. package/dist/door/swing.js +36 -0
  164. package/dist/door/tool.d.ts.map +1 -1
  165. package/dist/door/tool.js +76 -29
  166. package/dist/dormer/panel-actions-section.d.ts.map +1 -1
  167. package/dist/dormer/panel-actions-section.js +3 -1
  168. package/dist/dormer/panel-position-section.d.ts.map +1 -1
  169. package/dist/dormer/panel-position-section.js +4 -3
  170. package/dist/dormer/panel-windows-section.d.ts.map +1 -1
  171. package/dist/dormer/panel-windows-section.js +38 -1
  172. package/dist/dormer/panel.d.ts.map +1 -1
  173. package/dist/dormer/panel.js +24 -18
  174. package/dist/downspout/inspector-editors.d.ts.map +1 -1
  175. package/dist/downspout/inspector-editors.js +3 -2
  176. package/dist/duct-fitting/inspector-editors.d.ts.map +1 -1
  177. package/dist/duct-fitting/inspector-editors.js +6 -1
  178. package/dist/duct-fitting/tool.d.ts.map +1 -1
  179. package/dist/duct-fitting/tool.js +11 -2
  180. package/dist/duct-terminal/tool.d.ts.map +1 -1
  181. package/dist/duct-terminal/tool.js +11 -2
  182. package/dist/elevator/panel.d.ts.map +1 -1
  183. package/dist/elevator/panel.js +41 -18
  184. package/dist/eyebrow-vent/panel.d.ts.map +1 -1
  185. package/dist/eyebrow-vent/panel.js +16 -6
  186. package/dist/fence/drafting.d.ts +2 -3
  187. package/dist/fence/drafting.d.ts.map +1 -1
  188. package/dist/fence/drafting.js +2 -3
  189. package/dist/fence/inspector-editors.d.ts.map +1 -1
  190. package/dist/fence/inspector-editors.js +64 -21
  191. package/dist/fence/move-endpoint-tool.d.ts.map +1 -1
  192. package/dist/fence/move-endpoint-tool.js +11 -2
  193. package/dist/fence/system.d.ts.map +1 -1
  194. package/dist/fence/system.js +13 -0
  195. package/dist/fence-feature/actions.d.ts.map +1 -1
  196. package/dist/fence-feature/actions.js +5 -2
  197. package/dist/fence-feature/inspector.d.ts.map +1 -1
  198. package/dist/fence-feature/inspector.js +150 -34
  199. package/dist/fence-feature/move-session.d.ts +1 -1
  200. package/dist/floor-opening/floorplan.d.ts +29 -6
  201. package/dist/floor-opening/floorplan.d.ts.map +1 -1
  202. package/dist/floor-opening/floorplan.js +172 -14
  203. package/dist/gutter/downspouts-panel.d.ts.map +1 -1
  204. package/dist/gutter/downspouts-panel.js +14 -2
  205. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  206. package/dist/hvac-equipment/tool.js +3 -2
  207. package/dist/i18n/definition-messages.d.ts +5 -0
  208. package/dist/i18n/definition-messages.d.ts.map +1 -0
  209. package/dist/i18n/definition-messages.js +771 -0
  210. package/dist/index.d.ts +4 -1
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +6 -1
  213. package/dist/item/authored-params.d.ts.map +1 -1
  214. package/dist/item/authored-params.js +19 -4
  215. package/dist/item/floorplan.d.ts +1 -1
  216. package/dist/item/floorplan.d.ts.map +1 -1
  217. package/dist/item/panel.d.ts.map +1 -1
  218. package/dist/item/panel.js +9 -7
  219. package/dist/liquid-line/tool.d.ts.map +1 -1
  220. package/dist/liquid-line/tool.js +10 -3
  221. package/dist/measurement/tool.d.ts +1 -1
  222. package/dist/measurement/tool.d.ts.map +1 -1
  223. package/dist/measurement/tool.js +8 -8
  224. package/dist/pipe-fitting/tool.d.ts.map +1 -1
  225. package/dist/pipe-fitting/tool.js +3 -2
  226. package/dist/pipe-trap/tool.d.ts.map +1 -1
  227. package/dist/pipe-trap/tool.js +7 -2
  228. package/dist/procedural-item/renderer.d.ts.map +1 -1
  229. package/dist/procedural-item/renderer.js +8 -1
  230. package/dist/ridge-vent/panel.d.ts.map +1 -1
  231. package/dist/ridge-vent/panel.js +22 -9
  232. package/dist/roof/barrel-panel.d.ts.map +1 -1
  233. package/dist/roof/barrel-panel.js +7 -3
  234. package/dist/roof/definition.d.ts.map +1 -1
  235. package/dist/roof/definition.js +33 -3
  236. package/dist/roof/floorplan-overrides.d.ts +22 -0
  237. package/dist/roof/floorplan-overrides.d.ts.map +1 -0
  238. package/dist/roof/floorplan-overrides.js +46 -0
  239. package/dist/roof/floorplan-tool.d.ts +9 -0
  240. package/dist/roof/floorplan-tool.d.ts.map +1 -0
  241. package/dist/roof/floorplan-tool.js +168 -0
  242. package/dist/roof/floorplan.d.ts.map +1 -1
  243. package/dist/roof/floorplan.js +131 -41
  244. package/dist/roof/glazing-controls.d.ts +2 -1
  245. package/dist/roof/glazing-controls.d.ts.map +1 -1
  246. package/dist/roof/glazing-controls.js +51 -13
  247. package/dist/roof/glazing-panel-editor.d.ts.map +1 -1
  248. package/dist/roof/glazing-panel-editor.js +40 -13
  249. package/dist/roof/glazing-panel.d.ts.map +1 -1
  250. package/dist/roof/glazing-panel.js +73 -9
  251. package/dist/roof/paint.d.ts +19 -0
  252. package/dist/roof/paint.d.ts.map +1 -0
  253. package/dist/roof/paint.js +158 -0
  254. package/dist/roof/panel.d.ts.map +1 -1
  255. package/dist/roof/panel.js +90 -22
  256. package/dist/roof/renderer.d.ts.map +1 -1
  257. package/dist/roof/renderer.js +13 -2
  258. package/dist/roof/roof-footprint-source.d.ts +17 -0
  259. package/dist/roof/roof-footprint-source.d.ts.map +1 -1
  260. package/dist/roof/roof-footprint-source.js +14 -0
  261. package/dist/roof/roof-footprint.d.ts +36 -2
  262. package/dist/roof/roof-footprint.d.ts.map +1 -1
  263. package/dist/roof/roof-footprint.js +124 -2
  264. package/dist/roof/roof-materials.d.ts.map +1 -1
  265. package/dist/roof/roof-materials.js +10 -1
  266. package/dist/roof/roof-placement-mode.d.ts +0 -2
  267. package/dist/roof/roof-placement-mode.d.ts.map +1 -1
  268. package/dist/roof/roof-placement-mode.js +8 -6
  269. package/dist/roof/roof-plan-creases.d.ts +50 -0
  270. package/dist/roof/roof-plan-creases.d.ts.map +1 -0
  271. package/dist/roof/roof-plan-creases.js +194 -0
  272. package/dist/roof/roof-ridge-mode.d.ts +20 -0
  273. package/dist/roof/roof-ridge-mode.d.ts.map +1 -0
  274. package/dist/roof/roof-ridge-mode.js +16 -0
  275. package/dist/roof/tool.d.ts +17 -4
  276. package/dist/roof/tool.d.ts.map +1 -1
  277. package/dist/roof/tool.js +211 -113
  278. package/dist/roof/wall-catch.d.ts +106 -0
  279. package/dist/roof/wall-catch.d.ts.map +1 -0
  280. package/dist/roof/wall-catch.js +267 -0
  281. package/dist/roof-segment/build-up-section.d.ts +9 -0
  282. package/dist/roof-segment/build-up-section.d.ts.map +1 -0
  283. package/dist/roof-segment/build-up-section.js +191 -0
  284. package/dist/roof-segment/definition.d.ts.map +1 -1
  285. package/dist/roof-segment/definition.js +50 -5
  286. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  287. package/dist/roof-segment/floorplan-affordances.js +68 -19
  288. package/dist/roof-segment/floorplan.d.ts.map +1 -1
  289. package/dist/roof-segment/floorplan.js +16 -12
  290. package/dist/roof-segment/paint.d.ts +3 -1
  291. package/dist/roof-segment/paint.d.ts.map +1 -1
  292. package/dist/roof-segment/paint.js +43 -2
  293. package/dist/roof-segment/panel-model.d.ts +23 -0
  294. package/dist/roof-segment/panel-model.d.ts.map +1 -0
  295. package/dist/roof-segment/panel-model.js +64 -0
  296. package/dist/roof-segment/panel.d.ts.map +1 -1
  297. package/dist/roof-segment/panel.js +96 -14
  298. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  299. package/dist/roof-segment/parametrics.js +4 -0
  300. package/dist/roof-segment/renderer.d.ts.map +1 -1
  301. package/dist/roof-segment/renderer.js +26 -5
  302. package/dist/separator/definition.d.ts.map +1 -1
  303. package/dist/separator/definition.js +10 -12
  304. package/dist/separator/floorplan-affordances.d.ts +9 -0
  305. package/dist/separator/floorplan-affordances.d.ts.map +1 -0
  306. package/dist/separator/floorplan-affordances.js +23 -0
  307. package/dist/separator/floorplan.d.ts +9 -0
  308. package/dist/separator/floorplan.d.ts.map +1 -0
  309. package/dist/separator/floorplan.js +54 -0
  310. package/dist/separator/renderer.d.ts +4 -0
  311. package/dist/separator/renderer.d.ts.map +1 -1
  312. package/dist/separator/renderer.js +21 -6
  313. package/dist/separator/selection.d.ts +10 -0
  314. package/dist/separator/selection.d.ts.map +1 -0
  315. package/dist/separator/selection.js +35 -0
  316. package/dist/shared/build-up-controls.d.ts +88 -0
  317. package/dist/shared/build-up-controls.d.ts.map +1 -0
  318. package/dist/shared/build-up-controls.js +139 -0
  319. package/dist/shared/curtain-opening-limits.d.ts.map +1 -1
  320. package/dist/shared/curtain-opening-limits.js +44 -14
  321. package/dist/shared/item-interaction-actions.d.ts.map +1 -1
  322. package/dist/shared/item-interaction-actions.js +11 -2
  323. package/dist/shared/layer-thickness.d.ts +2 -0
  324. package/dist/shared/layer-thickness.d.ts.map +1 -0
  325. package/dist/shared/layer-thickness.js +3 -0
  326. package/dist/shared/move-roof-tool.d.ts.map +1 -1
  327. package/dist/shared/move-roof-tool.js +100 -5
  328. package/dist/shared/node-batch/batchable.d.ts +2 -0
  329. package/dist/shared/node-batch/batchable.d.ts.map +1 -1
  330. package/dist/shared/node-batch/batchable.js +4 -0
  331. package/dist/shared/node-batch/candidates.d.ts +21 -5
  332. package/dist/shared/node-batch/candidates.d.ts.map +1 -1
  333. package/dist/shared/node-batch/candidates.js +85 -50
  334. package/dist/shared/node-batch/system.d.ts.map +1 -1
  335. package/dist/shared/node-batch/system.js +24 -15
  336. package/dist/shared/opening-casing-move.d.ts +16 -0
  337. package/dist/shared/opening-casing-move.d.ts.map +1 -0
  338. package/dist/shared/opening-casing-move.js +33 -0
  339. package/dist/shared/opening-casing-section.d.ts +15 -0
  340. package/dist/shared/opening-casing-section.d.ts.map +1 -0
  341. package/dist/shared/opening-casing-section.js +38 -0
  342. package/dist/shared/opening-casing.d.ts +26 -0
  343. package/dist/shared/opening-casing.d.ts.map +1 -0
  344. package/dist/shared/opening-casing.js +80 -0
  345. package/dist/shared/opening-depth-position.d.ts +13 -0
  346. package/dist/shared/opening-depth-position.d.ts.map +1 -0
  347. package/dist/shared/opening-depth-position.js +34 -0
  348. package/dist/shared/opening-documentation.d.ts.map +1 -1
  349. package/dist/shared/opening-documentation.js +17 -8
  350. package/dist/shared/opening-guides-runtime.d.ts +2 -1
  351. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  352. package/dist/shared/opening-guides-runtime.js +11 -7
  353. package/dist/shared/opening-labels.d.ts +11 -0
  354. package/dist/shared/opening-labels.d.ts.map +1 -0
  355. package/dist/shared/opening-labels.js +46 -0
  356. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  357. package/dist/shared/opening-placement-dimensions.js +11 -9
  358. package/dist/shared/opening-plane-offset.d.ts +4 -3
  359. package/dist/shared/opening-plane-offset.d.ts.map +1 -1
  360. package/dist/shared/opening-plane-offset.js +7 -4
  361. package/dist/shared/opening-swap.d.ts +8 -0
  362. package/dist/shared/opening-swap.d.ts.map +1 -0
  363. package/dist/shared/opening-swap.js +18 -0
  364. package/dist/shared/polygon-vertex-affordance.d.ts +19 -0
  365. package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
  366. package/dist/shared/polygon-vertex-affordance.js +65 -6
  367. package/dist/shared/roof-opening-host.d.ts +2 -1
  368. package/dist/shared/roof-opening-host.d.ts.map +1 -1
  369. package/dist/shared/roof-opening-host.js +14 -5
  370. package/dist/shared/roof-wall-opening-cut.d.ts.map +1 -1
  371. package/dist/shared/roof-wall-opening-cut.js +14 -6
  372. package/dist/shared/roof-wall-opening-placement.d.ts +2 -1
  373. package/dist/shared/roof-wall-opening-placement.d.ts.map +1 -1
  374. package/dist/shared/roof-wall-opening-placement.js +6 -4
  375. package/dist/shared/run-hanger-inspector.d.ts.map +1 -1
  376. package/dist/shared/run-hanger-inspector.js +39 -5
  377. package/dist/shared/system-check-panel.d.ts.map +1 -1
  378. package/dist/shared/system-check-panel.js +94 -15
  379. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  380. package/dist/shared/wall-attach-target.js +6 -3
  381. package/dist/shelf/definition.d.ts.map +1 -1
  382. package/dist/shelf/definition.js +2 -0
  383. package/dist/site/ground-hole.d.ts +3 -3
  384. package/dist/site/ground-hole.js +3 -3
  385. package/dist/site/ground-veil.d.ts +5 -12
  386. package/dist/site/ground-veil.d.ts.map +1 -1
  387. package/dist/site/ground-veil.js +9 -33
  388. package/dist/site/panel.d.ts.map +1 -1
  389. package/dist/site/panel.js +52 -12
  390. package/dist/site/renderer.d.ts.map +1 -1
  391. package/dist/site/renderer.js +52 -23
  392. package/dist/skylight/panel.d.ts.map +1 -1
  393. package/dist/skylight/panel.js +49 -19
  394. package/dist/slab/deck-geometry.d.ts +28 -0
  395. package/dist/slab/deck-geometry.d.ts.map +1 -0
  396. package/dist/slab/deck-geometry.js +320 -0
  397. package/dist/slab/definition.d.ts +2 -1
  398. package/dist/slab/definition.d.ts.map +1 -1
  399. package/dist/slab/definition.js +6 -1
  400. package/dist/slab/dependency-tracker.d.ts.map +1 -1
  401. package/dist/slab/dependency-tracker.js +3 -0
  402. package/dist/slab/floorplan-affordances.d.ts +500 -0
  403. package/dist/slab/floorplan-affordances.d.ts.map +1 -1
  404. package/dist/slab/geometry.d.ts.map +1 -1
  405. package/dist/slab/geometry.js +46 -9
  406. package/dist/slab/panel.d.ts.map +1 -1
  407. package/dist/slab/panel.js +97 -21
  408. package/dist/slab/renderer.d.ts +11 -0
  409. package/dist/slab/renderer.d.ts.map +1 -0
  410. package/dist/slab/renderer.js +19 -0
  411. package/dist/slab/system.d.ts.map +1 -1
  412. package/dist/slab/system.js +12 -1
  413. package/dist/solar-panel/panel.d.ts.map +1 -1
  414. package/dist/solar-panel/panel.js +49 -14
  415. package/dist/stair/construction-controls.d.ts +3 -1
  416. package/dist/stair/construction-controls.d.ts.map +1 -1
  417. package/dist/stair/construction-controls.js +75 -12
  418. package/dist/stair/paint.d.ts +6 -0
  419. package/dist/stair/paint.d.ts.map +1 -1
  420. package/dist/stair/panel.d.ts.map +1 -1
  421. package/dist/stair/panel.js +243 -51
  422. package/dist/stair/parametrics.d.ts.map +1 -1
  423. package/dist/stair/parametrics.js +7 -0
  424. package/dist/stair/placement-defaults.d.ts +18 -0
  425. package/dist/stair/placement-defaults.d.ts.map +1 -0
  426. package/dist/stair/placement-defaults.js +27 -0
  427. package/dist/stair/railing-controls.d.ts.map +1 -1
  428. package/dist/stair/railing-controls.js +78 -18
  429. package/dist/stair/renderer.d.ts.map +1 -1
  430. package/dist/stair/renderer.js +16 -10
  431. package/dist/stair/structure-controls.d.ts +18 -0
  432. package/dist/stair/structure-controls.d.ts.map +1 -0
  433. package/dist/stair/structure-controls.js +275 -0
  434. package/dist/stair/tool.d.ts.map +1 -1
  435. package/dist/stair/tool.js +13 -9
  436. package/dist/stair/use-stair-render-data.d.ts +41 -0
  437. package/dist/stair/use-stair-render-data.d.ts.map +1 -1
  438. package/dist/stair-segment/panel.d.ts.map +1 -1
  439. package/dist/stair-segment/panel.js +65 -18
  440. package/dist/turbine-vent/panel.d.ts.map +1 -1
  441. package/dist/turbine-vent/panel.js +14 -5
  442. package/dist/unit/unit-panel.d.ts.map +1 -1
  443. package/dist/unit/unit-panel.js +28 -12
  444. package/dist/wall/actions.d.ts +1 -1
  445. package/dist/wall/actions.d.ts.map +1 -1
  446. package/dist/wall/actions.js +17 -13
  447. package/dist/wall/construction-dimensions.d.ts +6 -0
  448. package/dist/wall/construction-dimensions.d.ts.map +1 -1
  449. package/dist/wall/construction-dimensions.js +8 -0
  450. package/dist/wall/contextual-dimensions.d.ts +6 -0
  451. package/dist/wall/contextual-dimensions.d.ts.map +1 -1
  452. package/dist/wall/contextual-dimensions.js +104 -17
  453. package/dist/wall/curtain-opening-frame.d.ts.map +1 -1
  454. package/dist/wall/curtain-opening-frame.js +6 -4
  455. package/dist/wall/curtain-wall-layout.d.ts +1 -1
  456. package/dist/wall/curtain-wall-layout.d.ts.map +1 -1
  457. package/dist/wall/curtain-wall-layout.js +6 -4
  458. package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
  459. package/dist/wall/curtain-wall-materials.js +8 -3
  460. package/dist/wall/curtain-wall-panel.d.ts.map +1 -1
  461. package/dist/wall/curtain-wall-panel.js +241 -37
  462. package/dist/wall/curve-tool.d.ts.map +1 -1
  463. package/dist/wall/curve-tool.js +2 -3
  464. package/dist/wall/definition.d.ts.map +1 -1
  465. package/dist/wall/definition.js +20 -5
  466. package/dist/wall/floorplan-affordances.d.ts.map +1 -1
  467. package/dist/wall/floorplan-affordances.js +9 -6
  468. package/dist/wall/floorplan-move.d.ts.map +1 -1
  469. package/dist/wall/floorplan-move.js +66 -16
  470. package/dist/wall/floorplan.d.ts +4 -5
  471. package/dist/wall/floorplan.d.ts.map +1 -1
  472. package/dist/wall/floorplan.js +62 -46
  473. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  474. package/dist/wall/move-endpoint-tool.js +1 -0
  475. package/dist/wall/move-tool.d.ts.map +1 -1
  476. package/dist/wall/move-tool.js +77 -12
  477. package/dist/wall/paint.d.ts +2 -2
  478. package/dist/wall/paint.d.ts.map +1 -1
  479. package/dist/wall/paint.js +11 -4
  480. package/dist/wall/panel-model.d.ts +17 -2
  481. package/dist/wall/panel-model.d.ts.map +1 -1
  482. package/dist/wall/panel-model.js +158 -18
  483. package/dist/wall/panel.d.ts +8 -0
  484. package/dist/wall/panel.d.ts.map +1 -1
  485. package/dist/wall/panel.js +228 -156
  486. package/dist/wall/parametrics.d.ts +1 -1
  487. package/dist/wall/parametrics.d.ts.map +1 -1
  488. package/dist/wall/parametrics.js +14 -1
  489. package/dist/wall/railing-wall-adapter.d.ts +7 -0
  490. package/dist/wall/railing-wall-adapter.d.ts.map +1 -0
  491. package/dist/wall/railing-wall-adapter.js +38 -0
  492. package/dist/wall/railing-wall-floorplan.d.ts +8 -0
  493. package/dist/wall/railing-wall-floorplan.d.ts.map +1 -0
  494. package/dist/wall/railing-wall-floorplan.js +27 -0
  495. package/dist/wall/railing-wall-geometry.d.ts +12 -0
  496. package/dist/wall/railing-wall-geometry.d.ts.map +1 -0
  497. package/dist/wall/railing-wall-geometry.js +51 -0
  498. package/dist/wall/railing-wall-guard.d.ts +81 -0
  499. package/dist/wall/railing-wall-guard.d.ts.map +1 -0
  500. package/dist/wall/railing-wall-guard.js +435 -0
  501. package/dist/wall/railing-wall-materials.d.ts +11 -0
  502. package/dist/wall/railing-wall-materials.d.ts.map +1 -0
  503. package/dist/wall/railing-wall-materials.js +31 -0
  504. package/dist/wall/railing-wall-panel-model.d.ts +30 -0
  505. package/dist/wall/railing-wall-panel-model.d.ts.map +1 -0
  506. package/dist/wall/railing-wall-panel-model.js +117 -0
  507. package/dist/wall/railing-wall-panel.d.ts +17 -0
  508. package/dist/wall/railing-wall-panel.d.ts.map +1 -0
  509. package/dist/wall/railing-wall-panel.js +42 -0
  510. package/dist/wall/rectangle-command.d.ts +79 -1
  511. package/dist/wall/rectangle-command.d.ts.map +1 -1
  512. package/dist/wall/rectangle-tool.d.ts.map +1 -1
  513. package/dist/wall/rectangle-tool.js +2 -0
  514. package/dist/wall/renderer.d.ts.map +1 -1
  515. package/dist/wall/renderer.js +3 -1
  516. package/dist/wall/skirting-floor-gaps.d.ts +8 -0
  517. package/dist/wall/skirting-floor-gaps.d.ts.map +1 -0
  518. package/dist/wall/skirting-floor-gaps.js +36 -0
  519. package/dist/wall/system.d.ts +0 -14
  520. package/dist/wall/system.d.ts.map +1 -1
  521. package/dist/wall/system.js +6 -1
  522. package/dist/wall/tool.d.ts +16 -0
  523. package/dist/wall/tool.d.ts.map +1 -1
  524. package/dist/wall/tool.js +160 -47
  525. package/dist/wall/treatments.d.ts +3 -0
  526. package/dist/wall/treatments.d.ts.map +1 -1
  527. package/dist/wall/treatments.js +30 -7
  528. package/dist/window/actions.d.ts +7 -0
  529. package/dist/window/actions.d.ts.map +1 -0
  530. package/dist/window/actions.js +29 -0
  531. package/dist/window/definition.d.ts.map +1 -1
  532. package/dist/window/definition.js +11 -2
  533. package/dist/window/floorplan-move.d.ts.map +1 -1
  534. package/dist/window/floorplan-move.js +5 -0
  535. package/dist/window/floorplan.d.ts +2 -0
  536. package/dist/window/floorplan.d.ts.map +1 -1
  537. package/dist/window/floorplan.js +58 -1
  538. package/dist/window/mechanism.d.ts.map +1 -1
  539. package/dist/window/mechanism.js +21 -1
  540. package/dist/window/move-tool.d.ts.map +1 -1
  541. package/dist/window/move-tool.js +10 -3
  542. package/dist/window/paint.d.ts +2 -7
  543. package/dist/window/paint.d.ts.map +1 -1
  544. package/dist/window/paint.js +31 -3
  545. package/dist/window/panel.d.ts.map +1 -1
  546. package/dist/window/panel.js +311 -69
  547. package/dist/window/placement.d.ts.map +1 -1
  548. package/dist/window/placement.js +5 -1
  549. package/dist/window/swing.d.ts +13 -0
  550. package/dist/window/swing.d.ts.map +1 -0
  551. package/dist/window/swing.js +16 -0
  552. package/dist/window/tool.d.ts.map +1 -1
  553. package/dist/window/tool.js +19 -14
  554. package/dist/zone/floorplan-affordances.d.ts +136 -0
  555. package/dist/zone/floorplan-affordances.d.ts.map +1 -1
  556. package/dist/zone/quantities-panel.d.ts.map +1 -1
  557. package/dist/zone/quantities-panel.js +34 -9
  558. package/dist/zone/renderer.d.ts.map +1 -1
  559. package/dist/zone/renderer.js +9 -5
  560. package/package.json +14 -14
  561. package/dist/site/generic-foundation-geometry.d.ts +0 -16
  562. package/dist/site/generic-foundation-geometry.d.ts.map +0 -1
  563. package/dist/site/generic-foundation-geometry.js +0 -75
  564. package/dist/site/generic-foundation.d.ts +0 -4
  565. package/dist/site/generic-foundation.d.ts.map +0 -1
  566. package/dist/site/generic-foundation.js +0 -91
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { usePascalI18n } from '@pascal-app/core';
3
4
  import { getLinearUnitLabel, linearControlValueToMeters, metersToLinearUnit, PanelSection, SegmentedControl, SelectControl, SliderControl, } from '@pascal-app/editor';
4
5
  import { useViewer } from '@pascal-app/viewer';
5
6
  import { useCallback } from 'react';
@@ -18,6 +19,7 @@ export function GlazingNumber({ field, label, value, preview, fraction = false,
18
19
  return (_jsx(SliderControl, { label: label, value: fraction ? value * 100 : display(value), mixed: mixed, min: fraction ? (field === 'glassOpacity' ? 5 : 0) : display(0.001), max: fraction ? 100 : undefined, unit: fraction ? '%' : millimeters ? 'mm' : getLinearUnitLabel(unit), precision: fraction ? 0 : millimeters ? 1 : 3, step: fraction || millimeters ? 1 : 0.005, onChange: onChange, onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true }));
19
20
  }
20
21
  export function GlazingGridControls({ axis, title, description, grid, grids, preview, }) {
22
+ const i18n = usePascalI18n();
21
23
  const unit = useViewer((state) => state.unit);
22
24
  const patch = useCallback((data, commit = false) => {
23
25
  preview.previewGlazing((config) => ({ ...config, [axis]: { ...config[axis], ...data } }));
@@ -25,26 +27,62 @@ export function GlazingGridControls({ axis, title, description, grid, grids, pre
25
27
  preview.commit();
26
28
  }, [axis, preview]);
27
29
  const mixedLayout = grids.some((value) => value.layout !== grid.layout);
28
- return (_jsxs(PanelSection, { title: title, children: [_jsx(SelectControl, { label: "Layout", value: grid.layout, mixed: mixedLayout, options: [
29
- { value: 'maximum-spacing', label: 'Maximum spacing' },
30
- { value: 'count', label: 'Panel count' },
31
- { value: 'fixed-spacing', label: 'Fixed spacing' },
32
- ], onChange: (layout) => patch({ layout }, true) }), mixedLayout ? (_jsx("p", { className: "pt-1 text-[11px] text-muted-foreground", children: "Choose a layout to edit the grid." })) : grid.layout === 'count' ? (_jsx(SliderControl, { label: "Panels", value: grid.count, mixed: grids.some((value) => value.count !== grid.count), min: 1, max: 32, step: 1, precision: 0, onChange: (count) => patch({ count: Math.round(count) }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true })) : (_jsx(SliderControl, { label: grid.layout === 'maximum-spacing' ? 'Max spacing' : 'Spacing', value: metersToLinearUnit(grid.spacing, unit), mixed: grids.some((value) => value.spacing !== grid.spacing), min: metersToLinearUnit(0.2, unit), max: metersToLinearUnit(100, unit), unit: getLinearUnitLabel(unit), step: 0.05, precision: 2, onChange: (input) => patch({
30
+ return (_jsxs(PanelSection, { title: title, children: [_jsx(SelectControl, { label: i18n._({ id: 'node.roof.glazingControls.layout', message: 'Layout' }), value: grid.layout, mixed: mixedLayout, options: [
31
+ {
32
+ value: 'maximum-spacing',
33
+ label: i18n._({
34
+ id: 'node.roof.glazingControls.maximumSpacing',
35
+ message: 'Maximum spacing',
36
+ }),
37
+ },
38
+ {
39
+ value: 'count',
40
+ label: i18n._({ id: 'node.roof.glazingControls.panelCount', message: 'Panel count' }),
41
+ },
42
+ {
43
+ value: 'fixed-spacing',
44
+ label: i18n._({
45
+ id: 'node.roof.glazingControls.fixedSpacing',
46
+ message: 'Fixed spacing',
47
+ }),
48
+ },
49
+ ], onChange: (layout) => patch({ layout }, true) }), mixedLayout ? (_jsx("p", { className: "pt-1 text-[11px] text-muted-foreground", children: i18n._({
50
+ id: 'node.roof.glazingControls.chooseALayoutToEditThe',
51
+ message: 'Choose a layout to edit the grid.',
52
+ }) })) : grid.layout === 'count' ? (_jsx(SliderControl, { label: i18n._({ id: 'node.roof.glazingControls.panels', message: 'Panels' }), value: grid.count, mixed: grids.some((value) => value.count !== grid.count), min: 1, max: 32, step: 1, precision: 0, onChange: (count) => patch({ count: Math.round(count) }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true })) : (_jsx(SliderControl, { label: grid.layout === 'maximum-spacing'
53
+ ? i18n._({ id: 'node.roof.glazingControls.maxSpacing', message: 'Max spacing' })
54
+ : i18n._({ id: 'node.roof.glazingControls.spacing', message: 'Spacing' }), value: metersToLinearUnit(grid.spacing, unit), mixed: grids.some((value) => value.spacing !== grid.spacing), min: metersToLinearUnit(0.2, unit), max: metersToLinearUnit(100, unit), unit: getLinearUnitLabel(unit), step: 0.05, precision: 2, onChange: (input) => patch({
33
55
  spacing: linearControlValueToMeters(input, unit, { minMeters: 0.2, maxMeters: 100 }),
34
- }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true })), !mixedLayout && grid.layout === 'fixed-spacing' && (_jsxs("div", { className: "flex flex-col gap-2 pt-1", role: "group", "aria-label": `${title} alignment`, children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Alignment" }), _jsx(SegmentedControl, { value: grid.alignment, mixed: grids.some((value) => value.alignment !== grid.alignment), options: [
35
- { value: 'start', label: 'Start' },
36
- { value: 'center', label: 'Center' },
37
- { value: 'end', label: 'End' },
56
+ }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true })), !mixedLayout && grid.layout === 'fixed-spacing' && (_jsxs("div", { className: "flex flex-col gap-2 pt-1", role: "group", "aria-label": i18n._({
57
+ id: 'node.roof.glazingControls.titleAlignment',
58
+ message: '{title} alignment',
59
+ values: { title },
60
+ }), children: [_jsx("span", { className: "text-xs text-muted-foreground", children: i18n._({ id: 'node.roof.glazingControls.alignment', message: 'Alignment' }) }), _jsx(SegmentedControl, { value: grid.alignment, mixed: grids.some((value) => value.alignment !== grid.alignment), options: [
61
+ {
62
+ value: 'start',
63
+ label: i18n._({ id: 'node.roof.glazingControls.start', message: 'Start' }),
64
+ },
65
+ {
66
+ value: 'center',
67
+ label: i18n._({ id: 'node.roof.glazingControls.center', message: 'Center' }),
68
+ },
69
+ {
70
+ value: 'end',
71
+ label: i18n._({ id: 'node.roof.glazingControls.end', message: 'End' }),
72
+ },
38
73
  ], onChange: (alignment) => patch({ alignment }, true) })] })), _jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: description })] }));
39
74
  }
40
75
  export function GlazingColor({ field, label, value, mixed, preview, }) {
41
- return (_jsxs("label", { className: "flex h-10 items-center justify-between gap-2 rounded-lg border border-border/50 bg-[#2C2C2E] px-3 text-xs", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-mono text-[11px] text-foreground", children: mixed ? 'Mixed' : value.toUpperCase() }), _jsx("input", { "aria-label": label, type: "color", value: value, className: "size-6 cursor-pointer overflow-hidden rounded border border-border/50 bg-transparent p-0 focus-visible:outline-2 focus-visible:outline-ring", onChange: (event) => preview.previewGlazing((config) => ({ ...config, [field]: event.target.value })), onBlur: preview.finish, onKeyDown: (event) => {
76
+ const i18n = usePascalI18n();
77
+ return (_jsxs("label", { className: "flex h-10 items-center justify-between gap-2 rounded-lg border border-border/50 bg-[#2C2C2E] px-3 text-xs", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-mono text-[11px] text-foreground", children: mixed
78
+ ? i18n._({ id: 'node.roof.glazingControls.mixed', message: 'Mixed' })
79
+ : value.toUpperCase() }), _jsx("input", { "aria-label": label, type: "color", value: value, className: "size-6 cursor-pointer overflow-hidden rounded border border-border/50 bg-transparent p-0 focus-visible:outline-2 focus-visible:outline-ring", onChange: (event) => preview.previewGlazing((config) => ({ ...config, [field]: event.target.value })), onBlur: preview.finish, onKeyDown: (event) => {
42
80
  if (event.key === 'Escape')
43
81
  preview.cancel();
44
82
  } })] })] }));
45
83
  }
46
84
  export const GLAZING_INFILL_OPTIONS = [
47
- { value: 'glass', label: 'Glass' },
48
- { value: 'solid', label: 'Solid' },
49
- { value: 'empty', label: 'Empty' },
85
+ { value: 'glass', label: /* i18n */ { id: 'node.roof.glazingControls.glass', message: 'Glass' } },
86
+ { value: 'solid', label: /* i18n */ { id: 'node.roof.glazingControls.solid', message: 'Solid' } },
87
+ { value: 'empty', label: /* i18n */ { id: 'node.roof.glazingControls.empty', message: 'Empty' } },
50
88
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"glazing-panel-editor.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-panel-editor.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAA;AAwBzB,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAA;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;CAChD,sCAmFA"}
1
+ {"version":3,"file":"glazing-panel-editor.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-panel-editor.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,eAAe,EAErB,MAAM,kBAAkB,CAAA;AA+BzB,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAA;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;CAChD,sCAoHA"}
@@ -1,23 +1,29 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { getGlazedRoofLayout, getGlazedRoofPanelType, getRoofGlazing, } from '@pascal-app/core';
3
+ import { getGlazedRoofLayout, getGlazedRoofPanelType, getRoofGlazing, usePascalI18n, } from '@pascal-app/core';
4
4
  import { ActionButton, PanelSection, SegmentedControl, SelectControl, SliderControl, } from '@pascal-app/editor';
5
5
  import { RotateCcw } from 'lucide-react';
6
6
  import { useState } from 'react';
7
7
  import { GLAZING_INFILL_OPTIONS } from './glazing-controls.js';
8
- function faceLabel(id) {
8
+ const FACE_LABELS = {
9
+ front: /* i18n */ { id: 'node.roof.glazing.face.front', message: 'Front slope' },
10
+ back: /* i18n */ { id: 'node.roof.glazing.face.back', message: 'Back slope' },
11
+ slope: /* i18n */ { id: 'node.roof.glazing.face.slope', message: 'Shed slope' },
12
+ 'end-left': /* i18n */ { id: 'node.roof.glazing.face.endLeft', message: 'Left end' },
13
+ 'end-right': /* i18n */ { id: 'node.roof.glazing.face.endRight', message: 'Right end' },
14
+ };
15
+ function faceLabel(id, i18n) {
9
16
  if (id.startsWith('barrel-'))
10
- return `Arch bay ${Number(id.slice(7)) + 1}`;
11
- const labels = {
12
- front: 'Front slope',
13
- back: 'Back slope',
14
- slope: 'Shed slope',
15
- 'end-left': 'Left end',
16
- 'end-right': 'Right end',
17
- };
18
- return labels[id] ?? id;
17
+ return i18n._({
18
+ id: 'node.roof.glazing.face.archBay',
19
+ message: 'Arch bay {number}',
20
+ values: { number: Number(id.slice(7)) + 1 },
21
+ });
22
+ const label = FACE_LABELS[id];
23
+ return label ? i18n._(label) : id;
19
24
  }
20
25
  export function GlazingPanelEditor({ node, onUpdate, }) {
26
+ const i18n = usePascalI18n();
21
27
  const [faceId, setFaceId] = useState('front');
22
28
  const [column, setColumn] = useState(0);
23
29
  const [row, setRow] = useState(0);
@@ -36,9 +42,30 @@ export function GlazingPanelEditor({ node, onUpdate, }) {
36
42
  ...(type ? [{ face: layout.face.id, column: activeColumn, row: activeRow, type }] : []),
37
43
  ],
38
44
  });
39
- return (_jsxs(PanelSection, { title: "Individual panels", defaultExpanded: false, children: [_jsx("p", { className: "pb-1 text-[11px] leading-relaxed text-muted-foreground", children: "Choose a panel to override its default infill." }), _jsx(SelectControl, { label: "Roof face", value: layout.face.id, options: layouts.map(({ face }) => ({ value: face.id, label: faceLabel(face.id) })), onChange: (value) => {
45
+ return (_jsxs(PanelSection, { title: i18n._({
46
+ id: 'node.roof.glazingPanelEditor.individualPanels',
47
+ message: 'Individual panels',
48
+ }), defaultExpanded: false, children: [_jsx("p", { className: "pb-1 text-[11px] leading-relaxed text-muted-foreground", children: i18n._({
49
+ id: 'node.roof.glazingPanelEditor.chooseAPanelToOverrideIts',
50
+ message: 'Choose a panel to override its default infill.',
51
+ }) }), _jsx(SelectControl, { label: i18n._({ id: 'node.roof.glazingPanelEditor.roofFace', message: 'Roof face' }), value: layout.face.id, options: layouts.map(({ face }) => ({ value: face.id, label: faceLabel(face.id, i18n) })), onChange: (value) => {
40
52
  setFaceId(value);
41
53
  setColumn(0);
42
54
  setRow(0);
43
- } }), _jsxs("p", { className: "py-1 text-[11px] text-muted-foreground", children: [columns, " ", columns === 1 ? 'column' : 'columns', " \u00B7 ", rows, " ", rows === 1 ? 'row' : 'rows'] }), columns > 1 && (_jsx(SliderControl, { label: "Column", value: activeColumn + 1, min: 1, max: columns, step: 1, precision: 0, onChange: (value) => setColumn(Math.round(value) - 1) })), rows > 1 && (_jsx(SliderControl, { label: "Row", value: activeRow + 1, min: 1, max: rows, step: 1, precision: 0, onChange: (value) => setRow(Math.round(value) - 1) })), _jsxs("div", { className: "flex flex-col gap-2 pt-1", role: "group", "aria-label": "Selected panel infill", children: [_jsxs("span", { className: "flex items-center justify-between text-xs text-muted-foreground", children: ["Panel infill ", _jsx("span", { className: "text-[11px]", children: overridden ? 'Custom' : 'Default' })] }), _jsx(SegmentedControl, { value: getGlazedRoofPanelType(node, layout.face.id, activeColumn, activeRow), options: GLAZING_INFILL_OPTIONS, onChange: (type) => update(type) })] }), _jsx(ActionButton, { label: "Reset to default", icon: _jsx(RotateCcw, { className: "size-3.5" }), disabled: !overridden, className: "mt-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-[#2C2C2E]", onClick: () => update() })] }));
55
+ } }), _jsx("p", { className: "py-1 text-[11px] text-muted-foreground", children: i18n._({
56
+ id: 'node.roof.glazingPanelEditor.grid',
57
+ message: '{columns, plural, one {{columnCount} column} other {{columnCount} columns}} · {rows, plural, one {{rowCount} row} other {{rowCount} rows}}',
58
+ values: { columns, rows, columnCount: String(columns), rowCount: String(rows) },
59
+ }) }), columns > 1 && (_jsx(SliderControl, { label: i18n._({ id: 'node.roof.glazingPanelEditor.column2', message: 'Column' }), value: activeColumn + 1, min: 1, max: columns, step: 1, precision: 0, onChange: (value) => setColumn(Math.round(value) - 1) })), rows > 1 && (_jsx(SliderControl, { label: i18n._({ id: 'node.roof.glazingPanelEditor.row2', message: 'Row' }), value: activeRow + 1, min: 1, max: rows, step: 1, precision: 0, onChange: (value) => setRow(Math.round(value) - 1) })), _jsxs("div", { className: "flex flex-col gap-2 pt-1", role: "group", "aria-label": i18n._({
60
+ id: 'node.roof.glazingPanelEditor.selectedPanelInfill',
61
+ message: 'Selected panel infill',
62
+ }), children: [_jsxs("span", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [i18n._({ id: 'node.roof.glazingPanelEditor.panelInfill', message: 'Panel infill' }), ' ', _jsx("span", { className: "text-[11px]", children: overridden
63
+ ? i18n._({ id: 'node.roof.glazingPanelEditor.custom', message: 'Custom' })
64
+ : i18n._({ id: 'node.roof.glazingPanelEditor.default', message: 'Default' }) })] }), _jsx(SegmentedControl, { value: getGlazedRoofPanelType(node, layout.face.id, activeColumn, activeRow), options: GLAZING_INFILL_OPTIONS.map((option) => ({
65
+ ...option,
66
+ label: i18n._(option.label),
67
+ })), onChange: (type) => update(type) })] }), _jsx(ActionButton, { label: i18n._({
68
+ id: 'node.roof.glazingPanelEditor.resetToDefault',
69
+ message: 'Reset to default',
70
+ }), icon: _jsx(RotateCcw, { className: "size-3.5" }), disabled: !overridden, className: "mt-1 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-[#2C2C2E]", onClick: () => update() })] }));
44
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"glazing-panel.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAA;AAazB,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAA;CAAE,sCAuKtF"}
1
+ {"version":3,"file":"glazing-panel.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AAazB,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAA;CAAE,sCAmPtF"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { getEffectiveNode, getRoofGlazing, isGlazedRoofSegment, supportsRoofGlazing, useLiveNodeOverrides, } from '@pascal-app/core';
3
+ import { getEffectiveNode, getRoofGlazing, isGlazedRoofSegment, supportsRoofGlazing, useLiveNodeOverrides, usePascalI18n, } from '@pascal-app/core';
4
4
  import { PanelSection, SegmentedControl, ToggleControl } from '@pascal-app/editor';
5
5
  import { useEffect, useMemo } from 'react';
6
6
  import { useShallow } from 'zustand/react/shallow';
@@ -8,6 +8,7 @@ import { GLAZING_INFILL_OPTIONS, GlazingColor, GlazingGridControls, GlazingNumbe
8
8
  import { GlazingPanelEditor } from './glazing-panel-editor.js';
9
9
  import { createRoofGlazingPreview } from './glazing-preview.js';
10
10
  export function RoofGlazingPanel({ segments }) {
11
+ const i18n = usePascalI18n();
11
12
  useLiveNodeOverrides(useShallow((state) => segments.map((segment) => state.overrides.get(segment.id))));
12
13
  const idKey = segments.map((segment) => segment.id).join(',');
13
14
  const preview = useMemo(() => createRoofGlazingPreview(idKey ? idKey.split(',') : []), [idKey]);
@@ -27,15 +28,78 @@ export function RoofGlazingPanel({ segments }) {
27
28
  preview.previewGlazing((current) => ({ ...current, ...patch }));
28
29
  preview.commit();
29
30
  };
30
- return (_jsxs(_Fragment, { children: [_jsxs(PanelSection, { title: "Roof system", children: [_jsx(SegmentedControl, { value: glazed ? 'glazed' : 'standard', mixed: mixed, options: [
31
- { value: 'standard', label: 'Standard' },
32
- { value: 'glazed', label: 'Glazed', disabled: !supported },
31
+ return (_jsxs(_Fragment, { children: [_jsxs(PanelSection, { title: i18n._({ id: 'node.roof.glazingPanel.roofSystem', message: 'Roof system' }), children: [_jsx(SegmentedControl, { value: glazed ? 'glazed' : 'standard', mixed: mixed, options: [
32
+ {
33
+ value: 'standard',
34
+ label: i18n._({ id: 'node.roof.glazingPanel.standard', message: 'Standard' }),
35
+ },
36
+ {
37
+ value: 'glazed',
38
+ label: i18n._({ id: 'node.roof.glazingPanel.glazed', message: 'Glazed' }),
39
+ disabled: !supported,
40
+ },
33
41
  ], onChange: (roofSystem) => {
34
42
  if (roofSystem === 'standard' || supported)
35
43
  preview.commit({ roofSystem });
36
- } }), !supported && (_jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: "Glazing is available for gable, straight shed, and barrel roofs." })), mixed && (_jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: "Choose one roof system to edit settings for all selected segments." })), segments.length > 1 && (_jsxs("p", { className: "pt-1 text-[11px] text-muted-foreground", children: ["Changes apply to all ", segments.length, " roof segments."] }))] }), glazed && !mixed && (_jsxs(_Fragment, { children: [_jsx(GlazingGridControls, { axis: "across", title: allBarrel ? 'Grid along the length' : 'Grid across the roof', description: allBarrel
37
- ? 'Divides the length of each arch bay into columns.'
38
- : 'Divides each roof face into columns.', grid: config.across, grids: configs.map((value) => value.across), preview: preview }), _jsx(GlazingGridControls, { axis: "along", title: allBarrel ? 'Grid within each arch bay' : 'Grid along the slope', description: allBarrel
39
- ? 'Subdivides each flat arch bay. Arch bays controls the divisions around the curve.'
40
- : 'Spacing is measured on the slope, not its horizontal projection.', grid: config.along, grids: configs.map((value) => value.along), preview: preview }), _jsxs(PanelSection, { title: "Framing", children: [_jsx(GlazingNumber, { field: "frameWidth", label: "Frame width", value: config.frameWidth, mixed: mixedField('frameWidth'), preview: preview }), _jsx(GlazingNumber, { field: "frameDepth", label: "Frame depth", value: config.frameDepth, mixed: mixedField('frameDepth'), preview: preview }), _jsx(GlazingColor, { field: "frameColor", label: "Frame color", value: config.frameColor, mixed: mixedField('frameColor'), preview: preview })] }), _jsxs(PanelSection, { title: "Glass", children: [_jsx(GlazingNumber, { field: "glassThickness", label: "Pane thickness", value: config.glassThickness, mixed: mixedField('glassThickness'), preview: preview }), _jsx(GlazingColor, { field: "glassColor", label: "Glass tint", value: config.glassColor, mixed: mixedField('glassColor'), preview: preview }), _jsx(GlazingNumber, { field: "glassOpacity", label: "Opacity", value: config.glassOpacity, mixed: mixedField('glassOpacity'), preview: preview, fraction: true }), _jsx(GlazingNumber, { field: "glassRoughness", label: "Roughness", value: config.glassRoughness, mixed: mixedField('glassRoughness'), preview: preview, fraction: true })] }), _jsxs(PanelSection, { title: "Infill", children: [_jsxs("div", { className: "flex flex-col gap-2 pb-1", role: "group", "aria-label": "Default panel infill", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: "Default panel infill" }), _jsx(SegmentedControl, { value: config.panelType, mixed: mixedField('panelType'), options: GLAZING_INFILL_OPTIONS, onChange: (panelType) => update({ panelType }) })] }), _jsx(ToggleControl, { label: "Close the roof ends", checked: config.glazedEnds, mixed: mixedField('glazedEnds'), onChange: (glazedEnds) => update({ glazedEnds }) }), _jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: "End infill fills the space above the walls. Edit room walls and ceilings separately." })] }), segments.length === 1 && (_jsx(GlazingPanelEditor, { node: node, onUpdate: update }, node.id))] }))] }));
44
+ } }), !supported && (_jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: i18n._({
45
+ id: 'node.roof.glazingPanel.glazingIsAvailableForGableStraight',
46
+ message: 'Glazing is available for gable, straight shed, and barrel roofs.',
47
+ }) })), mixed && (_jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: i18n._({
48
+ id: 'node.roof.glazingPanel.chooseOneRoofSystemToEdit',
49
+ message: 'Choose one roof system to edit settings for all selected segments.',
50
+ }) })), segments.length > 1 && (_jsx("p", { className: "pt-1 text-[11px] text-muted-foreground", children: i18n._({
51
+ id: 'node.roof.glazingPanel.changesApplyToAllLengthRoof',
52
+ message: 'Changes apply to all {length} roof segments.',
53
+ values: { length: segments.length },
54
+ }) }))] }), glazed && !mixed && (_jsxs(_Fragment, { children: [_jsx(GlazingGridControls, { axis: "across", title: allBarrel
55
+ ? i18n._({
56
+ id: 'node.roof.glazingPanel.gridAlongTheLength',
57
+ message: 'Grid along the length',
58
+ })
59
+ : i18n._({
60
+ id: 'node.roof.glazingPanel.gridAcrossTheRoof',
61
+ message: 'Grid across the roof',
62
+ }), description: allBarrel
63
+ ? i18n._({
64
+ id: 'node.roof.glazingPanel.dividesTheLengthOfEachArch',
65
+ message: 'Divides the length of each arch bay into columns.',
66
+ })
67
+ : i18n._({
68
+ id: 'node.roof.glazingPanel.dividesEachRoofFaceIntoColumns',
69
+ message: 'Divides each roof face into columns.',
70
+ }), grid: config.across, grids: configs.map((value) => value.across), preview: preview }), _jsx(GlazingGridControls, { axis: "along", title: allBarrel
71
+ ? i18n._({
72
+ id: 'node.roof.glazingPanel.gridWithinEachArchBay',
73
+ message: 'Grid within each arch bay',
74
+ })
75
+ : i18n._({
76
+ id: 'node.roof.glazingPanel.gridAlongTheSlope',
77
+ message: 'Grid along the slope',
78
+ }), description: allBarrel
79
+ ? i18n._({
80
+ id: 'node.roof.glazingPanel.subdividesEachFlatArchBayArch',
81
+ message: 'Subdivides each flat arch bay. Arch bays controls the divisions around the curve.',
82
+ })
83
+ : i18n._({
84
+ id: 'node.roof.glazingPanel.spacingIsMeasuredOnTheSlope',
85
+ message: 'Spacing is measured on the slope, not its horizontal projection.',
86
+ }), grid: config.along, grids: configs.map((value) => value.along), preview: preview }), _jsxs(PanelSection, { title: i18n._({ id: 'node.roof.glazingPanel.framing', message: 'Framing' }), children: [_jsx(GlazingNumber, { field: "frameWidth", label: i18n._({ id: 'node.roof.glazingPanel.frameWidth', message: 'Frame width' }), value: config.frameWidth, mixed: mixedField('frameWidth'), preview: preview }), _jsx(GlazingNumber, { field: "frameDepth", label: i18n._({ id: 'node.roof.glazingPanel.frameDepth', message: 'Frame depth' }), value: config.frameDepth, mixed: mixedField('frameDepth'), preview: preview }), _jsx(GlazingColor, { field: "frameColor", label: i18n._({ id: 'node.roof.glazingPanel.frameColor', message: 'Frame color' }), value: config.frameColor, mixed: mixedField('frameColor'), preview: preview })] }), _jsxs(PanelSection, { title: i18n._({ id: 'node.roof.glazingPanel.glass', message: 'Glass' }), children: [_jsx(GlazingNumber, { field: "glassThickness", label: i18n._({
87
+ id: 'node.roof.glazingPanel.paneThickness',
88
+ message: 'Pane thickness',
89
+ }), value: config.glassThickness, mixed: mixedField('glassThickness'), preview: preview }), _jsx(GlazingColor, { field: "glassColor", label: i18n._({ id: 'node.roof.glazingPanel.glassTint', message: 'Glass tint' }), value: config.glassColor, mixed: mixedField('glassColor'), preview: preview }), _jsx(GlazingNumber, { field: "glassOpacity", label: i18n._({ id: 'node.roof.glazingPanel.opacity', message: 'Opacity' }), value: config.glassOpacity, mixed: mixedField('glassOpacity'), preview: preview, fraction: true }), _jsx(GlazingNumber, { field: "glassRoughness", label: i18n._({ id: 'node.roof.glazingPanel.roughness', message: 'Roughness' }), value: config.glassRoughness, mixed: mixedField('glassRoughness'), preview: preview, fraction: true })] }), _jsxs(PanelSection, { title: i18n._({ id: 'node.roof.glazingPanel.infill', message: 'Infill' }), children: [_jsxs("div", { className: "flex flex-col gap-2 pb-1", role: "group", "aria-label": i18n._({
90
+ id: 'node.roof.glazingPanel.defaultPanelInfill',
91
+ message: 'Default panel infill',
92
+ }), children: [_jsx("span", { className: "text-xs text-muted-foreground", children: i18n._({
93
+ id: 'node.roof.glazingPanel.defaultPanelInfill',
94
+ message: 'Default panel infill',
95
+ }) }), _jsx(SegmentedControl, { value: config.panelType, mixed: mixedField('panelType'), options: GLAZING_INFILL_OPTIONS.map((option) => ({
96
+ ...option,
97
+ label: i18n._(option.label),
98
+ })), onChange: (panelType) => update({ panelType }) })] }), _jsx(ToggleControl, { label: i18n._({
99
+ id: 'node.roof.glazingPanel.closeTheRoofEnds',
100
+ message: 'Close the roof ends',
101
+ }), checked: config.glazedEnds, mixed: mixedField('glazedEnds'), onChange: (glazedEnds) => update({ glazedEnds }) }), _jsx("p", { className: "pt-1 text-[11px] leading-relaxed text-muted-foreground", children: i18n._({
102
+ id: 'node.roof.glazingPanel.endInfillFillsTheSpaceAbove',
103
+ message: 'End infill fills the space above the walls. Edit room walls and ceilings separately.',
104
+ }) })] }), segments.length === 1 && (_jsx(GlazingPanelEditor, { node: node, onUpdate: update }, node.id))] }))] }));
41
105
  }
@@ -0,0 +1,19 @@
1
+ import { type AnyNodeId, type PaintCapability } from '@pascal-app/core';
2
+ type RoofGableBand = 'gable-left' | 'gable-right';
3
+ /** Every gable of the roof: the `matching` scope of a gable hit. */
4
+ export declare const ROOF_ALL_GABLES_ROLE = "gables:all";
5
+ /** One gable of the merged shell: `gable-left:<segmentId>` / `gable-right:<segmentId>`. */
6
+ export declare function roofGableRole(band: RoofGableBand, segmentId: string): string;
7
+ export declare function parseRoofGableRole(role: string): {
8
+ band: RoofGableBand;
9
+ segmentId: AnyNodeId;
10
+ } | null;
11
+ /**
12
+ * The merged roof shell's paint. Its surfaces are the roof's top / edge / wall
13
+ * finishes and the heel band; an edge hit on a segment's ±x end wall is that
14
+ * gable alone (its segment's gable finish), and the `matching` scope widens it
15
+ * to every gable — the roof's edge, with no segment keeping a gable of its own.
16
+ */
17
+ export declare const roofPaint: PaintCapability;
18
+ export {};
19
+ //# sourceMappingURL=paint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/roof/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAId,KAAK,eAAe,EAKrB,MAAM,kBAAkB,CAAA;AAazB,KAAK,aAAa,GAAG,YAAY,GAAG,aAAa,CAAA;AAEjD,oEAAoE;AACpE,eAAO,MAAM,oBAAoB,eAAe,CAAA;AAEhD,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAMtD;AAqCD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,eA8GvB,CAAA"}
@@ -0,0 +1,158 @@
1
+ import { getEffectiveRoofSurfaceMaterial, getEffectiveSegmentSurfaceMaterial, getRoofWallBandMaterial, useScene, } from '@pascal-app/core';
2
+ import { buildRoofSurfaceMaterialPatch, resolveRoofWallHit } from '@pascal-app/editor';
3
+ import { getRoofMaterialArray, levelWallCladdingRef, levelWallFaceRef, ROOF_HEEL_MATERIAL_INDEX, useViewer, } from '@pascal-app/viewer';
4
+ import { Vector3 } from 'three';
5
+ import { wallBandPatch } from '../roof-segment/paint.js';
6
+ import { swapPreviewMaterial } from '../shared/swap-preview-material.js';
7
+ /** Every gable of the roof: the `matching` scope of a gable hit. */
8
+ export const ROOF_ALL_GABLES_ROLE = 'gables:all';
9
+ /** One gable of the merged shell: `gable-left:<segmentId>` / `gable-right:<segmentId>`. */
10
+ export function roofGableRole(band, segmentId) {
11
+ return `${band}:${segmentId}`;
12
+ }
13
+ export function parseRoofGableRole(role) {
14
+ const split = role.indexOf(':');
15
+ if (split < 0)
16
+ return null;
17
+ const band = role.slice(0, split);
18
+ if (band !== 'gable-left' && band !== 'gable-right')
19
+ return null;
20
+ return { band, segmentId: role.slice(split + 1) };
21
+ }
22
+ const isSurfaceRole = (role) => role === 'top' || role === 'edge' || role === 'wall';
23
+ const hitWorldPoint = new Vector3();
24
+ /** The merged shell's surface under the cursor: its material slot, else the hit normal. */
25
+ function surfaceRole(materialIndex, normal) {
26
+ if (materialIndex === 3)
27
+ return 'top';
28
+ if (materialIndex === ROOF_HEEL_MATERIAL_INDEX)
29
+ return 'heel';
30
+ if (materialIndex === 0)
31
+ return 'edge';
32
+ if (materialIndex === 1 || materialIndex === 2)
33
+ return 'wall';
34
+ const normalY = normal?.[1];
35
+ if (normalY !== undefined && normalY > 0.35)
36
+ return 'top';
37
+ if (normalY !== undefined && Math.abs(normalY) <= 0.35)
38
+ return 'edge';
39
+ if (normalY !== undefined && normalY < -0.35)
40
+ return 'wall';
41
+ return null;
42
+ }
43
+ /** The merged roof with `role` repainted, so the preview draws it the way a commit would. */
44
+ function previewRoof(roof, role, material, preset) {
45
+ if (role === 'heel')
46
+ return { ...roof, ...wallBandPatch('heel', material, preset) };
47
+ const surface = role === ROOF_ALL_GABLES_ROLE ? 'edge' : role;
48
+ if (!isSurfaceRole(surface))
49
+ return null;
50
+ return { ...roof, ...buildRoofSurfaceMaterialPatch(roof, surface, material, preset) };
51
+ }
52
+ /**
53
+ * The merged roof shell's paint. Its surfaces are the roof's top / edge / wall
54
+ * finishes and the heel band; an edge hit on a segment's ±x end wall is that
55
+ * gable alone (its segment's gable finish), and the `matching` scope widens it
56
+ * to every gable — the roof's edge, with no segment keeping a gable of its own.
57
+ */
58
+ export const roofPaint = {
59
+ materialTarget: 'roof',
60
+ resolveRole(args) {
61
+ const role = surfaceRole(args.materialIndex, args.normal);
62
+ if (role !== 'edge' || !(args.localPosition && args.hitObject))
63
+ return role;
64
+ args.hitObject.updateWorldMatrix(true, false);
65
+ const position = args.hitObject.localToWorld(hitWorldPoint.set(...args.localPosition));
66
+ const hit = resolveRoofWallHit(args.node, [position.x, position.y, position.z], args.normal, args.hitObject);
67
+ if (!hit || (hit.face.id !== 'left' && hit.face.id !== 'right'))
68
+ return role;
69
+ return roofGableRole(hit.face.id === 'left' ? 'gable-left' : 'gable-right', hit.segment.id);
70
+ },
71
+ roleLabel(_node, role) {
72
+ if (role === 'heel')
73
+ return 'Heel band';
74
+ if (role === ROOF_ALL_GABLES_ROLE)
75
+ return 'All gables';
76
+ const gable = parseRoofGableRole(role);
77
+ if (!gable)
78
+ return null;
79
+ return gable.band === 'gable-left' ? 'Left gable' : 'Right gable';
80
+ },
81
+ scopes(_node, role) {
82
+ if (!parseRoofGableRole(role))
83
+ return null;
84
+ return {
85
+ scopes: ['single', 'matching'],
86
+ labels: { matching: 'All gables' },
87
+ roleFor: (scope) => (scope === 'matching' ? ROOF_ALL_GABLES_ROLE : role),
88
+ };
89
+ },
90
+ buildPatch({ node, role, material, materialPreset }) {
91
+ const roof = node;
92
+ if (role === 'heel')
93
+ return wallBandPatch('heel', material, materialPreset);
94
+ if (role === ROOF_ALL_GABLES_ROLE)
95
+ return buildRoofSurfaceMaterialPatch(roof, 'edge', material, materialPreset);
96
+ if (!isSurfaceRole(role))
97
+ return {};
98
+ return buildRoofSurfaceMaterialPatch(roof, role, material, materialPreset);
99
+ },
100
+ commit(args) {
101
+ const scene = useScene.getState();
102
+ const gable = parseRoofGableRole(args.role);
103
+ if (gable) {
104
+ scene.updateNode(gable.segmentId, wallBandPatch(gable.band, args.material, args.materialPreset));
105
+ return;
106
+ }
107
+ if (args.role !== ROOF_ALL_GABLES_ROLE) {
108
+ scene.updateNode(args.node.id, roofPaint.buildPatch(args));
109
+ return;
110
+ }
111
+ // Every gable: the roof's edge, and no segment keeping a gable of its own.
112
+ const cleared = {
113
+ ...wallBandPatch('gable-left', undefined, undefined),
114
+ ...wallBandPatch('gable-right', undefined, undefined),
115
+ };
116
+ scene.updateNodes([
117
+ { id: args.node.id, data: roofPaint.buildPatch(args) },
118
+ ...(args.node.children ?? []).flatMap((childId) => scene.nodes[childId]?.type === 'roof-segment'
119
+ ? [{ id: childId, data: cleared }]
120
+ : []),
121
+ ]);
122
+ },
123
+ applyPreview(args) {
124
+ // One gable has no surface of its own on the merged shell until it is painted.
125
+ if (parseRoofGableRole(args.role))
126
+ return null;
127
+ const mesh = args.root.getObjectByName('merged-roof');
128
+ if (!mesh)
129
+ return null;
130
+ const roof = args.node;
131
+ const preview = previewRoof(roof, args.role, args.material, args.materialPreset);
132
+ if (!preview)
133
+ return null;
134
+ // The renderer's wall-derived defaults, so the surfaces not being painted hold still.
135
+ const nodes = args.nodes ?? useScene.getState().nodes;
136
+ const viewer = useViewer.getState();
137
+ const material = getRoofMaterialArray(preview, viewer.shading, viewer.textures, viewer.colorPreset, viewer.sceneTheme, levelWallCladdingRef(nodes, roof), args.materials ?? useScene.getState().materials, levelWallFaceRef(nodes, roof));
138
+ return material ? swapPreviewMaterial(mesh, material) : null;
139
+ },
140
+ // The top / edge / wall finishes return null here and resolve through the
141
+ // editor's roof surface fallback (`resolveActivePaintMaterialFromSelection`).
142
+ getEffectiveMaterial({ node, role, nodes }) {
143
+ if (role === 'heel') {
144
+ const own = getRoofWallBandMaterial(node, 'heel');
145
+ return own ? { material: own.material, materialPreset: own.materialPreset } : null;
146
+ }
147
+ const gable = parseRoofGableRole(role);
148
+ const segment = gable ? nodes?.[gable.segmentId] : undefined;
149
+ if (!(gable && segment?.type === 'roof-segment'))
150
+ return null;
151
+ // Unpainted, a gable shows the segment's edge, falling back to the roof's.
152
+ const own = getRoofWallBandMaterial(segment, gable.band);
153
+ if (own)
154
+ return { material: own.material, materialPreset: own.materialPreset };
155
+ const edge = getEffectiveSegmentSurfaceMaterial(segment, 'edge', getEffectiveRoofSurfaceMaterial(node, 'edge'));
156
+ return { material: edge.material, materialPreset: edge.materialPreset };
157
+ },
158
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof/panel.tsx"],"names":[],"mappings":"AA0CA,MAAM,CAAC,OAAO,UAAU,SAAS,uCA8jBhC"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof/panel.tsx"],"names":[],"mappings":"AAiDA,MAAM,CAAC,OAAO,UAAU,SAAS,uCAqsBhC"}