@pascal-app/editor 1.0.1 → 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 (498) hide show
  1. package/package.json +16 -9
  2. package/src/components/editor/action-menu-button.tsx +83 -0
  3. package/src/components/editor/bake-thumbnail.tsx +315 -4
  4. package/src/components/editor/capture-level-picker.tsx +72 -0
  5. package/src/components/editor/custom-camera-controls.tsx +221 -128
  6. package/src/components/editor/delete-confirmation-dialog.tsx +297 -7
  7. package/src/components/editor/duplicate-node.ts +244 -0
  8. package/src/components/editor/editor-layout-mobile.tsx +37 -25
  9. package/src/components/editor/editor-layout-v2.tsx +131 -58
  10. package/src/components/editor/export-manager.tsx +34 -8
  11. package/src/components/editor/first-person/build-collider-world.test.ts +51 -0
  12. package/src/components/editor/first-person/build-collider-world.ts +6 -2
  13. package/src/components/editor/first-person/mechanism-targets.test.ts +75 -0
  14. package/src/components/editor/first-person/mechanism-targets.ts +36 -0
  15. package/src/components/editor/first-person-controls.tsx +205 -2
  16. package/src/components/editor/floating-action-menu.tsx +63 -207
  17. package/src/components/editor/floor-aware-camera-controls.test.ts +442 -0
  18. package/src/components/editor/floor-aware-camera-controls.ts +324 -0
  19. package/src/components/editor/floor-openings-overlay.tsx +243 -0
  20. package/src/components/editor/floor-region-controls.tsx +846 -0
  21. package/src/components/editor/floor-region-webgpu-materials.test.ts +12 -0
  22. package/src/components/editor/floor-surface.test.ts +165 -0
  23. package/src/components/editor/floor-surface.ts +182 -0
  24. package/src/components/editor/floorplan-background-selection.test.ts +11 -2
  25. package/src/components/editor/floorplan-background-selection.ts +1 -3
  26. package/src/components/editor/floorplan-panel.tsx +536 -487
  27. package/src/components/editor/footprint-height-handle.tsx +204 -0
  28. package/src/components/editor/grid.tsx +31 -7
  29. package/src/components/editor/group-actions.ts +59 -11
  30. package/src/components/editor/group-floating-action-menu.tsx +19 -9
  31. package/src/components/editor/group-move-3d.ts +4 -6
  32. package/src/components/editor/group-rotate-handle.tsx +81 -35
  33. package/src/components/editor/group-selection-box-3d.tsx +25 -17
  34. package/src/components/editor/group-transform-shared.test.ts +126 -1
  35. package/src/components/editor/group-transform-shared.ts +79 -73
  36. package/src/components/editor/handles/handle-arrow.tsx +72 -2
  37. package/src/components/editor/handles/handle-hit-priority.test.tsx +63 -0
  38. package/src/components/editor/handles/handle-hit-priority.tsx +37 -0
  39. package/src/components/editor/handles/swallow-next-click.test.ts +28 -0
  40. package/src/components/editor/handles/use-handle-drag.ts +272 -131
  41. package/src/components/editor/index.tsx +316 -176
  42. package/src/components/editor/join-walls-pill.tsx +44 -0
  43. package/src/components/editor/node-action-menu.tsx +70 -70
  44. package/src/components/editor/node-arrow-handles.tsx +167 -14
  45. package/src/components/editor/open-wall-ends-3d-layer.tsx +273 -0
  46. package/src/components/editor/open-wall-ends-hint.tsx +89 -0
  47. package/src/components/editor/quick-measurement-hud.tsx +3 -2
  48. package/src/components/editor/registry-action-contributions.test.tsx +63 -0
  49. package/src/components/editor/registry-action-contributions.tsx +132 -0
  50. package/src/components/editor/room-controls.tsx +847 -0
  51. package/src/components/editor/room-floor-highlight.tsx +128 -0
  52. package/src/components/editor/room-handles-2d.tsx +354 -0
  53. package/src/components/editor/room-handles.tsx +675 -0
  54. package/src/components/editor/room-highlight.tsx +225 -0
  55. package/src/components/editor/room-labels.test.ts +357 -0
  56. package/src/components/editor/room-labels.tsx +990 -0
  57. package/src/components/editor/room-transform-ghost.tsx +256 -0
  58. package/src/components/editor/room-webgpu-materials.test.ts +27 -0
  59. package/src/components/editor/selection-manager.tsx +451 -317
  60. package/src/components/editor/slab-hole-highlights.tsx +3 -0
  61. package/src/components/editor/snapshot-capture-overlay.tsx +4 -0
  62. package/src/components/editor/snapshot-capture.test.ts +52 -4
  63. package/src/components/editor/snapshot-capture.ts +30 -5
  64. package/src/components/editor/thumbnail-generator.test.ts +308 -0
  65. package/src/components/editor/thumbnail-generator.tsx +1035 -229
  66. package/src/components/editor/use-floorplan-background-placement.ts +31 -11
  67. package/src/components/editor/vector-edge-extractor.tsx +121 -0
  68. package/src/components/editor/views/host-view.tsx +61 -0
  69. package/src/components/editor/views/plugins-view.tsx +670 -0
  70. package/src/components/editor/views/scene-region.tsx +59 -0
  71. package/src/components/editor/views/use-editor-views.ts +57 -0
  72. package/src/components/editor/views/view-bar.tsx +220 -0
  73. package/src/components/editor/wall-justification.test.ts +140 -0
  74. package/src/components/editor/wall-move-side-handles.tsx +114 -163
  75. package/src/components/editor/wall-opening-highlights.tsx +2 -3
  76. package/src/components/editor/wall-push-arrow.tsx +92 -0
  77. package/src/components/editor/wall-region-handles.tsx +509 -0
  78. package/src/components/editor/wall-snap-beacon-layer.tsx +3 -0
  79. package/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +8 -4
  80. package/src/components/editor-2d/floorplan-group-move.tsx +17 -24
  81. package/src/components/editor-2d/floorplan-open-wall-ends-layer.test.tsx +86 -0
  82. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +290 -0
  83. package/src/components/editor-2d/floorplan-registered-tool-layer.tsx +33 -12
  84. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +11 -1
  85. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +242 -126
  86. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.test.ts +156 -0
  87. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +278 -0
  88. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +77 -0
  89. package/src/components/editor-2d/renderers/floorplan-draft-measurement.tsx +166 -0
  90. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +4 -1
  91. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +87 -8
  92. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +355 -245
  93. package/src/components/editor-2d/svg-paths.ts +12 -15
  94. package/src/components/procedural-items/inspector.tsx +40 -15
  95. package/src/components/systems/ceiling/ceiling-selection-affordance-system.test.ts +97 -14
  96. package/src/components/systems/ceiling/ceiling-selection-affordance-system.tsx +18 -18
  97. package/src/components/systems/zone/zone-system.test.ts +47 -0
  98. package/src/components/systems/zone/zone-system.tsx +31 -66
  99. package/src/components/tools/__fixtures__/hosting.ts +10 -0
  100. package/src/components/tools/item/item-surface-placement.test.ts +3 -9
  101. package/src/components/tools/item/item-surface-strategy-resolver.test.ts +3 -9
  102. package/src/components/tools/item/placement-history.test.tsx +474 -0
  103. package/src/components/tools/item/placement-strategies.ts +63 -47
  104. package/src/components/tools/item/shelf-surface-strategy-resolver.test.ts +3 -3
  105. package/src/components/tools/item/use-draft-node.test.tsx +432 -1
  106. package/src/components/tools/item/use-draft-node.ts +207 -97
  107. package/src/components/tools/item/use-placement-coordinator.tsx +251 -111
  108. package/src/components/tools/paint-region/use-paint-tint.ts +37 -0
  109. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +466 -0
  110. package/src/components/tools/registry/item-surface-move.test.ts +10 -2
  111. package/src/components/tools/registry/item-surface-move.ts +46 -24
  112. package/src/components/tools/registry/item-surface-resolver.test.ts +2 -2
  113. package/src/components/tools/registry/move-registry-node-tool.tsx +26 -10
  114. package/src/components/tools/select/box-select-tool.tsx +2 -12
  115. package/src/components/tools/select/plane-box-select-tool.test.tsx +79 -0
  116. package/src/components/tools/select/plane-box-select-tool.tsx +35 -22
  117. package/src/components/tools/select/select-candidates.test.ts +37 -4
  118. package/src/components/tools/select/select-candidates.ts +15 -11
  119. package/src/components/tools/shared/affordance-dispatch.test.ts +24 -0
  120. package/src/components/tools/shared/affordance-dispatch.ts +13 -0
  121. package/src/components/tools/shared/cursor-sphere.tsx +36 -12
  122. package/src/components/tools/shared/draft-measurement-label.tsx +38 -0
  123. package/src/components/tools/shared/pointer-support-cap.test.ts +27 -0
  124. package/src/components/tools/shared/pointer-support-cap.ts +17 -5
  125. package/src/components/tools/shared/surface-rejection.test.tsx +5 -4
  126. package/src/components/tools/shared/surface-rejection.tsx +14 -0
  127. package/src/components/tools/site/site-boundary-editor.tsx +1 -2
  128. package/src/components/tools/stair/stair-defaults.ts +0 -3
  129. package/src/components/tools/stair/stair-tool.tsx +90 -42
  130. package/src/components/tools/tool-manager.tsx +82 -23
  131. package/src/components/tools/wall/wall-drafting.test.ts +19 -4
  132. package/src/components/tools/zone/zone-tool.tsx +4 -12
  133. package/src/components/ui/action-menu/action-button.tsx +3 -0
  134. package/src/components/ui/action-menu/camera-actions.tsx +2 -1
  135. package/src/components/ui/action-menu/control-modes.tsx +2 -35
  136. package/src/components/ui/action-menu/measurement-control.tsx +3 -10
  137. package/src/components/ui/build-panel/build-panel.tsx +235 -0
  138. package/src/components/ui/command-palette/editor-commands.tsx +4 -30
  139. package/src/components/ui/command-palette/index.tsx +5 -24
  140. package/src/components/ui/controls/finish-swatch.tsx +110 -0
  141. package/src/components/ui/controls/material-paint-panel.tsx +101 -91
  142. package/src/components/ui/controls/material-picker.tsx +8 -67
  143. package/src/components/ui/controls/scene-material-list.tsx +4 -32
  144. package/src/components/ui/controls/select-control.tsx +65 -0
  145. package/src/components/ui/controls/slider-control.tsx +76 -31
  146. package/src/components/ui/floating-level-selector.tsx +9 -14
  147. package/src/components/ui/helpers/building-helper.tsx +4 -1
  148. package/src/components/ui/helpers/contextual-helper-panel.tsx +154 -70
  149. package/src/components/ui/helpers/helper-manager.test.tsx +69 -0
  150. package/src/components/ui/helpers/helper-manager.tsx +348 -19
  151. package/src/components/ui/helpers/item-helper.tsx +8 -0
  152. package/src/components/ui/helpers/registered-tool-helper.tsx +10 -33
  153. package/src/components/ui/icon-ref.tsx +45 -1
  154. package/src/components/ui/item-catalog/item-catalog.tsx +5 -30
  155. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  156. package/src/components/ui/node-icon-image.tsx +16 -0
  157. package/src/components/ui/panels/collections/collections-popover.tsx +20 -14
  158. package/src/components/ui/panels/floor-foundation-panel.tsx +551 -0
  159. package/src/components/ui/panels/floor-opening-panel.tsx +143 -0
  160. package/src/components/ui/panels/mobile-panel-sheet.tsx +2 -2
  161. package/src/components/ui/panels/mobile-selection-bar.tsx +2 -2
  162. package/src/components/ui/panels/multi-field-value.test.ts +26 -3
  163. package/src/components/ui/panels/multi-field-value.ts +6 -3
  164. package/src/components/ui/panels/multi-height-mode.tsx +27 -21
  165. package/src/components/ui/panels/multi-parametric-inspector.tsx +52 -2
  166. package/src/components/ui/panels/multi-selection-panel.tsx +43 -4
  167. package/src/components/ui/panels/node-display.ts +8 -3
  168. package/src/components/ui/panels/panel-manager.tsx +103 -68
  169. package/src/components/ui/panels/panel-wrapper.tsx +78 -36
  170. package/src/components/ui/panels/parametric-field-control.tsx +1 -1
  171. package/src/components/ui/panels/parametric-inspector.tsx +7 -19
  172. package/src/components/ui/panels/reference-panel.tsx +2 -3
  173. package/src/components/ui/panels/room-construction-rows.tsx +774 -0
  174. package/src/components/ui/panels/room-name-options.test.ts +55 -0
  175. package/src/components/ui/panels/room-name-options.ts +47 -0
  176. package/src/components/ui/panels/room-openings-field.tsx +110 -0
  177. package/src/components/ui/panels/room-panel.tsx +725 -0
  178. package/src/components/ui/panels/shape-choice.tsx +58 -0
  179. package/src/components/ui/panels/wall-region-list.tsx +109 -0
  180. package/src/components/ui/primitives/color-dot.tsx +36 -24
  181. package/src/components/ui/primitives/shortcut-token.tsx +4 -0
  182. package/src/components/ui/primitives/sidebar.tsx +2 -0
  183. package/src/components/ui/right-stack.test.ts +29 -0
  184. package/src/components/ui/right-stack.tsx +145 -0
  185. package/src/components/ui/sidebar/icon-rail.tsx +5 -0
  186. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  187. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +615 -372
  188. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +7 -7
  189. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  190. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +4 -4
  191. package/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +1 -5
  192. package/src/components/ui/sidebar/panels/site-panel/collection-tree-node.tsx +197 -0
  193. package/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx +1 -5
  194. package/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx +1 -5
  195. package/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +1 -5
  196. package/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +1 -5
  197. package/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +24 -11
  198. package/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +1 -5
  199. package/src/components/ui/sidebar/panels/site-panel/index.tsx +176 -211
  200. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +30 -8
  201. package/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx +1 -3
  202. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +4 -1
  203. package/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +1 -3
  204. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +1 -4
  205. package/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +1 -3
  206. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +21 -13
  207. package/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +1 -5
  208. package/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +1 -5
  209. package/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx +1 -5
  210. package/src/components/ui/sidebar/panels/site-panel/tree-node.tsx +0 -27
  211. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -3
  212. package/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx +1 -5
  213. package/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx +1 -5
  214. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +9 -4
  215. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +0 -2
  216. package/src/components/ui/sidebar/tab-bar.tsx +10 -0
  217. package/src/components/ui/sidebar/use-plugin-panels.tsx +15 -5
  218. package/src/components/viewer/floorplan-compass-button.tsx +9 -1
  219. package/src/components/viewer/floorplan-preview-visibility.test.ts +35 -0
  220. package/src/components/viewer/floorplan-preview-visibility.ts +19 -0
  221. package/src/components/viewer/floorplan-preview.tsx +6 -18
  222. package/src/components/viewer/viewer-hover-label.tsx +34 -0
  223. package/src/components/viewer/viewer-rooms.tsx +175 -0
  224. package/src/components/viewer/viewer-scene-header.tsx +181 -145
  225. package/src/components/viewer/viewer-selection-manager.tsx +124 -0
  226. package/src/components/viewer/viewer-stage.tsx +2 -2
  227. package/src/components/viewer-zone-system.tsx +9 -9
  228. package/src/hooks/use-auto-save.integration.test.tsx +311 -0
  229. package/src/hooks/use-auto-save.ts +55 -14
  230. package/src/hooks/use-ceiling-events.test.ts +1 -0
  231. package/src/hooks/use-ceiling-events.ts +2 -0
  232. package/src/hooks/use-grid-events.test.ts +2 -0
  233. package/src/hooks/use-grid-events.ts +16 -11
  234. package/src/hooks/use-keyboard.test.ts +182 -0
  235. package/src/hooks/use-keyboard.ts +122 -91
  236. package/src/hooks/use-open-wall-ends.test.ts +99 -0
  237. package/src/hooks/use-open-wall-ends.ts +238 -0
  238. package/src/hooks/use-placement-notice.test.ts +48 -0
  239. package/src/hooks/use-placement-notice.ts +42 -0
  240. package/src/hooks/use-selected-room.ts +143 -0
  241. package/src/index.tsx +306 -39
  242. package/src/lib/catalog-panel-model.ts +39 -0
  243. package/src/lib/catalog-selection.test.ts +27 -0
  244. package/src/lib/catalog-selection.ts +8 -0
  245. package/src/lib/ceiling-edit-session.test.ts +321 -0
  246. package/src/lib/ceiling-edit-session.ts +206 -0
  247. package/src/lib/ceiling-region-session.test.ts +179 -0
  248. package/src/lib/contextual-help.test.ts +27 -1
  249. package/src/lib/contextual-help.ts +16 -9
  250. package/src/lib/continuation.test.ts +19 -1
  251. package/src/lib/continuation.ts +25 -4
  252. package/src/lib/door-interaction.ts +14 -0
  253. package/src/lib/editor-level-display.test.ts +96 -0
  254. package/src/lib/editor-level-display.ts +48 -0
  255. package/src/lib/editor-views.ts +144 -0
  256. package/src/lib/export-geometry-wait.test.ts +90 -0
  257. package/src/lib/floor-edit-session.ts +153 -0
  258. package/src/lib/floor-footprints.test.ts +563 -0
  259. package/src/lib/floor-footprints.ts +395 -0
  260. package/src/lib/floor-foundation-support.test.ts +283 -0
  261. package/src/lib/floor-opening-draft.ts +218 -0
  262. package/src/lib/floor-openings.test.ts +216 -0
  263. package/src/lib/floor-region-geometry.ts +191 -0
  264. package/src/lib/floor-region-session.test.ts +485 -0
  265. package/src/lib/floor-region-session.ts +589 -0
  266. package/src/lib/floor-region-snap.ts +101 -0
  267. package/src/lib/floor-step-hover.test.ts +32 -0
  268. package/src/lib/floorplan/annotation-visibility.ts +17 -0
  269. package/src/lib/floorplan/dimension-drive.test.ts +360 -0
  270. package/src/lib/floorplan/dimension-drive.ts +479 -0
  271. package/src/lib/floorplan/floorplan-export.test.ts +15 -9
  272. package/src/lib/floorplan/floorplan-export.tsx +32 -8
  273. package/src/lib/floorplan/floorplan-extension.ts +48 -0
  274. package/src/lib/floorplan/floorplan-mode.test.ts +4 -0
  275. package/src/lib/floorplan/floorplan-mode.ts +2 -0
  276. package/src/lib/floorplan/floorplan-pdfkit-document.ts +339 -18
  277. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +138 -8
  278. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +56 -25
  279. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +138 -0
  280. package/src/lib/floorplan/floorplan-readonly.ts +6 -0
  281. package/src/lib/floorplan/geometry.ts +13 -6
  282. package/src/lib/floorplan/index.ts +0 -9
  283. package/src/lib/floorplan/items.ts +5 -2
  284. package/src/lib/floorplan/marks.test.ts +213 -0
  285. package/src/lib/floorplan/marks.ts +238 -0
  286. package/src/lib/floorplan/open-wall-ends.test.ts +268 -0
  287. package/src/lib/floorplan/open-wall-ends.ts +162 -0
  288. package/src/lib/floorplan/pdf-fonts/GeistMono-Bold.ttf +0 -0
  289. package/src/lib/floorplan/pdf-fonts/GeistMono-Regular.ttf +0 -0
  290. package/src/lib/floorplan/pdf-fonts/LICENSE-GeistMono.txt +92 -0
  291. package/src/lib/floorplan/pdf-fonts/LICENSE-LiberationSans.txt +102 -0
  292. package/src/lib/floorplan/pdf-fonts/LiberationSans-Bold.ttf +0 -0
  293. package/src/lib/floorplan/pdf-fonts/LiberationSans-Regular.ttf +0 -0
  294. package/src/lib/floorplan/schedules.test.ts +189 -0
  295. package/src/lib/floorplan/schedules.ts +339 -0
  296. package/src/lib/floorplan/sheet-export.test.ts +100 -0
  297. package/src/lib/floorplan/sheet-export.ts +318 -0
  298. package/src/lib/floorplan/site-plan/build-site-plan-drawing.ts +779 -0
  299. package/src/lib/floorplan/site-plan/contours.test.ts +43 -0
  300. package/src/lib/floorplan/site-plan/contributors.ts +97 -0
  301. package/src/lib/floorplan/site-plan/coverage.ts +232 -0
  302. package/src/lib/floorplan/site-plan/drawing-type-switch.test.ts +15 -0
  303. package/src/lib/floorplan/site-plan/drawing-type-switch.tsx +86 -0
  304. package/src/lib/floorplan/site-plan/front-edge.test.ts +103 -0
  305. package/src/lib/floorplan/site-plan/front-edge.ts +156 -0
  306. package/src/lib/floorplan/site-plan/geometry.test.ts +275 -0
  307. package/src/lib/floorplan/site-plan/geometry.ts +557 -0
  308. package/src/lib/floorplan/site-plan/index.ts +71 -0
  309. package/src/lib/floorplan/site-plan/site-annotations.test.ts +366 -0
  310. package/src/lib/floorplan/site-plan/site-annotations.ts +1083 -0
  311. package/src/lib/floorplan/site-plan/site-parts.ts +379 -0
  312. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +138 -0
  313. package/src/lib/floorplan/site-plan/street-name.test.ts +69 -0
  314. package/src/lib/floorplan/site-plan/street-name.ts +302 -0
  315. package/src/lib/floorplan/site-plan/yards.test.ts +69 -0
  316. package/src/lib/floorplan/types.ts +1 -27
  317. package/src/lib/fresh-planar-placement.test.ts +36 -0
  318. package/src/lib/fresh-planar-placement.ts +191 -36
  319. package/src/lib/geometry-script/author.ts +152 -0
  320. package/src/lib/geometry-script/client.ts +152 -0
  321. package/src/lib/geometry-script/protocol.ts +12 -0
  322. package/src/lib/gesture-lifecycle.test.ts +595 -0
  323. package/src/lib/gesture-lifecycle.ts +290 -0
  324. package/src/lib/glb-export-zone-holes.test.ts +41 -0
  325. package/src/lib/glb-export.test.ts +544 -16
  326. package/src/lib/glb-export.ts +256 -125
  327. package/src/lib/grid-frame.test.ts +19 -0
  328. package/src/lib/grid-frame.ts +18 -0
  329. package/src/lib/history.test.ts +6 -0
  330. package/src/lib/history.ts +7 -0
  331. package/src/lib/hud-title.ts +109 -0
  332. package/src/lib/hydration-gated-storage.ts +49 -0
  333. package/src/lib/ifc-export.test.ts +174 -0
  334. package/src/lib/ifc-export.ts +201 -0
  335. package/src/lib/ifc-parts.ts +15 -0
  336. package/src/lib/inspector-expanded.test.ts +44 -0
  337. package/src/lib/inspector-expanded.ts +36 -0
  338. package/src/lib/interaction/scope.ts +27 -1
  339. package/src/lib/keyboard-pan.test.ts +184 -0
  340. package/src/lib/keyboard-pan.ts +238 -0
  341. package/src/lib/live-gesture-round-trip.test.ts +360 -0
  342. package/src/lib/lot/__fixtures__/map-dossier-miami-shores.json +1 -0
  343. package/src/lib/lot/__fixtures__/map-dossier-stpete.json +1 -0
  344. package/src/lib/lot/clean-ring.test.ts +186 -0
  345. package/src/lib/lot/clean-ring.ts +217 -0
  346. package/src/lib/lot/dossier.test.ts +202 -0
  347. package/src/lib/lot/dossier.ts +498 -0
  348. package/src/lib/lot/drop-in.test.ts +326 -0
  349. package/src/lib/lot/drop-in.ts +407 -0
  350. package/src/lib/lot/index.ts +43 -0
  351. package/src/lib/lot/lot-patch.test.ts +340 -0
  352. package/src/lib/lot/lot-patch.ts +394 -0
  353. package/src/lib/lot/parcel-provider.ts +43 -0
  354. package/src/lib/lot/terrain.test.ts +161 -0
  355. package/src/lib/lot/terrain.ts +266 -0
  356. package/src/lib/material-catalog-model.ts +74 -0
  357. package/src/lib/material-paint-panel-model.ts +80 -0
  358. package/src/lib/material-paint.ts +4 -0
  359. package/src/lib/mezzanine-actions.test.ts +342 -0
  360. package/src/lib/mezzanine-draft.test.ts +501 -0
  361. package/src/lib/mezzanine-draft.ts +278 -0
  362. package/src/lib/mezzanine-messages.ts +26 -0
  363. package/src/lib/mezzanine-selection.test.ts +207 -0
  364. package/src/lib/mezzanine-stairs.ts +46 -0
  365. package/src/lib/model-export.ts +3 -1
  366. package/src/lib/node-action-movement.ts +17 -6
  367. package/src/lib/node-display-label.ts +37 -0
  368. package/src/lib/orbit-floor-clearance.test.ts +165 -0
  369. package/src/lib/orbit-floor-clearance.ts +106 -0
  370. package/src/lib/overlay-transform.test.ts +28 -0
  371. package/src/lib/overlay-transform.ts +12 -0
  372. package/src/lib/paint-commit-route.test.ts +37 -0
  373. package/src/lib/paint-commit-route.ts +17 -0
  374. package/src/lib/paint-eyedropper.test.tsx +165 -0
  375. package/src/lib/paint-eyedropper.ts +99 -0
  376. package/src/lib/paint-pass-through.test.ts +111 -0
  377. package/src/lib/paint-pass-through.ts +76 -0
  378. package/src/lib/paint-region-hover.ts +25 -0
  379. package/src/lib/paint-region-mode.ts +154 -0
  380. package/src/lib/paint-regions.test.ts +166 -0
  381. package/src/lib/paint-regions.ts +192 -0
  382. package/src/lib/paint-scope.test.ts +317 -35
  383. package/src/lib/paint-scope.ts +266 -25
  384. package/src/lib/panel-rows.ts +96 -0
  385. package/src/lib/panel-tool-options.test.ts +34 -0
  386. package/src/lib/panel-tool-options.ts +46 -0
  387. package/src/lib/parametric-node-update.ts +37 -0
  388. package/src/lib/plate-paint-affected.test.ts +300 -0
  389. package/src/lib/plate-paint-affected.ts +177 -0
  390. package/src/lib/plugin-chat.ts +50 -0
  391. package/src/lib/plugin-panels.test.ts +25 -0
  392. package/src/lib/plugin-panels.ts +94 -0
  393. package/src/lib/print-shell-compiler.ts +1 -0
  394. package/src/lib/registered-draft-snap.ts +12 -0
  395. package/src/lib/roof-duplication.ts +10 -2
  396. package/src/lib/room-assembly-overlay.test.ts +275 -0
  397. package/src/lib/room-assembly-overlay.ts +266 -0
  398. package/src/lib/room-built-on.test.ts +379 -0
  399. package/src/lib/room-built-on.ts +138 -0
  400. package/src/lib/room-construction-commands.ts +712 -0
  401. package/src/lib/room-construction.test.ts +746 -0
  402. package/src/lib/room-construction.ts +385 -0
  403. package/src/lib/room-controls-phase6.test.ts +630 -0
  404. package/src/lib/room-divide-session.ts +523 -0
  405. package/src/lib/room-handle-drag.ts +1068 -0
  406. package/src/lib/room-name-catalog.test.ts +90 -0
  407. package/src/lib/room-name-catalog.ts +168 -0
  408. package/src/lib/room-push-dimensions.test.ts +311 -0
  409. package/src/lib/room-push-dimensions.ts +251 -0
  410. package/src/lib/room-selection-commands.ts +62 -0
  411. package/src/lib/room-selection.test.ts +973 -0
  412. package/src/lib/room-selection.ts +417 -0
  413. package/src/lib/room-structure-commands.ts +94 -0
  414. package/src/lib/room-structure.test.ts +921 -0
  415. package/src/lib/room-transform-session.ts +570 -0
  416. package/src/lib/room-zone-routing.test.ts +294 -0
  417. package/src/lib/room-zone-routing.ts +197 -0
  418. package/src/lib/scene-clipboard.test.ts +364 -0
  419. package/src/lib/scene-clipboard.ts +229 -48
  420. package/src/lib/scene-material-refs.test.ts +79 -0
  421. package/src/lib/scene-material-refs.ts +79 -0
  422. package/src/lib/scene.test.ts +87 -0
  423. package/src/lib/scene.ts +39 -45
  424. package/src/lib/selection-routing.test.ts +129 -45
  425. package/src/lib/selection-routing.ts +53 -74
  426. package/src/lib/session-writes.test.ts +120 -0
  427. package/src/lib/session-writes.ts +205 -0
  428. package/src/lib/sidebar-panel.ts +62 -0
  429. package/src/lib/site-boundary.test.ts +4 -6
  430. package/src/lib/site-boundary.ts +1 -1
  431. package/src/lib/snapping-mode.test.ts +17 -2
  432. package/src/lib/snapping-mode.ts +19 -7
  433. package/src/lib/spatial-drag-plane.test.ts +53 -0
  434. package/src/lib/spatial-drag-plane.ts +19 -0
  435. package/src/lib/spatial-pointer-input.test.ts +72 -0
  436. package/src/lib/spatial-pointer-input.ts +62 -0
  437. package/src/lib/spatial-snap.test.ts +47 -0
  438. package/src/lib/terrace-draft.test.ts +145 -0
  439. package/src/lib/terrace-draft.ts +213 -0
  440. package/src/lib/terrain-panel-model.ts +117 -0
  441. package/src/lib/tool-cursor-icon.test.ts +16 -0
  442. package/src/lib/tool-cursor-icon.ts +11 -0
  443. package/src/lib/typing-target.ts +9 -0
  444. package/src/lib/units.ts +77 -39
  445. package/src/lib/vector-edges.test.ts +58 -0
  446. package/src/lib/vector-edges.ts +400 -0
  447. package/src/lib/viewer-selection.test.ts +577 -0
  448. package/src/lib/viewer-selection.ts +569 -0
  449. package/src/lib/wall-draw-variant.test.ts +71 -0
  450. package/src/lib/wall-draw-variant.ts +91 -0
  451. package/src/lib/wall-paint-region-session.ts +246 -0
  452. package/src/lib/wall-paint-region.test.ts +373 -0
  453. package/src/lib/wall-polygon-draft.test.ts +262 -0
  454. package/src/lib/wall-polygon-draft.ts +286 -0
  455. package/src/lib/wall-push.test.ts +453 -0
  456. package/src/lib/wall-region-face.ts +352 -0
  457. package/src/lib/wall-region-handles.test.ts +304 -0
  458. package/src/lib/wall-region-handles.ts +368 -0
  459. package/src/lib/wall-region-list.test.ts +119 -0
  460. package/src/lib/wall-region-list.ts +136 -0
  461. package/src/lib/wall-region-snap.ts +110 -0
  462. package/src/lib/window-interaction.ts +14 -0
  463. package/src/lib/world-grid-snap.test.ts +48 -0
  464. package/src/lib/world-grid-snap.ts +9 -5
  465. package/src/lib/zone-content.ts +4 -1
  466. package/src/lib/zone-name.test.ts +17 -0
  467. package/src/lib/zone-name.ts +17 -0
  468. package/src/store/opens-in-select-mode.test.ts +223 -0
  469. package/src/store/paint-mode.test.ts +188 -0
  470. package/src/store/rotation-snapping.test.ts +53 -0
  471. package/src/store/terrain-sculpt-mode.test.ts +19 -21
  472. package/src/store/tool-mode.test.ts +137 -6
  473. package/src/store/use-delete-confirmation.ts +28 -1
  474. package/src/store/use-drawing-view.test.ts +24 -3
  475. package/src/store/use-drawing-view.ts +29 -1
  476. package/src/store/use-editor.tsx +442 -323
  477. package/src/store/use-floorplan-draft-preview.ts +23 -1
  478. package/src/store/use-floorplan-marquee.ts +12 -2
  479. package/src/store/use-interaction-scope.ts +155 -6
  480. package/src/store/use-quick-measurement-hud.ts +3 -3
  481. package/src/store/use-stair-build-preview.ts +13 -5
  482. package/src/store/use-wall-move-ghosts.ts +4 -2
  483. package/src/store/use-wall-region-handles-selection.test.ts +222 -0
  484. package/src/store/use-wall-region-handles-selection.ts +139 -0
  485. package/src/store/view-layout.test.ts +175 -0
  486. package/src/store/view-layout.ts +196 -0
  487. package/src/test-utils/immediate-animation-frames.ts +16 -0
  488. package/src/test-utils/live-gesture-round-trip.ts +224 -0
  489. package/src/test-utils/selection-harness.ts +82 -0
  490. package/src/components/editor-2d/renderers/floorplan-stair-layer.tsx +0 -499
  491. package/src/components/systems/zone/zone-label-editor-system.tsx +0 -333
  492. package/src/components/tools/fence/fence-drafting.test.ts +0 -100
  493. package/src/components/tools/fence/fence-drafting.ts +0 -266
  494. package/src/components/ui/sidebar/panels/plugins-panel.tsx +0 -218
  495. package/src/components/viewer/viewer-units-panel.tsx +0 -116
  496. package/src/lib/floorplan/stairs.ts +0 -489
  497. package/src/lib/level-duplication.test.ts +0 -144
  498. package/src/lib/level-duplication.ts +0 -195
package/src/index.tsx CHANGED
@@ -20,13 +20,15 @@ export {
20
20
  export { useViewer } from '@pascal-app/viewer'
21
21
  export type { EditorProps } from './components/editor'
22
22
  export { default as Editor } from './components/editor'
23
+ export { ActionMenuButton } from './components/editor/action-menu-button'
23
24
  // Headless component aliases: the implementation files keep their
24
25
  // internal names (`ParametricInspector`, `FloatingActionMenu`) because
25
26
  // they're referenced throughout the editor's own internals; the public
26
27
  // surface uses the shorter, shell-friendly names from the unified
27
28
  // preset-system spec.
28
29
  export { BakeExporter } from './components/editor/bake-exporter'
29
- export { BakeThumbnail } from './components/editor/bake-thumbnail'
30
+ export { BakeThumbnail, prepareBakeThumbnailLook } from './components/editor/bake-thumbnail'
31
+ export { copyCollectionIds, duplicateNodeAndPickUp } from './components/editor/duplicate-node'
30
32
  export { FirstPersonControls } from './components/editor/first-person-controls'
31
33
  export { FloatingActionMenu as FloatingMenu } from './components/editor/floating-action-menu'
32
34
  // Embed surface — the editor's real in-canvas affordances, so a host can mount
@@ -49,7 +51,7 @@ export { FloatingActionMenu as FloatingMenu } from './components/editor/floating
49
51
  // camera controls via the `useViewer.inputDragging` / `useEditor.movingNode`
50
52
  // flags. Tools place onto `useViewer.selection.levelId`, so the host must set a
51
53
  // building + level selection first.
52
- export { Grid } from './components/editor/grid'
54
+ export { EDITOR_GRID_INPUT_NAME, Grid } from './components/editor/grid'
53
55
  export {
54
56
  DimensionPill,
55
57
  type DimensionPillPart,
@@ -79,12 +81,18 @@ export {
79
81
  useInvisibleHitAreaMaterial,
80
82
  } from './components/editor/node-arrow-handles'
81
83
  export { QuickMeasurementCard } from './components/editor/quick-measurement-card'
84
+ export { SelectionManager } from './components/editor/selection-manager'
82
85
  export {
83
86
  type SnapshotCameraData,
84
87
  ThumbnailGenerator,
85
88
  } from './components/editor/thumbnail-generator'
89
+ export { WallMoveSideHandles } from './components/editor/wall-move-side-handles'
86
90
  export { useFloorplanRender } from './components/editor-2d/floorplan-render-context'
87
91
  export { FloorplanDimensionRenderer } from './components/editor-2d/renderers/floorplan-dimension-renderer'
92
+ export {
93
+ type DraftMeasurement,
94
+ FloorplanDraftMeasurement,
95
+ } from './components/editor-2d/renderers/floorplan-draft-measurement'
88
96
  export { FloorplanGeometryRenderer } from './components/editor-2d/renderers/floorplan-geometry-renderer'
89
97
  export {
90
98
  FloorplanNodePreview,
@@ -104,16 +112,7 @@ export type {
104
112
  SelectionAffordanceInteractionApi,
105
113
  SelectionAffordanceProps,
106
114
  } from './components/systems/selection-affordance-services'
107
- // Phase 5 Stage D transitional exports — pure drafting / angle helpers
108
- // consumed by kind-owned drag actions in @pascal-app/nodes. Stage F
109
- // cleanup moves these into @pascal-app/nodes (fence/drafting.ts +
110
- // shared/segment-angle.ts) once every Stage D port is in.
111
- export {
112
- createFenceOnCurrentLevel,
113
- createSplineFenceOnCurrentLevel,
114
- type FencePlanPoint,
115
- snapFenceDraftPoint,
116
- } from './components/tools/fence/fence-drafting'
115
+ export { StairEditSystem } from './components/systems/stair/stair-edit-system'
117
116
  export { MoveTool } from './components/tools/item/move-tool'
118
117
  // Placement-math helpers — shared by kind-owned placement tools in
119
118
  // `@pascal-app/nodes` (wall curve sagitta snap, door / window placement,
@@ -140,6 +139,10 @@ export {
140
139
  export { MoveRegistryNodeTool } from './components/tools/registry/move-registry-node-tool'
141
140
  export { useRegistryToolContext } from './components/tools/registry-tool-context'
142
141
  export { CursorSphere } from './components/tools/shared/cursor-sphere'
142
+ export {
143
+ DRAFT_LABEL_Y_OFFSET,
144
+ DraftMeasurementLabel,
145
+ } from './components/tools/shared/draft-measurement-label'
143
146
  export { DragBoundingBox } from './components/tools/shared/drag-bounding-box'
144
147
  export { getFloorStackPreviewPosition } from './components/tools/shared/floor-stack-preview'
145
148
  export { useFreshPlacementVisibility } from './components/tools/shared/fresh-placement-visibility'
@@ -184,11 +187,8 @@ export {
184
187
  DEFAULT_SPIRAL_TOP_LANDING_MODE,
185
188
  DEFAULT_STAIR_ATTACHMENT_SIDE,
186
189
  DEFAULT_STAIR_FILL_TO_FLOOR,
187
- DEFAULT_STAIR_HEIGHT,
188
- DEFAULT_STAIR_LENGTH,
189
190
  DEFAULT_STAIR_RAILING_HEIGHT,
190
191
  DEFAULT_STAIR_RAILING_MODE,
191
- DEFAULT_STAIR_STEP_COUNT,
192
192
  DEFAULT_STAIR_THICKNESS,
193
193
  DEFAULT_STAIR_TYPE,
194
194
  DEFAULT_STAIR_WIDTH,
@@ -197,6 +197,7 @@ export { preloadRegistryToolModules, ToolManager } from './components/tools/tool
197
197
  export {
198
198
  chainEndJoinsExistingWall,
199
199
  createWallOnCurrentLevel,
200
+ findWallSnapTarget,
200
201
  getSegmentGridStep,
201
202
  isSegmentLongEnough,
202
203
  resolveEndpointWallSplit,
@@ -212,19 +213,25 @@ export {
212
213
  type WallPlanPoint,
213
214
  type WallSnapRadii,
214
215
  } from './components/tools/wall/wall-drafting'
215
- // `ToolbarLeft` / `ToolbarRight` are the headless-spec aliases for the
216
- // existing `ViewerToolbarLeft` / `ViewerToolbarRight` exports — the
217
- // underlying components are the same; the alias just matches the names
218
- // used in `pascalorg/private-editor:plans/community-preset-system.md`
219
- // so consumer code stays close to the spec vocabulary.
216
+ // `ToolbarLeft` / `ToolbarRight` alias `ViewerToolbarLeft` / `ViewerToolbarRight`
217
+ // (same components) under the names headless hosts compose their toolbars with.
220
218
  export {
221
219
  CameraActions as ToolbarRight,
222
220
  CameraActions as ViewerToolbarRight,
223
221
  } from './components/ui/action-menu/camera-actions'
222
+ export { furnishTools } from './components/ui/action-menu/furnish-tools'
224
223
  export {
225
224
  ViewToggles as ToolbarLeft,
226
225
  ViewToggles as ViewerToolbarLeft,
227
226
  } from './components/ui/action-menu/view-toggles'
227
+ // The Build panel's grouped layout, shared by the community and standalone tabs.
228
+ export {
229
+ BuildPanelAdvancedSection,
230
+ BuildPanelRoomsSection,
231
+ BuildPanelSection,
232
+ BuildToolGrid,
233
+ BuildToolTile,
234
+ } from './components/ui/build-panel/build-panel'
228
235
  export { useCommandPalette } from './components/ui/command-palette'
229
236
  export { ActionButton, ActionGroup } from './components/ui/controls/action-button'
230
237
  export {
@@ -239,19 +246,36 @@ export {
239
246
  export { MetricControl } from './components/ui/controls/metric-control'
240
247
  export { PanelSection } from './components/ui/controls/panel-section'
241
248
  export { SegmentedControl } from './components/ui/controls/segmented-control'
249
+ export { SelectControl } from './components/ui/controls/select-control'
242
250
  export { SliderControl } from './components/ui/controls/slider-control'
243
251
  export { TerrainSculptPanel } from './components/ui/controls/terrain-sculpt-panel'
244
252
  export { ToggleControl } from './components/ui/controls/toggle-control'
245
253
  export { ToolOptionsPanel } from './components/ui/controls/tool-options-panel'
246
254
  export { FloatingLevelSelector } from './components/ui/floating-level-selector'
247
255
  export { CATALOG_ITEMS } from './components/ui/item-catalog/catalog-items'
248
- // Item collections UI — used by the kind-owned ItemPanel in nodes/.
249
- export { CollectionsPopover } from './components/ui/panels/collections/collections-popover'
256
+ // A base plate's panel (one connected footprint's floor and foundation); the
257
+ // slab kind's panel hands base plates to it.
258
+ export { FloorFoundationPanel } from './components/ui/panels/floor-foundation-panel'
259
+ export {
260
+ resolveHomogeneousSelection,
261
+ resolveUniqueSelectionIds,
262
+ } from './components/ui/panels/homogeneous-selection'
263
+ export {
264
+ commitMultiNodeFields,
265
+ fieldVisibleForAll,
266
+ firstNumericFieldValue,
267
+ firstVec3FieldValue,
268
+ reduceFieldValue,
269
+ reduceHeightBoundMode,
270
+ } from './components/ui/panels/multi-field-value'
271
+ export { applyMultiHeightMode } from './components/ui/panels/multi-height-mode'
250
272
  // Phase 5 Stage E — kinds with bespoke editors (slab holes list,
251
273
  // ceiling height presets, etc.) use `parametrics.customPanel` to mount
252
274
  // a kind-owned panel and need PanelWrapper for the chrome.
253
275
  export { PanelWrapper } from './components/ui/panels/panel-wrapper'
254
276
  export { ParametricInspector as Inspector } from './components/ui/panels/parametric-inspector'
277
+ export { ShapeChoice } from './components/ui/panels/shape-choice'
278
+ export { WallPaintRegionList } from './components/ui/panels/wall-region-list'
255
279
  export { PALETTE_COLORS } from './components/ui/primitives/color-dot'
256
280
  export {
257
281
  DropdownMenu,
@@ -269,6 +293,7 @@ export {
269
293
  } from './components/ui/primitives/shortcut-token'
270
294
  export { useSidebarStore } from './components/ui/primitives/sidebar'
271
295
  export { Slider } from './components/ui/primitives/slider'
296
+ export { Tooltip, TooltipContent, TooltipTrigger } from './components/ui/primitives/tooltip'
272
297
  export { SceneLoader } from './components/ui/scene-loader'
273
298
  export type { ExtraPanel } from './components/ui/sidebar/icon-rail'
274
299
  export { ItemsPanel } from './components/ui/sidebar/panels/items-panel'
@@ -301,10 +326,13 @@ export {
301
326
  ViewerControlsBar,
302
327
  type ViewerControlsBarProps,
303
328
  } from './components/viewer/viewer-controls-bar'
329
+ export { ViewerHoverLabel } from './components/viewer/viewer-hover-label'
330
+ export { ParametricViewerRooms, ViewerRooms } from './components/viewer/viewer-rooms'
304
331
  export {
305
332
  ViewerSceneHeader,
306
333
  type ViewerSceneHeaderProps,
307
334
  } from './components/viewer/viewer-scene-header'
335
+ export { ViewerSelectionManager } from './components/viewer/viewer-selection-manager'
308
336
  export { ViewerStage, type ViewerStageProps } from './components/viewer/viewer-stage'
309
337
  export {
310
338
  normalizeViewerStageModes,
@@ -318,7 +346,6 @@ export {
318
346
  ViewerStageSwitcher,
319
347
  type ViewerStageSwitcherProps,
320
348
  } from './components/viewer/viewer-stage-switcher'
321
- export { ViewerUnitsPanel } from './components/viewer/viewer-units-panel'
322
349
  export {
323
350
  WalkthroughHud,
324
351
  type WalkthroughHudProps,
@@ -330,8 +357,10 @@ export type { SaveStatus } from './hooks/use-auto-save'
330
357
  // can express their affordances declaratively in their own folder.
331
358
  export { type UseDragActionArgs, useDragAction } from './hooks/use-drag-action'
332
359
  // Phase 5 Stage D — extras for kind-owned placement tools (FenceTool etc.).
333
- export { markToolCancelConsumed } from './hooks/use-keyboard'
360
+ export { cancelActiveTool, markToolCancelConsumed } from './hooks/use-keyboard'
361
+ export { usePlacementNotice } from './hooks/use-placement-notice'
334
362
  export { useReducedMotion } from './hooks/use-reduced-motion'
363
+ export { useSelectedRoom } from './hooks/use-selected-room'
335
364
  export { type Selection, useSelection } from './hooks/use-selection'
336
365
  export {
337
366
  clearPlacementSurface,
@@ -339,6 +368,21 @@ export {
339
368
  type PlacementSurface,
340
369
  publishPlacementSurface,
341
370
  } from './lib/active-placement-surface'
371
+ export {
372
+ activateCatalogItem,
373
+ filterCatalogItems,
374
+ isCatalogItemSelected,
375
+ } from './lib/catalog-panel-model'
376
+ export {
377
+ type CeilingEditSession,
378
+ endCeilingEdit,
379
+ exitCeilingEditToRoom,
380
+ getCeilingEditSession,
381
+ setCeilingHoles,
382
+ startCeilingEdit,
383
+ useCeilingEditCeilingId,
384
+ useCeilingEditSession,
385
+ } from './lib/ceiling-edit-session'
342
386
  export {
343
387
  CEILING_ALIGNMENT_THRESHOLD_M,
344
388
  type CeilingPlanSnapInput,
@@ -361,7 +405,19 @@ export {
361
405
  continuationContextOf,
362
406
  nextContinuation,
363
407
  } from './lib/continuation'
408
+ export { canDirectMoveNode } from './lib/direct-manipulation'
409
+ export {
410
+ closeDoorOpenState,
411
+ getDisplayedDoorValue,
412
+ openDoorOpenState,
413
+ } from './lib/door-interaction'
364
414
  export { createEditorApi } from './lib/editor-api'
415
+ export {
416
+ type EditorHostView,
417
+ editorHostViewRegistry,
418
+ openEditorView,
419
+ registerEditorHostView,
420
+ } from './lib/editor-views'
365
421
  export {
366
422
  clearStructuralElevationGuide,
367
423
  collectElevationSnapTargets,
@@ -382,30 +438,36 @@ export {
382
438
  } from './lib/elevator-support'
383
439
  export type { ExportTextureUtils } from './lib/export-texture-utils'
384
440
  export { getFloatingMenuScale } from './lib/floating-menu-scale'
385
- // Floor-plan stair helpers — the cumulative-transform walk
386
- // (`computeFloorplanStairSegmentTransforms`) and the rich segment-entry
387
- // builder (`buildFloorplanStairEntry`) used by the kind-owned stair
388
- // floor-plan emitter in `@pascal-app/nodes/src/stair/floorplan.ts`.
389
- // Each flight's transform depends on every prior sibling's length /
390
- // height / `attachmentSide`, so individual stair-segments can't compute
391
- // their own polygon in isolation — the stair (parent) owns the
392
- // computation and emits the whole stack as one registry entry.
441
+ export { startOpeningDraft } from './lib/floor-opening-draft'
393
442
  export {
394
443
  alignFloorplanDraftPoint,
395
444
  applyFloorplanAlignment,
396
- buildFloorplanStairEntry,
445
+ clampPlanValue,
397
446
  FLOORPLAN_ALIGNMENT_THRESHOLD_M,
398
447
  FLOORPLAN_DRAFT_ALIGN_ID,
399
448
  type FloorplanAlignmentResult,
400
- type FloorplanStairArrowEntry,
401
- type FloorplanStairEntry,
402
- type FloorplanStairSegmentEntry,
403
449
  getFloorplanWallThickness,
450
+ getPlanPointDistance,
451
+ getThickPlanLinePolygon,
452
+ interpolatePlanPoint,
453
+ movePlanPointTowards,
454
+ rotatePlanVector,
404
455
  } from './lib/floorplan'
405
456
  export type {
406
457
  FloorplanAnnotationCategory,
407
458
  FloorplanAnnotationVisibility,
408
459
  } from './lib/floorplan/annotation-visibility'
460
+ // Annotations (WS3) — deterministic door/window marks, driving dimensions,
461
+ // and construction-document schedule data.
462
+ export {
463
+ type DimensionDrivePlan,
464
+ type DimensionDriveResolution,
465
+ type DimensionDriveTarget,
466
+ type DimensionPlanPoint,
467
+ parseDimensionInput,
468
+ planDimensionDrive,
469
+ resolveDimensionDrive,
470
+ } from './lib/floorplan/dimension-drive'
409
471
  export {
410
472
  exportFloorplanPdf,
411
473
  type FloorplanExportScope,
@@ -435,10 +497,86 @@ export {
435
497
  type FloorplanMode,
436
498
  isFloorplanToolAvailableInMode,
437
499
  } from './lib/floorplan/floorplan-mode'
500
+ export {
501
+ type MarkResolution,
502
+ type OpeningMarkKind,
503
+ orderedOpenings,
504
+ persistResolvedMarks,
505
+ resolveMarkDetail,
506
+ resolveMarks,
507
+ } from './lib/floorplan/marks'
508
+ export { clientToPlan } from './lib/floorplan/plan-coords'
509
+ export {
510
+ doorSchedule,
511
+ floorplanSchedules,
512
+ formatScheduleLength,
513
+ type OpeningScheduleRow,
514
+ type RoomScheduleRow,
515
+ roomSchedule,
516
+ type ScheduleResult,
517
+ type ScheduleUnit,
518
+ windowSchedule,
519
+ } from './lib/floorplan/schedules'
520
+ // Sheets — headless floor-plan geometry collection + the multi-sheet vector
521
+ // PDF writer.
522
+ export {
523
+ collectFloorplanSchedules,
524
+ collectSheetGeometry,
525
+ exportSheetsToPdf,
526
+ POINTS_PER_INCH,
527
+ resolveSheetRotationDeg,
528
+ type SheetGeometryEntry,
529
+ type SheetGeometryOptions,
530
+ type SheetPdfPage,
531
+ type SheetPdfWindow,
532
+ } from './lib/floorplan/sheet-export'
533
+ // ── Site plan (WS1) ──────────────────────────────────────────────────
534
+ export {
535
+ boundsInsidePolygon,
536
+ buildingRecentreOffset,
537
+ buildSitePlanDrawing,
538
+ castYardDimensions,
539
+ classifyEdges,
540
+ computeSiteCoverage,
541
+ describeSiteEdges,
542
+ detectFrontEdgeFromRoads,
543
+ FloorplanDrawingTypeSwitch,
544
+ FloorplanSitePlanLayer,
545
+ type FrontEdgeMatch,
546
+ flatworkKindOf,
547
+ formatCoveragePercent,
548
+ formatFeetInches,
549
+ formatSqFt,
550
+ formatStreetName,
551
+ type ImperviousRow,
552
+ type OutdoorPart,
553
+ type RoadCenterline,
554
+ registerSitePlanContributor,
555
+ type SiteCoverage,
556
+ type SitePlanContributor,
557
+ type SitePlanDrawing,
558
+ type SitePlanEdge,
559
+ type SitePlanServicePoint,
560
+ type SitePlanServiceRole,
561
+ type SitePlanServices,
562
+ serviceEntranceOf,
563
+ setbackEnvelope,
564
+ streetCore,
565
+ streetEdgeNames,
566
+ type YardDimension,
567
+ } from './lib/floorplan/site-plan'
438
568
  export {
439
569
  commitFreshPlacementSubtree,
440
570
  createFreshPlacementSubtree,
441
571
  } from './lib/fresh-planar-placement'
572
+ export {
573
+ type BlenderScriptBuilder,
574
+ compileAndStoreGeometryScript,
575
+ configureBlenderScriptBuilder,
576
+ rebuildAuthoredObject,
577
+ storedScript,
578
+ } from './lib/geometry-script/author'
579
+ export { compileGeometryScriptInWorker } from './lib/geometry-script/client'
442
580
  export { exportSceneToGlb, type GlbExportOptions } from './lib/glb-export'
443
581
  export {
444
582
  type EditorGridEvent,
@@ -474,6 +612,32 @@ export {
474
612
  movingNodeOf,
475
613
  scopeNodeId,
476
614
  } from './lib/interaction/scope'
615
+ export { isEditableKeyboardTarget } from './lib/keyboard-pan'
616
+ // Lot drop-in — address → parcel → streets → front edge → setbacks, on the
617
+ // site node, through the parcel provider the host sets.
618
+ export {
619
+ DEFAULT_SETBACKS_FT,
620
+ DEFAULT_SETBACKS_M,
621
+ DEFAULT_SETBACKS_SOURCE,
622
+ type DropInInput,
623
+ type DropInOptions,
624
+ describeFrontEdge,
625
+ describeLotSummary,
626
+ dropInLot,
627
+ findSiteNode,
628
+ getParcelProvider,
629
+ type LotDropInResult,
630
+ type LotRoad,
631
+ type LotSummary,
632
+ type ParcelEndpoint,
633
+ type ParcelProvider,
634
+ type ParcelResolveData,
635
+ STREET_CLASSES,
636
+ setParcelProvider,
637
+ sitePatchFromParcel,
638
+ useParcelProvider,
639
+ } from './lib/lot'
640
+ export { useMaterialCatalogModel } from './lib/material-catalog-model'
477
641
  export {
478
642
  type ActivePaintMaterial,
479
643
  buildResetSurfaceMaterialUpdates,
@@ -483,6 +647,7 @@ export {
483
647
  getActivePaintMaterialLabel,
484
648
  hasActivePaintMaterial,
485
649
  } from './lib/material-paint'
650
+ export { useMaterialPaintPanelModel } from './lib/material-paint-panel-model'
486
651
  export {
487
652
  CREATABLE_MEASUREMENT_KINDS,
488
653
  type CreatableMeasurementKind,
@@ -529,6 +694,22 @@ export type {
529
694
  ModelExportFormat,
530
695
  ModelExportOptions,
531
696
  } from './lib/model-export'
697
+ export { eyedropperMaterial } from './lib/paint-eyedropper'
698
+ export {
699
+ cyclePaintScope,
700
+ type PaintHoverInfo,
701
+ type PaintScope,
702
+ paintScopeLabel,
703
+ } from './lib/paint-scope'
704
+ export {
705
+ getNodePanelModel,
706
+ type NodePanelModel,
707
+ PANEL_MODEL_EXTENSION,
708
+ type PanelAction,
709
+ type PanelRow,
710
+ } from './lib/panel-rows'
711
+ export { type PanelToolOption, usePanelToolHints } from './lib/panel-tool-options'
712
+ export { commitParametricNodeFields } from './lib/parametric-node-update'
532
713
  export { consumePlacementDragRelease } from './lib/placement-drag-release'
533
714
  export {
534
715
  addFreshPlacementMetadata,
@@ -541,11 +722,22 @@ export {
541
722
  type PlanarPoint,
542
723
  resolvePlanarCursorPosition,
543
724
  } from './lib/planar-cursor-placement'
725
+ export type {
726
+ ChatToolCardProps,
727
+ ChatToolOutput,
728
+ PluginChatExtension,
729
+ } from './lib/plugin-chat'
544
730
  export {
545
731
  type EditorHostPanel,
546
732
  type EditorHostPanelWorkspace,
547
733
  editorHostPanelRegistry,
734
+ type PluginAccess,
735
+ type PluginDirectoryContext,
736
+ type PluginInstallLock,
737
+ pluginInstallLocks,
548
738
  registerEditorHostPanel,
739
+ setPluginDirectoryContext,
740
+ setPluginInstallLocks,
549
741
  } from './lib/plugin-panels'
550
742
  export { configureManifoldRuntime } from './lib/print-shell-compiler-manifold-worker'
551
743
  export type { ManifoldRuntimeOptions } from './lib/print-shell-compiler-protocol'
@@ -554,16 +746,35 @@ export {
554
746
  quickMeasurementContext,
555
747
  resolveQuickMeasurementReport,
556
748
  } from './lib/quick-measurement'
749
+ export {
750
+ REGISTERED_DRAFT_SNAP_EXTENSION,
751
+ snapRegisteredDraftPoint,
752
+ } from './lib/registered-draft-snap'
557
753
  export { clearRoofDuplicateMetadata, duplicateRoofSubtree } from './lib/roof-duplication'
558
754
  // Roof wall-face hit resolution + overlap guard — shared by the
559
755
  // kind-owned door / window tools in `@pascal-app/nodes` and the item
560
756
  // placement coordinator's roof-wall strategy.
561
757
  export { hasRoofFaceChildOverlap, type RoofWallHit, resolveRoofWallHit } from './lib/roof-wall-hit'
758
+ export { WALL_PUSH_AFFORDANCE, type WallPushArrowPayload } from './lib/room-handle-drag'
759
+ export type { RoomKey, RoomSelectionRecord } from './lib/room-selection'
760
+ export { popRoomSelection, selectRoom } from './lib/room-selection-commands'
761
+ export {
762
+ captureElementActionOrigin,
763
+ completeElementAction,
764
+ type ElementActionOrigin,
765
+ } from './lib/room-zone-routing'
562
766
  export type { SceneGraph } from './lib/scene'
563
- export { applySceneGraphToEditor } from './lib/scene'
767
+ export { applySceneGraphToEditor, getSavedSceneDocument } from './lib/scene'
768
+ export {
769
+ forEachSceneMaterialRef,
770
+ referencedSceneMaterialIds,
771
+ remapSceneMaterialRefs,
772
+ sceneMaterialUsageCounts,
773
+ } from './lib/scene-material-refs'
564
774
  export { movementSfxStepKey } from './lib/sfx/movement-tick'
565
- export { triggerSFX } from './lib/sfx-bus'
775
+ export { emitDeleteSFX, triggerSFX } from './lib/sfx-bus'
566
776
  export { playSFX, type SFXName, type SFXPlaybackOptions } from './lib/sfx-player'
777
+ export { showSidebarPanel } from './lib/sidebar-panel'
567
778
  export {
568
779
  clearSlabSnapFeedback,
569
780
  resolveSlabEdgeBandSnap,
@@ -575,12 +786,14 @@ export {
575
786
  type SlabPlanSnapResult,
576
787
  } from './lib/slab-plan-snap'
577
788
  export {
789
+ cycleSnappingModeIn,
578
790
  getSnappingModeLabel,
579
791
  resolveSnapFlags,
580
792
  type SnapContext,
581
793
  type SnapFlags,
582
794
  type SnappingMode,
583
795
  } from './lib/snapping-mode'
796
+ export { getSpatialPointerId, spatialPointerInput } from './lib/spatial-pointer-input'
584
797
  export { duplicateStairSubtree } from './lib/stair-duplication'
585
798
  export {
586
799
  getBuildingLevelsForLevel,
@@ -590,6 +803,7 @@ export {
590
803
  resolveStairPlacementLevelId,
591
804
  resolveStairToLevelId,
592
805
  } from './lib/stair-levels'
806
+ export { surfaceAttachmentId, surfaceFramePose, updateSurfaceNode } from './lib/surface-attachment'
593
807
  export {
594
808
  clearSurfacePlanSnapFeedback,
595
809
  resolveSurfacePlanPointSnap,
@@ -597,18 +811,58 @@ export {
597
811
  type SurfacePlanSnapInput,
598
812
  type SurfacePlanSnapResult,
599
813
  } from './lib/surface-plan-snap'
814
+ // The Build panel's Outdoor → Terrace tool (an outdoor room: no walls, no ceiling).
600
815
  export {
816
+ cancelTerraceDraft,
817
+ startTerraceDraft,
818
+ useTerraceDraft,
819
+ } from './lib/terrace-draft'
820
+ export { useTerrainPanelRows } from './lib/terrain-panel-model'
821
+ export {
822
+ brushRadiusRange,
823
+ clipTerrainPatchToSite,
824
+ commitStroke,
601
825
  fieldExtentForSite,
602
826
  flattenSite,
603
827
  resetSiteTerrain,
604
828
  resolveFlattenTarget,
605
829
  sculptFieldForSite,
830
+ terrainPointInsideSite,
606
831
  } from './lib/terrain-sculpt'
607
832
  export { exportSceneToUsdz, type UsdzExportOptions } from './lib/usdz-export'
833
+ export { useLinearDisplay } from './lib/use-linear-display'
608
834
  // `cn` (twMerge + clsx) — used by kind-owned panels in `@pascal-app/
609
835
  // nodes` so they don't need their own copy / their own tailwind-merge
610
836
  // dependency.
611
837
  export { cn } from './lib/utils'
838
+ export {
839
+ applyViewerClick,
840
+ applyViewerHover,
841
+ framedLookAt,
842
+ frameViewerCamera,
843
+ useViewerFloorDisplay,
844
+ type ViewerPick,
845
+ type ViewerSource,
846
+ } from './lib/viewer-selection'
847
+ export {
848
+ getWallDrawVariant,
849
+ selectWallDrawVariant,
850
+ useWallDrawVariant,
851
+ type WallDrawVariant,
852
+ } from './lib/wall-draw-variant'
853
+ export {
854
+ addWallPolygonDraftCorner,
855
+ commitWallPolygonDraft,
856
+ discardWallPolygonDraft,
857
+ startWallPolygonDraft,
858
+ wallPolygonDraftWalls,
859
+ } from './lib/wall-polygon-draft'
860
+ export {
861
+ closeWindowOpenState,
862
+ getDisplayedWindowValue,
863
+ isOperableWindowType,
864
+ openWindowOpenState,
865
+ } from './lib/window-interaction'
612
866
  export {
613
867
  getActiveBuildingPose,
614
868
  projectAlignmentGuidesWorldToActiveBuildingLocal,
@@ -625,6 +879,8 @@ export { type CommandAction, useCommandRegistry } from './store/use-command-regi
625
879
  export {
626
880
  DRAWING_TYPE_OPTIONS,
627
881
  default as useDrawingView,
882
+ EDITOR_DRAWING_TYPE_OPTIONS,
883
+ type EditorDrawingType,
628
884
  } from './store/use-drawing-view'
629
885
  export type {
630
886
  CaptureMode,
@@ -632,7 +888,6 @@ export type {
632
888
  Mode,
633
889
  SnapshotCropMode,
634
890
  SnapshotStandardAspect,
635
- SplitOrientation,
636
891
  StructureTool,
637
892
  Tool,
638
893
  ToolDefaults,
@@ -652,6 +907,7 @@ export {
652
907
  isAngleSnapActive,
653
908
  isGridSnapActive,
654
909
  isMagneticSnapActive,
910
+ selectDefaultBuildingAndLevel,
655
911
  } from './store/use-editor'
656
912
  export { default as useFacingPose, type FacingPose } from './store/use-facing-pose'
657
913
  export { default as useFenceCurveDraft } from './store/use-fence-curve-draft'
@@ -728,3 +984,14 @@ export {
728
984
  type WallSnapKind,
729
985
  type WallSnapPoint,
730
986
  } from './store/use-wall-snap-indicator'
987
+ export {
988
+ activeViewLayout,
989
+ isViewVisible,
990
+ sceneLayout,
991
+ VIEW_2D,
992
+ VIEW_3D,
993
+ type ViewLayout,
994
+ type ViewPaneIndex,
995
+ type VisibleScene,
996
+ visibleScene,
997
+ } from './store/view-layout'
@@ -0,0 +1,39 @@
1
+ import { useViewer } from '@pascal-app/viewer'
2
+ import { CATALOG_ITEMS, type CatalogItem } from '../components/ui/item-catalog/catalog-items'
3
+ import useEditor, { type CatalogCategory } from '../store/use-editor'
4
+
5
+ export function filterCatalogItems({
6
+ category,
7
+ items = CATALOG_ITEMS,
8
+ search = '',
9
+ activePlacementTag,
10
+ activeFunctionalTag,
11
+ overrideItems,
12
+ }: {
13
+ category?: CatalogCategory
14
+ items?: readonly CatalogItem[]
15
+ search?: string
16
+ activePlacementTag?: string | null
17
+ activeFunctionalTag?: string | null
18
+ overrideItems?: readonly CatalogItem[]
19
+ }): readonly CatalogItem[] {
20
+ return (
21
+ overrideItems ??
22
+ items.filter((item) => {
23
+ if (!search && category && item.category !== category) return false
24
+ if (activePlacementTag && !item.tags?.includes(activePlacementTag)) return false
25
+ if (activeFunctionalTag && !item.tags?.includes(activeFunctionalTag)) return false
26
+ return !search || item.name.toLowerCase().includes(search.toLowerCase())
27
+ })
28
+ )
29
+ }
30
+
31
+ export function activateCatalogItem(item: CatalogItem) {
32
+ useViewer.getState().setSelection({ selectedIds: [], zoneId: null })
33
+ const editor = useEditor.getState()
34
+ editor.setSelectedItem(item)
35
+ editor.setTool(item.tool ?? 'item')
36
+ editor.setMode('build')
37
+ }
38
+
39
+ export { isCatalogItemSelected } from './catalog-selection'
@@ -0,0 +1,27 @@
1
+ import { test } from 'bun:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isCatalogItemSelected } from './catalog-selection'
4
+
5
+ test('no selection leaves every tile unhighlighted, including items without model URLs', () => {
6
+ for (const item of [{ id: 'chair' }, { id: 'cabinet' }]) {
7
+ assert.equal(isCatalogItemSelected(item, null), false)
8
+ }
9
+ })
10
+
11
+ test('only the chosen item is highlighted when model URLs are missing or shared', () => {
12
+ for (const src of [undefined, '/shared-model.glb']) {
13
+ const items = [
14
+ { id: 'first', src },
15
+ { id: 'second', src },
16
+ ]
17
+ assert.deepEqual(
18
+ items.map((item) => isCatalogItemSelected(item, items[1]!)),
19
+ [false, true],
20
+ )
21
+ }
22
+ })
23
+
24
+ test('selection follows identity across reloaded catalog objects', () => {
25
+ assert.equal(isCatalogItemSelected({ id: 'chair' }, { id: 'chair' }), true)
26
+ assert.equal(isCatalogItemSelected({ id: 'chair' }, { id: 'table' }), false)
27
+ })