@pascal-app/editor 1.0.7 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/package.json +9 -15
  2. package/src/components/editor/action-menu-button.tsx +1 -1
  3. package/src/components/editor/alignment-3d-guide-layer.tsx +1 -1
  4. package/src/components/editor/custom-camera-controls.tsx +101 -45
  5. package/src/components/editor/duplicate-node.ts +2 -1
  6. package/src/components/editor/editor-layout-v2.tsx +1 -1
  7. package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
  8. package/src/components/editor/first-person-controls.tsx +20 -1983
  9. package/src/components/editor/fit-scene-framing.test.ts +318 -0
  10. package/src/components/editor/fit-scene-framing.ts +142 -0
  11. package/src/components/editor/floating-action-menu.tsx +5 -3
  12. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  13. package/src/components/editor/floor-openings-overlay.tsx +1 -1
  14. package/src/components/editor/floor-region-controls.tsx +8 -4
  15. package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
  16. package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
  17. package/src/components/editor/floorplan-panel.tsx +199 -30
  18. package/src/components/editor/floorplan-wall-typing-keys.test.tsx +152 -0
  19. package/src/components/editor/floorplan-wall-typing-keys.ts +79 -0
  20. package/src/components/editor/follow-pascal.test.tsx +1 -2
  21. package/src/components/editor/follow-pascal.tsx +1 -1
  22. package/src/components/editor/footprint-height-handle.tsx +2 -2
  23. package/src/components/editor/group-actions.ts +1 -2
  24. package/src/components/editor/group-floating-action-menu.tsx +1 -1
  25. package/src/components/editor/group-move-3d.ts +1 -2
  26. package/src/components/editor/group-rotate-handle.tsx +1 -2
  27. package/src/components/editor/group-transform-shared.ts +3 -1
  28. package/src/components/editor/handles/use-handle-drag.ts +1 -2
  29. package/src/components/editor/index.tsx +43 -13
  30. package/src/components/editor/inspector-extension-actions.tsx +1 -1
  31. package/src/components/editor/measurement-pill.tsx +1 -1
  32. package/src/components/editor/node-arrow-handles.tsx +2 -2
  33. package/src/components/editor/open-wall-ends-3d-layer.tsx +2 -3
  34. package/src/components/editor/open-wall-ends-hint.tsx +1 -1
  35. package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
  36. package/src/components/editor/quick-measurement-card.tsx +1 -1
  37. package/src/components/editor/room-controls.tsx +10 -6
  38. package/src/components/editor/room-handles-2d.tsx +3 -3
  39. package/src/components/editor/room-handles.tsx +4 -5
  40. package/src/components/editor/room-highlight.tsx +6 -105
  41. package/src/components/editor/room-labels.test.ts +8 -822
  42. package/src/components/editor/room-labels.tsx +41 -1670
  43. package/src/components/editor/room-webgpu-materials.test.ts +1 -1
  44. package/src/components/editor/selection-manager.tsx +5 -3
  45. package/src/components/editor/site-edge-labels.tsx +7 -3
  46. package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
  47. package/src/components/editor/use-floorplan-background-placement.ts +2 -1
  48. package/src/components/editor/views/plugins-view.tsx +1 -1
  49. package/src/components/editor/views/view-bar.tsx +9 -9
  50. package/src/components/editor/wall-measurement-label.tsx +31 -15
  51. package/src/components/editor/wall-move-side-handles.tsx +11 -7
  52. package/src/components/editor/wall-pull-grip.tsx +2 -2
  53. package/src/components/editor/wall-region-handles.tsx +2 -2
  54. package/src/components/editor/wall-snap-beacon-layer.tsx +53 -32
  55. package/src/components/editor-2d/floorplan-group-move.tsx +3 -4
  56. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +13 -13
  57. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +2 -3
  58. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +2 -1
  59. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +23 -6
  60. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
  61. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
  62. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
  63. package/src/components/editor-2d/renderers/floorplan-draft-measurement.tsx +7 -1
  64. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +14 -3
  65. package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.test.tsx +35 -0
  66. package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.tsx +65 -0
  67. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +30 -10
  68. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +39 -35
  69. package/src/components/systems/roof/roof-edit-system.test.tsx +15 -1
  70. package/src/components/systems/roof/roof-edit-system.tsx +33 -21
  71. package/src/components/tools/distribution/distribution-run-tool.test.tsx +371 -3
  72. package/src/components/tools/distribution/distribution-run-tool.tsx +151 -33
  73. package/src/components/tools/item/move-tool.tsx +1 -6
  74. package/src/components/tools/item/placement-history.test.tsx +1 -1
  75. package/src/components/tools/item/use-placement-coordinator.tsx +3 -4
  76. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +7 -3
  77. package/src/components/tools/registry/move-registry-node-tool.test.ts +42 -1
  78. package/src/components/tools/registry/move-registry-node-tool.tsx +39 -16
  79. package/src/components/tools/shared/cursor-sphere.tsx +1 -1
  80. package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
  81. package/src/components/tools/shared/placement-box.tsx +2 -6
  82. package/src/components/tools/shared/placement-coordinate-input.tsx +94 -0
  83. package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
  84. package/src/components/tools/shared/segment-angle.ts +0 -4
  85. package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
  86. package/src/components/tools/tool-manager.tsx +1 -24
  87. package/src/components/tools/wall/wall-typed-entry.test.ts +99 -0
  88. package/src/components/tools/wall/wall-typed-entry.ts +70 -0
  89. package/src/components/ui/action-menu/camera-actions.tsx +2 -2
  90. package/src/components/ui/action-menu/control-modes.tsx +1 -1
  91. package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
  92. package/src/components/ui/action-menu/index.tsx +3 -3
  93. package/src/components/ui/action-menu/measurement-control.tsx +3 -3
  94. package/src/components/ui/action-menu/placement.ts +0 -18
  95. package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
  96. package/src/components/ui/action-menu/view-toggles.tsx +5 -5
  97. package/src/components/ui/controls/finish-swatch.tsx +1 -1
  98. package/src/components/ui/controls/material-paint-panel.tsx +2 -2
  99. package/src/components/ui/controls/scene-material-list.tsx +2 -2
  100. package/src/components/ui/controls/select-control.tsx +1 -1
  101. package/src/components/ui/controls/slider-control.tsx +18 -6
  102. package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
  103. package/src/components/ui/controls/tool-options-panel.tsx +74 -44
  104. package/src/components/ui/floating-level-selector.tsx +3 -3
  105. package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
  106. package/src/components/ui/helpers/helper-manager.test.tsx +54 -1
  107. package/src/components/ui/helpers/helper-manager.tsx +55 -1
  108. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  109. package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
  110. package/src/components/ui/panels/floor-foundation-panel.tsx +3 -3
  111. package/src/components/ui/panels/floor-opening-panel.tsx +5 -5
  112. package/src/components/ui/panels/mobile-selection-bar.tsx +28 -24
  113. package/src/components/ui/panels/multi-height-mode.tsx +3 -3
  114. package/src/components/ui/panels/multi-selection-panel.tsx +1 -1
  115. package/src/components/ui/panels/node-display.ts +1 -1
  116. package/src/components/ui/panels/panel-manager.tsx +5 -3
  117. package/src/components/ui/panels/panel-wrapper.tsx +42 -19
  118. package/src/components/ui/panels/parametric-inspector.tsx +1 -1
  119. package/src/components/ui/panels/room-construction-rows.tsx +7 -7
  120. package/src/components/ui/panels/room-name-options.ts +1 -5
  121. package/src/components/ui/panels/room-openings-field.tsx +1 -1
  122. package/src/components/ui/panels/room-panel.tsx +7 -9
  123. package/src/components/ui/primitives/color-dot.tsx +2 -2
  124. package/src/components/ui/primitives/opacity-control.tsx +2 -2
  125. package/src/components/ui/primitives/sidebar.tsx +3 -3
  126. package/src/components/ui/right-stack.test.ts +13 -6
  127. package/src/components/ui/right-stack.tsx +22 -11
  128. package/src/components/ui/sidebar/icon-rail.tsx +1 -1
  129. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
  130. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  131. package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
  132. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
  133. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
  134. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +2 -6
  135. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  136. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
  137. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +1 -1
  138. package/src/components/ui/sidebar/panels/site-panel/index.tsx +3 -10
  139. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
  140. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  141. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
  142. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +1 -1
  143. package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
  144. package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
  145. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
  146. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +1 -1
  147. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
  148. package/src/components/ui/sidebar/tab-bar.tsx +1 -1
  149. package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +2 -2
  150. package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
  151. package/src/components/viewer-overlay.tsx +1 -2
  152. package/src/hooks/use-auto-frame.ts +1 -2
  153. package/src/hooks/use-keyboard.ts +1 -2
  154. package/src/hooks/use-selected-room.ts +5 -7
  155. package/src/i18n/floor-footprint-name.ts +1 -1
  156. package/src/i18n/locales/en/messages.po +1036 -306
  157. package/src/i18n/locales/en/messages.ts +1 -1
  158. package/src/i18n/locales/en-XA/messages.ts +1 -1
  159. package/src/i18n/locales/es/messages.po +2267 -439
  160. package/src/i18n/locales/fr/messages.po +2267 -439
  161. package/src/i18n/locales/ja/messages.po +2267 -439
  162. package/src/i18n/locales/zh-CN/messages.po +2267 -439
  163. package/src/i18n/locales.test.ts +1 -1
  164. package/src/index.tsx +183 -178
  165. package/src/lib/below-grade.test.tsx +4 -4
  166. package/src/lib/camera-facing.test.ts +1 -1
  167. package/src/lib/camera-facing.ts +2 -3
  168. package/src/lib/contextual-help.ts +6 -0
  169. package/src/lib/editor-level-display.ts +1 -1
  170. package/src/lib/elevation-guides.ts +21 -6
  171. package/src/lib/elevator-support.ts +1 -72
  172. package/src/lib/floor-footprints.test.ts +3 -3
  173. package/src/lib/floor-footprints.ts +1 -9
  174. package/src/lib/floor-foundation-support.test.ts +8 -3
  175. package/src/lib/floor-opening-draft.ts +2 -2
  176. package/src/lib/floor-region-session.ts +1 -1
  177. package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
  178. package/src/lib/floorplan/annotation-visibility.ts +1 -1
  179. package/src/lib/floorplan/floorplan-export.test.ts +1 -1
  180. package/src/lib/floorplan/floorplan-export.tsx +8 -11
  181. package/src/lib/floorplan/floorplan-extension.ts +4 -157
  182. package/src/lib/floorplan/floorplan-mode.ts +2 -1
  183. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
  184. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
  185. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
  186. package/src/lib/floorplan/geometry.ts +2 -112
  187. package/src/lib/floorplan/index.ts +0 -9
  188. package/src/lib/floorplan/items.ts +2 -1
  189. package/src/lib/floorplan/open-wall-ends.ts +2 -1
  190. package/src/lib/floorplan/schedules.ts +6 -3
  191. package/src/lib/floorplan/sheet-export.ts +7 -3
  192. package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
  193. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
  194. package/src/lib/follow-pascal-presentation.ts +1 -1
  195. package/src/lib/gesture-lifecycle.ts +3 -1
  196. package/src/lib/glb-export.ts +1 -1
  197. package/src/lib/interaction/scope.ts +1 -0
  198. package/src/lib/layer-thickness.ts +1 -1
  199. package/src/lib/level-selection.test.ts +18 -2
  200. package/src/lib/level-selection.ts +31 -8
  201. package/src/lib/linear-display.ts +1 -1
  202. package/src/lib/live-gesture-round-trip.test.ts +1 -1
  203. package/src/lib/material-paint.ts +1 -1
  204. package/src/lib/measurement-label.test.ts +1 -1
  205. package/src/lib/measurements.test.ts +7 -5
  206. package/src/lib/mezzanine-selection.test.ts +1 -1
  207. package/src/lib/node-action-movement.test.tsx +115 -0
  208. package/src/lib/node-action-movement.ts +2 -0
  209. package/src/lib/paint-region-mode.ts +1 -1
  210. package/src/lib/placement-metadata.ts +4 -0
  211. package/src/lib/point-ask/describe-target.ts +6 -8
  212. package/src/lib/point-ask/region.ts +1 -1
  213. package/src/lib/point-ask/session.ts +1 -2
  214. package/src/lib/print-shell-compiler.ts +12 -1
  215. package/src/lib/print-wall-solids.test.ts +11 -0
  216. package/src/lib/print-wall-solids.ts +9 -0
  217. package/src/lib/roof-duplication.test.ts +100 -0
  218. package/src/lib/roof-duplication.ts +30 -5
  219. package/src/lib/room-built-on.test.ts +2 -5
  220. package/src/lib/room-built-on.ts +1 -15
  221. package/src/lib/room-construction-commands.ts +3 -2
  222. package/src/lib/room-controls-phase6.test.ts +1 -1
  223. package/src/lib/room-handle-drag.ts +8 -37
  224. package/src/lib/room-name-catalog.test.ts +2 -1
  225. package/src/lib/room-name-messages.test.ts +2 -1
  226. package/src/lib/room-name-messages.ts +1 -118
  227. package/src/lib/room-name-storage.test.ts +2 -1
  228. package/src/lib/room-push-dimensions.test.ts +1 -1
  229. package/src/lib/room-selection-commands.ts +2 -2
  230. package/src/lib/room-selection.test.ts +6 -6
  231. package/src/lib/room-transform-session.ts +1 -2
  232. package/src/lib/room-zone-routing.ts +2 -2
  233. package/src/lib/scene-clipboard.ts +2 -1
  234. package/src/lib/selection-routing.test.ts +0 -28
  235. package/src/lib/selection-routing.ts +1 -40
  236. package/src/lib/sfx-bus.ts +8 -32
  237. package/src/lib/sfx-player.test.ts +72 -1
  238. package/src/lib/sfx-player.ts +49 -337
  239. package/src/lib/snapping-mode.test.ts +23 -1
  240. package/src/lib/viewer-selection.test.ts +38 -10
  241. package/src/lib/wall-pull.test.ts +1 -1
  242. package/src/lib/wall-pull.ts +1 -27
  243. package/src/lib/wall-region-list.ts +3 -1
  244. package/src/lib/window-interaction.test.ts +4 -2
  245. package/src/store/use-editor.tsx +22 -26
  246. package/src/store/use-floorplan-annotation-visibility.ts +5 -5
  247. package/src/store/use-placement-typing.test.ts +165 -0
  248. package/src/store/use-placement-typing.ts +186 -0
  249. package/src/store/use-wall-region-handles-selection.ts +1 -2
  250. package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
  251. package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
  252. package/src/components/editor/first-person/build-collider-world.ts +0 -549
  253. package/src/components/editor/first-person/ground-holes.test.ts +0 -128
  254. package/src/components/editor/first-person/ground-holes.ts +0 -130
  255. package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
  256. package/src/components/editor/first-person/mechanism-targets.ts +0 -88
  257. package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
  258. package/src/components/editor/first-person/terrain-collider.ts +0 -212
  259. package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
  260. package/src/components/editor/floorplan-camera-sync.ts +0 -213
  261. package/src/components/editor/localized-html.tsx +0 -22
  262. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
  263. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
  264. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
  265. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
  266. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
  267. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
  268. package/src/components/editor-2d/svg-paths.ts +0 -124
  269. package/src/components/tools/elevator/elevator-defaults.ts +0 -8
  270. package/src/components/tools/elevator/elevator-tool.tsx +0 -372
  271. package/src/components/tools/elevator/move-elevator-tool.tsx +0 -262
  272. package/src/components/ui/action-menu/action-button.tsx +0 -89
  273. package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
  274. package/src/components/ui/primitives/button.tsx +0 -69
  275. package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
  276. package/src/components/ui/primitives/popover.tsx +0 -42
  277. package/src/components/ui/primitives/switch.tsx +0 -29
  278. package/src/components/ui/primitives/tooltip.tsx +0 -57
  279. package/src/components/ui/scene-loader.tsx +0 -73
  280. package/src/components/viewer/floorplan-compass-button.tsx +0 -67
  281. package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
  282. package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
  283. package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
  284. package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
  285. package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
  286. package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
  287. package/src/components/viewer/floorplan-preview.tsx +0 -1065
  288. package/src/components/viewer/render-settings-menu.tsx +0 -294
  289. package/src/components/viewer/sky-control.tsx +0 -710
  290. package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
  291. package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
  292. package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
  293. package/src/components/viewer/viewer-controls-bar.tsx +0 -496
  294. package/src/components/viewer/viewer-hover-label.tsx +0 -42
  295. package/src/components/viewer/viewer-rooms.tsx +0 -248
  296. package/src/components/viewer/viewer-scene-header.tsx +0 -286
  297. package/src/components/viewer/viewer-selection-manager.tsx +0 -124
  298. package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
  299. package/src/components/viewer/viewer-stage-modes.ts +0 -49
  300. package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
  301. package/src/components/viewer/viewer-stage.test.tsx +0 -47
  302. package/src/components/viewer/viewer-stage.tsx +0 -221
  303. package/src/components/walkthrough-hud.tsx +0 -193
  304. package/src/hooks/use-mobile.ts +0 -19
  305. package/src/i18n/level-name.ts +0 -39
  306. package/src/i18n/scene-theme-name.ts +0 -16
  307. package/src/lib/below-grade.ts +0 -133
  308. package/src/lib/camera-pose.test.ts +0 -237
  309. package/src/lib/camera-pose.ts +0 -172
  310. package/src/lib/door-interaction.ts +0 -102
  311. package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
  312. package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
  313. package/src/lib/floorplan/floorplan-readonly.ts +0 -95
  314. package/src/lib/floorplan/marks.test.ts +0 -213
  315. package/src/lib/floorplan/marks.ts +0 -238
  316. package/src/lib/measurement-label.ts +0 -68
  317. package/src/lib/measurements.ts +0 -225
  318. package/src/lib/node-display-label.ts +0 -37
  319. package/src/lib/room-assembly-overlay.test.ts +0 -275
  320. package/src/lib/room-assembly-overlay.ts +0 -265
  321. package/src/lib/room-selection.ts +0 -417
  322. package/src/lib/scene-bounds.test.ts +0 -183
  323. package/src/lib/scene-bounds.ts +0 -169
  324. package/src/lib/typing-target.ts +0 -9
  325. package/src/lib/viewer-selection.ts +0 -595
  326. package/src/lib/window-interaction.ts +0 -142
  327. package/src/lib/zone-content.ts +0 -133
  328. package/src/store/camera-pose-store.test.ts +0 -29
  329. package/src/store/camera-pose-store.ts +0 -27
  330. package/src/store/navigation-sync-pose-store.test.ts +0 -34
  331. package/src/store/navigation-sync-pose-store.ts +0 -27
  332. package/src/store/use-audio.test.ts +0 -146
  333. package/src/store/use-audio.tsx +0 -169
  334. package/src/store/use-first-person-hud.ts +0 -40
  335. package/src/store/use-follow-pascal.test.ts +0 -62
  336. package/src/store/use-follow-pascal.ts +0 -53
@@ -1,25 +1,23 @@
1
1
  import {
2
2
  type AnyNode,
3
3
  area,
4
+ formatLinearMeasurement,
5
+ getAreaUnitLabel,
4
6
  getScaledDimensions,
5
7
  getWallCurveLength,
6
8
  getWallEffectiveHeightForNodes,
7
9
  getWallThickness,
8
10
  type ItemNode,
11
+ type LinearUnit,
12
+ type MetricNotation,
9
13
  resolveLevelId,
10
14
  type SlabNode,
11
15
  type StairNode,
16
+ squareMetersToAreaUnit,
12
17
  type WallNode,
13
18
  type WindowNode,
14
19
  type ZoneNode,
15
20
  } from '@pascal-app/core'
16
- import {
17
- formatLinearMeasurement,
18
- getAreaUnitLabel,
19
- type LinearUnit,
20
- type MetricNotation,
21
- squareMetersToAreaUnit,
22
- } from '../measurements'
23
21
  import type { PointKind, PointTarget } from './types'
24
22
 
25
23
  // Point and ask names what the finger is on (the owner, 8 October): the label chip and the
@@ -115,7 +113,7 @@ const roomOfWall = (nodes: Nodes, levelId: string, wallId: string) =>
115
113
 
116
114
  function wallHeight(wall: WallNode, nodes: Nodes): number {
117
115
  try {
118
- const height = getWallEffectiveHeightForNodes(wall, nodes as Record<string, AnyNode>)
116
+ const height = getWallEffectiveHeightForNodes(wall, nodes as Record<string, AnyNode>, 0)
119
117
  if (Number.isFinite(height) && height > 0) return height
120
118
  } catch {
121
119
  // No slab election to consult in a bare scene: the wall's own height stands.
@@ -1,4 +1,4 @@
1
- import { formatLinearMeasurement } from '../measurements'
1
+ import { formatLinearMeasurement } from '@pascal-app/core'
2
2
  import type { Rect, ScreenPoint } from './types'
3
3
 
4
4
  // A region is a view, not a selection (spec 2.3, "A region is a view, not a selection"): a
@@ -18,6 +18,7 @@ import {
18
18
  } from '@pascal-app/core'
19
19
  import { sceneViewBounds, sceneViewPose } from '@pascal-app/core/agent-operations'
20
20
  import { retractNodes, useViewer } from '@pascal-app/viewer'
21
+ import { cameraPoseStore, useFollowPascal } from '@pascal-app/viewer/ui'
21
22
  import { type Object3D, Vector2, Vector3 } from 'three'
22
23
  import {
23
24
  resolveRoofSegmentSelectionTarget,
@@ -25,9 +26,7 @@ import {
25
26
  } from '../../components/editor/selection-manager'
26
27
  import { getEditorThreeContext } from '../../components/editor/three-context-bridge'
27
28
  import { resolveEditorRoomHit } from '../../hooks/use-selected-room'
28
- import { cameraPoseStore } from '../../store/camera-pose-store'
29
29
  import useEditor, { getActiveContinuationContext } from '../../store/use-editor'
30
- import useFollowPascal from '../../store/use-follow-pascal'
31
30
  import useInteractionScope from '../../store/use-interaction-scope'
32
31
  import {
33
32
  type BubbleTarget,
@@ -148,8 +148,19 @@ function preparedWallHeight(
148
148
  },
149
149
  }
150
150
  }
151
+ if (Math.abs(node.endHeightOffset ?? 0) > 1e-5) {
152
+ return {
153
+ height: null,
154
+ diagnostic: {
155
+ severity: 'error',
156
+ code: 'unsupported_wall_print_slope',
157
+ message: `Wall ${node.id} has a sloped top that does not yet have a canonical printable solid.`,
158
+ nodeIds: [node.id],
159
+ },
160
+ }
161
+ }
151
162
 
152
- const height = getWallEffectiveHeightForNodes(node, nodes)
163
+ const height = getWallEffectiveHeightForNodes(node, nodes, 0)
153
164
  if (!Number.isFinite(height) || height <= 1e-7) {
154
165
  return {
155
166
  height: null,
@@ -155,6 +155,11 @@ describe('buildPrintableWallSolids', () => {
155
155
  { effectiveHeight: 2.5 },
156
156
  { [shaped.id]: shaped },
157
157
  )
158
+ const sloped = buildPrintableWallSolids(
159
+ { ...wall, endHeightOffset: 1.0 },
160
+ { effectiveHeight: 2.5 },
161
+ { [shaped.id]: shaped },
162
+ )
158
163
  const terrain = buildPrintableWallSolids(
159
164
  { ...wall, children: [], fillToTerrain: true },
160
165
  { effectiveHeight: 2.5 },
@@ -172,6 +177,12 @@ describe('buildPrintableWallSolids', () => {
172
177
  diagnostics: [expect.objectContaining({ code: 'unsupported_wall_print_curve' })],
173
178
  }),
174
179
  )
180
+ expect(sloped).toEqual(
181
+ expect.objectContaining({
182
+ status: 'blocked',
183
+ diagnostics: [expect.objectContaining({ code: 'unsupported_wall_print_slope' })],
184
+ }),
185
+ )
175
186
  expect(terrain).toEqual(
176
187
  expect.objectContaining({
177
188
  status: 'blocked',
@@ -27,6 +27,7 @@ export type PrintWallSolidDiagnostic = {
27
27
  code:
28
28
  | 'invalid_wall_print_dimensions'
29
29
  | 'unsupported_wall_print_curve'
30
+ | 'unsupported_wall_print_slope'
30
31
  | 'unsupported_wall_print_terrain'
31
32
  | 'unsupported_wall_print_opening_shape'
32
33
  | 'invalid_wall_print_opening'
@@ -258,6 +259,14 @@ export function buildPrintableWallSolids(
258
259
  nodeIds: [node.id],
259
260
  })
260
261
  }
262
+ if (Math.abs(node.endHeightOffset ?? 0) > DIMENSION_EPSILON) {
263
+ diagnostics.push({
264
+ severity: 'error',
265
+ code: 'unsupported_wall_print_slope',
266
+ message: `Sloped wall ${node.id} does not yet have a canonical printable solid.`,
267
+ nodeIds: [node.id],
268
+ })
269
+ }
261
270
  if (node.fillToTerrain) {
262
271
  diagnostics.push({
263
272
  severity: 'error',
@@ -0,0 +1,100 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2
+ import {
3
+ type AnyNode,
4
+ type AnyNodeDefinition,
5
+ type AnyNodeId,
6
+ BaseNode,
7
+ LevelNode,
8
+ nodeRegistry,
9
+ nodeType,
10
+ objectId,
11
+ RoofNode,
12
+ RoofSegmentNode,
13
+ registerNode,
14
+ useScene,
15
+ } from '@pascal-app/core'
16
+ import { useViewer } from '@pascal-app/viewer'
17
+ import { z } from 'zod'
18
+ import { duplicateRoofSubtree } from './roof-duplication'
19
+
20
+ // A plugin's solved roof plane: a face of the roof holding it (`capabilities.roofs`).
21
+ const RoofPlane = BaseNode.extend({
22
+ id: objectId('roofplane'),
23
+ type: nodeType('test:roof-plane'),
24
+ polygon: z.array(z.tuple([z.number(), z.number()])),
25
+ })
26
+ const roofPlanes = {
27
+ kind: 'test:roof-plane',
28
+ schemaVersion: 1,
29
+ schema: RoofPlane,
30
+ category: 'structure',
31
+ defaults: () => ({}),
32
+ capabilities: {
33
+ roofs: {
34
+ outline: (node: AnyNode) => (node as unknown as z.infer<typeof RoofPlane>).polygon,
35
+ heightAt: () => 2.9,
36
+ },
37
+ },
38
+ } as unknown as AnyNodeDefinition
39
+
40
+ const LEVEL_ID = 'level_roof-duplicate' as AnyNodeId
41
+ const ROOF_ID = 'roof_original' as AnyNodeId
42
+ const SEGMENT_ID = 'rseg_original' as AnyNodeId
43
+ const PLANE_ID = 'roofplane_original' as AnyNodeId
44
+ const POLYGON: [number, number][] = [
45
+ [0, 0],
46
+ [8, 0],
47
+ [8, 3],
48
+ ]
49
+
50
+ let restoreRegistry = () => {}
51
+ const previousScene = useScene.getState()
52
+
53
+ beforeEach(() => {
54
+ restoreRegistry = nodeRegistry._snapshot()
55
+ registerNode(roofPlanes)
56
+ useScene.setState({
57
+ nodes: {
58
+ [LEVEL_ID]: LevelNode.parse({ id: LEVEL_ID, children: [ROOF_ID] }) as AnyNode,
59
+ [ROOF_ID]: RoofNode.parse({
60
+ id: ROOF_ID,
61
+ parentId: LEVEL_ID,
62
+ children: [SEGMENT_ID, PLANE_ID],
63
+ }) as AnyNode,
64
+ [SEGMENT_ID]: RoofSegmentNode.parse({ id: SEGMENT_ID, parentId: ROOF_ID }) as AnyNode,
65
+ [PLANE_ID]: RoofPlane.parse({
66
+ id: PLANE_ID,
67
+ parentId: ROOF_ID,
68
+ polygon: POLYGON,
69
+ }) as unknown as AnyNode,
70
+ },
71
+ rootNodeIds: [LEVEL_ID],
72
+ collections: {},
73
+ dirtyNodes: new Set(),
74
+ } as never)
75
+ })
76
+
77
+ afterEach(() => {
78
+ restoreRegistry()
79
+ useViewer.getState().setSelection({ selectedIds: [] })
80
+ useScene.setState(previousScene)
81
+ useScene.temporal.getState().clear()
82
+ })
83
+
84
+ describe('duplicateRoofSubtree', () => {
85
+ test("copies the roof's faces of other kinds with it, as they stand in its frame", () => {
86
+ const { roof } = duplicateRoofSubtree(ROOF_ID, { mode: 'select' })
87
+ const nodes = useScene.getState().nodes
88
+ const copied = (nodes[roof.id as AnyNodeId] as RoofNode).children.map(
89
+ (id) => nodes[id as AnyNodeId]!,
90
+ )
91
+
92
+ expect(copied.map((node): string => node.type)).toEqual(['roof-segment', 'test:roof-plane'])
93
+ const plane = copied[1] as unknown as z.infer<typeof RoofPlane>
94
+ expect(plane.id).not.toBe(PLANE_ID)
95
+ expect(plane.id.startsWith('roofplane_')).toBe(true)
96
+ expect(plane.parentId).toBe(roof.id)
97
+ expect(plane.polygon).toEqual(POLYGON)
98
+ expect((nodes[ROOF_ID] as RoofNode).children).toEqual([SEGMENT_ID, PLANE_ID])
99
+ })
100
+ })
@@ -1,13 +1,16 @@
1
1
  'use client'
2
2
 
3
3
  import {
4
+ type AnyNode,
4
5
  type AnyNodeId,
5
6
  collectionIdsOf,
6
7
  generateId,
8
+ nodeRegistry,
7
9
  type RoofNode,
8
10
  RoofNode as RoofNodeSchema,
9
11
  type RoofSegmentNode,
10
12
  RoofSegmentNode as RoofSegmentNodeSchema,
13
+ roofFaceOf,
11
14
  sceneRegistry,
12
15
  useScene,
13
16
  } from '@pascal-app/core'
@@ -121,6 +124,23 @@ export function duplicateRoofSubtree(
121
124
  segmentSourceIds.push(childNode.id)
122
125
  }
123
126
 
127
+ // Its faces of other kinds (`capabilities.roofs`) are copied by their own schema, in the copy's
128
+ // frame as in the source's; a face that does not parse fails the copy, as a segment does.
129
+ const faceClones: { node: AnyNode; sourceId: AnyNodeId }[] = []
130
+ for (const childId of sourceRoof.children ?? []) {
131
+ const childNode = scene.nodes[childId as AnyNodeId]
132
+ const schema =
133
+ childNode && roofFaceOf(childNode) ? nodeRegistry.get(childNode.type)?.schema : undefined
134
+ if (!(childNode && schema)) continue
135
+ const { id: _id, ...fields } = structuredClone(childNode)
136
+ const node = schema.parse({
137
+ ...fields,
138
+ parentId: roofClone.id,
139
+ metadata: buildDuplicateMetadata(childNode.metadata),
140
+ }) as AnyNode
141
+ faceClones.push({ node, sourceId: childNode.id })
142
+ }
143
+
124
144
  // Each copy is in the collections its source is in.
125
145
  scene.createNodes([
126
146
  { node: roofClone, parentId, collectionIds: collectionIdsOf(scene.collections, sourceRoofId) },
@@ -129,6 +149,11 @@ export function duplicateRoofSubtree(
129
149
  parentId: roofClone.id as AnyNodeId,
130
150
  collectionIds: collectionIdsOf(scene.collections, segmentSourceIds[index]!),
131
151
  })),
152
+ ...faceClones.map(({ node, sourceId }) => ({
153
+ node,
154
+ parentId: roofClone.id as AnyNodeId,
155
+ collectionIds: collectionIdsOf(scene.collections, sourceId),
156
+ })),
132
157
  ])
133
158
 
134
159
  const nextScene = useScene.getState()
@@ -148,12 +173,12 @@ export function duplicateRoofSubtree(
148
173
 
149
174
  const segmentIds = segmentClones.map((segment) => segment.id)
150
175
  const createdChildIds = (createdRoof.children ?? []) as AnyNodeId[]
151
- const missingSegmentId = segmentIds.find(
152
- (segmentId) => !createdChildIds.includes(segmentId as AnyNodeId),
176
+ const missingChildId = [...segmentIds, ...faceClones.map(({ node }) => node.id)].find(
177
+ (childId) => !createdChildIds.includes(childId as AnyNodeId),
153
178
  )
154
- if (missingSegmentId) {
179
+ if (missingChildId) {
155
180
  throw new Error(
156
- `Duplicated roof "${createdRoof.id}" is missing cloned segment "${missingSegmentId}"`,
181
+ `Duplicated roof "${createdRoof.id}" is missing cloned child "${missingChildId}"`,
157
182
  )
158
183
  }
159
184
 
@@ -206,7 +231,7 @@ export function clearRoofDuplicateMetadata(
206
231
 
207
232
  for (const childId of roofNode.children ?? []) {
208
233
  const childNode = scene.nodes[childId as AnyNodeId]
209
- if (childNode?.type !== 'roof-segment') {
234
+ if (!childNode) {
210
235
  continue
211
236
  }
212
237
 
@@ -8,6 +8,7 @@ import {
8
8
  generateId,
9
9
  initSpaceDetectionSync,
10
10
  LevelNode,
11
+ roomFloorElevation,
11
12
  SlabNode,
12
13
  type SlabNode as SlabNodeType,
13
14
  useScene,
@@ -24,11 +25,7 @@ import {
24
25
  setRoomRelativeFloorHeight,
25
26
  stepRoomFloorElevation,
26
27
  } from './room-construction-commands'
27
- import {
28
- commitRoomElevation,
29
- ownFloorElevationBounds,
30
- roomFloorElevation,
31
- } from './room-handle-drag'
28
+ import { commitRoomElevation, ownFloorElevationBounds } from './room-handle-drag'
32
29
  import { applyRoomPlan } from './room-structure-commands'
33
30
  import { showRoomNotice, useRoomTransform } from './room-transform-session'
34
31
 
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  type AnyNode,
3
3
  roomFloorChoices as coreRoomFloorChoices,
4
+ levelFootprints,
4
5
  type PascalI18n,
5
6
  roomDrawnFloor,
6
7
  type SlabNode,
7
8
  type ZoneNode,
8
9
  } from '@pascal-app/core'
9
- import { levelFootprints } from './floor-footprints'
10
10
 
11
11
  // "Built on": which floor a room stands on. By default a room is part of its
12
12
  // connected footprint's shared floor (`floor.footprint` absent); a floor key
@@ -61,20 +61,6 @@ export function roomFloorChoices(nodes: Nodes, zoneId: string): PlateChoice[] {
61
61
  .map(({ key, plateId, name }) => ({ key, plateId, name }))
62
62
  }
63
63
 
64
- /**
65
- * The plate a room on a separate floor stands on alone: its height is that
66
- * plate's floor height (nothing else stands on it). Null for a room on the
67
- * shared floor or sharing its separate floor with other rooms.
68
- */
69
- export function roomOwnPlate(nodes: Nodes, zoneId: string): SlabNode | null {
70
- const zone = nodes[zoneId]
71
- if (!isRoom(zone) || !zone.floor?.footprint || zone.floor.support === 'open') return null
72
- const plate = listingPlate(nodes, zone)
73
- if (!plate) return null
74
- const alone = !(plate.zoneIds ?? []).some((id) => id !== zoneId && isGroundRoom(nodes[id]))
75
- return alone ? plate : null
76
- }
77
-
78
64
  /**
79
65
  * The shared floor beside a room on a separate floor, where it goes back to.
80
66
  * For a room on the shared floor, its own plate.
@@ -17,7 +17,9 @@ import {
17
17
  type NodeChange,
18
18
  planWallJustification,
19
19
  resolveCeilingHeight,
20
+ roomFloorElevation,
20
21
  roomFloorElevationFromRelative,
22
+ roomOwnPlate,
21
23
  roomSideFaces,
22
24
  runAsSingleSceneHistoryStep,
23
25
  type StructureConflict,
@@ -32,13 +34,12 @@ import useDeleteConfirmation, {
32
34
  } from '../store/use-delete-confirmation'
33
35
  import useEditor from '../store/use-editor'
34
36
  import { footprintHeightValue } from './floor-footprints'
35
- import { roomOwnPlate, roomSharedFootprint } from './room-built-on'
37
+ import { roomSharedFootprint } from './room-built-on'
36
38
  import { roomClearPolygon, roomConstructionState, roomFloorContents } from './room-construction'
37
39
  import {
38
40
  mezzanineElevationBounds,
39
41
  ownFloorElevationBounds,
40
42
  planRoomElevation,
41
- roomFloorElevation,
42
43
  } from './room-handle-drag'
43
44
  import { applyRoomPlan } from './room-structure-commands'
44
45
  import { showRoomNotice } from './room-transform-session'
@@ -9,6 +9,7 @@ import {
9
9
  generateId,
10
10
  initSpaceDetectionSync,
11
11
  LevelNode,
12
+ roomFloorElevation,
12
13
  structureChangeBatch,
13
14
  useLiveNodeOverrides,
14
15
  useScene,
@@ -33,7 +34,6 @@ import {
33
34
  getActiveRoomHandleDrag,
34
35
  planRoomPush,
35
36
  previewRoomPush,
36
- roomFloorElevation,
37
37
  roomPushHandles,
38
38
  runRoomHandleDrag,
39
39
  selectedWallDimensions,
@@ -16,12 +16,15 @@ import {
16
16
  type Point,
17
17
  planWallDivision,
18
18
  resolveMovedWallSupportSlabPatch,
19
+ roomFloorElevation,
20
+ roomOwnPlate,
19
21
  runAsSingleSceneHistoryStep,
20
22
  SEPARATOR_JOIN_REACH,
21
23
  type SeparatorNode,
22
24
  type SeparatorSpan,
23
25
  type StructureNodes,
24
26
  type StructurePlan,
27
+ separatorFloorElevation,
25
28
  setRoomFloorConstruction,
26
29
  setWallGeometry,
27
30
  setZoneEdges,
@@ -31,8 +34,9 @@ import {
31
34
  useLiveNodeOverrides,
32
35
  useScene,
33
36
  type WallNode,
37
+ type WallPushArrowPayload,
34
38
  } from '@pascal-app/core'
35
- import { useViewer } from '@pascal-app/viewer'
39
+ import { isTypingTarget, useViewer } from '@pascal-app/viewer'
36
40
  import type { Ray } from 'three'
37
41
  import { create } from 'zustand'
38
42
  import { ARROW_COLOR } from '../components/editor/handles/handle-arrow'
@@ -46,7 +50,6 @@ import { clientToPlan } from './floorplan/plan-coords'
46
50
  import { beginGesture } from './gesture-lifecycle'
47
51
  import { isHistoryShortcut } from './history'
48
52
  import { MEZZANINE_FAILED_MESSAGE, mezzanineConflictMessage } from './mezzanine-messages'
49
- import { roomOwnPlate } from './room-built-on'
50
53
  import {
51
54
  mezzanineEdgeDimensions,
52
55
  type RoomDimension,
@@ -62,7 +65,6 @@ import { applyRoomPlan } from './room-structure-commands'
62
65
  import { levelSeparatorLines, separatorWallLine } from './separator-lines'
63
66
  import { sfxEmitter } from './sfx-bus'
64
67
  import { type SpatialPointerId, spatialPointerInput } from './spatial-pointer-input'
65
- import { isTypingTarget } from './typing-target'
66
68
  import {
67
69
  nearestWallParallelTarget,
68
70
  publishWallParallelGuide,
@@ -146,19 +148,6 @@ export const useRoomHandleDrag = create<{ drag: RoomHandleDrag | null }>(() => (
146
148
 
147
149
  type Nodes = Record<string, AnyNode>
148
150
 
149
- /** The walking surface of a room: its own elevation, else its plate's. */
150
- export function roomFloorElevation(nodes: Nodes, zoneId: string): number {
151
- const zone = nodes[zoneId]
152
- if (zone?.type !== 'zone') return 0
153
- const own = roomOwnPlate(nodes, zoneId)
154
- if (own) return own.elevation
155
- if (typeof zone.floor?.elevation === 'number') return zone.floor.elevation
156
- const plate = Object.values(nodes).find(
157
- (node) => node.type === 'slab' && node.zoneIds?.includes(zoneId),
158
- )
159
- return plate?.type === 'slab' ? (plate.elevation ?? 0.05) : 0.05
160
- }
161
-
162
151
  /**
163
152
  * The stretch of a wall a push moves: `[0, 1]` is the whole wall (its
164
153
  * neighbours follow through the junction planner), anything shorter is split
@@ -206,7 +195,7 @@ function wallPushHandle(
206
195
  const offsets = getWallFaceOffsets(wall)
207
196
  const face = side === 'a' ? offsets.a : -offsets.b
208
197
  const offset = Math.max(face + HANDLE_OFFSET, HANDLE_MIN_OFFSET)
209
- const wallHeight = getWallEffectiveHeightForNodes(wall, nodes)
198
+ const wallHeight = getWallEffectiveHeightForNodes(wall, nodes, 0.5)
210
199
  return {
211
200
  key,
212
201
  wallId: wall.id,
@@ -396,14 +385,6 @@ export function separatorPushHandles(separator: SeparatorNode, floor = 0): WallP
396
385
  })
397
386
  }
398
387
 
399
- /** The floor an invisible wall lies on: the walking surface of a room it closes, else 0. */
400
- export function separatorFloorElevation(nodes: Nodes, separatorId: string): number {
401
- const zone = Object.values(nodes).find(
402
- (node) => node.type === 'zone' && node.boundarySeparatorIds.includes(separatorId),
403
- )
404
- return zone ? roomFloorElevation(nodes, zone.id) : 0
405
- }
406
-
407
388
  /**
408
389
  * Snaps a push the way the wall move always has: the wall's reference line
409
390
  * (not the travel) lands on the grid lattice along its normal, so an off-grid
@@ -642,7 +623,7 @@ function previewPushPlan(
642
623
  start: change.node.start,
643
624
  end: change.node.end,
644
625
  thickness: change.node.thickness ?? 0.1,
645
- height: getWallEffectiveHeightForNodes(change.node, nodes),
626
+ height: getWallEffectiveHeightForNodes(change.node, nodes, 0),
646
627
  },
647
628
  ]
648
629
  : []
@@ -1403,7 +1384,7 @@ export function beginWallGroupPush(wallIds: readonly string[], levelId: string):
1403
1384
  {
1404
1385
  wall,
1405
1386
  base,
1406
- top: base + getWallEffectiveHeightForNodes(wall, nodes),
1387
+ top: base + getWallEffectiveHeightForNodes(wall, nodes, 0),
1407
1388
  normal: wallPushNormal(wall),
1408
1389
  rooms: pushDimensionRooms(nodes, levelId, { wallId: wall.id, t0: 0, t1: 1 }, base),
1409
1390
  },
@@ -1488,16 +1469,6 @@ export function wallPointAt(wall: WallNode, t: number): Point {
1488
1469
  return [frame.point.x, frame.point.y]
1489
1470
  }
1490
1471
 
1491
- /**
1492
- * The affordance a floor-plan `move-arrow` carries to be a wall push arrow;
1493
- * its payload is a `WallPushArrowPayload`. The floor plan starts
1494
- * `runFloorplanWallPush` for it instead of a registry affordance session.
1495
- */
1496
- export const WALL_PUSH_AFFORDANCE = 'wall-push'
1497
-
1498
- /** A wall's or an invisible wall's side arrow: `wallId` is either. */
1499
- export type WallPushArrowPayload = { wallId: string; side: 'a' | 'b' }
1500
-
1501
1472
  type PlanPointer = (clientX: number, clientY: number) => readonly [number, number] | null
1502
1473
 
1503
1474
  /** The pointer's plan position measured along an arrow's outward normal from its spot. */
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import { type AnyNode, ZoneNode } from '@pascal-app/core'
3
+ import { ROOM_NAME_MESSAGES } from '@pascal-app/viewer/ui'
3
4
  import {
4
5
  MEZZANINE_NAME_SECTION,
5
6
  numberedRoomName,
@@ -8,7 +9,7 @@ import {
8
9
  roomNameSections,
9
10
  roomNameUseCount,
10
11
  } from './room-name-catalog'
11
- import { ROOM_NAME_MESSAGES, ROOM_NAME_SECTION_TITLES } from './room-name-messages'
12
+ import { ROOM_NAME_SECTION_TITLES } from './room-name-messages'
12
13
 
13
14
  const square: [number, number][] = [
14
15
  [0, 0],
@@ -1,8 +1,9 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import { type AnyNode, type MessageDescriptor, ZoneNode } from '@pascal-app/core'
3
+ import { displayRoomName, editedRoomName } from '@pascal-app/viewer/ui'
3
4
  import { roomNameOptions } from '../components/ui/panels/room-name-options'
4
5
  import { roomNameSections } from './room-name-catalog'
5
- import { displayRoomName, editedRoomName, localizedRoomNameSections } from './room-name-messages'
6
+ import { localizedRoomNameSections } from './room-name-messages'
6
7
 
7
8
  const FRENCH: Record<string, string> = {
8
9
  'editor.roomName.bedroom': 'Chambre',