@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,183 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
- import type { AnyNode } from '@pascal-app/core/schema'
3
- import { computeSceneBoundsXZ } from './scene-bounds'
4
-
5
- function makeWall(start: [number, number], end: [number, number]): AnyNode {
6
- return {
7
- object: 'node',
8
- id: `wall_${start.join('_')}_${end.join('_')}`,
9
- type: 'wall',
10
- parentId: null,
11
- visible: true,
12
- metadata: {},
13
- children: [],
14
- start,
15
- end,
16
- frontSide: 'unknown',
17
- backSide: 'unknown',
18
- } as unknown as AnyNode
19
- }
20
-
21
- function makeZone(polygon: [number, number][]): AnyNode {
22
- return {
23
- object: 'node',
24
- id: `zone_${polygon.length}_${polygon[0]?.[0] ?? 0}`,
25
- type: 'zone',
26
- parentId: null,
27
- visible: true,
28
- metadata: {},
29
- name: 'Zone',
30
- polygon,
31
- color: '#000000',
32
- } as unknown as AnyNode
33
- }
34
-
35
- function makeSite(points: [number, number][]): AnyNode {
36
- return {
37
- object: 'node',
38
- id: 'site_test',
39
- type: 'site',
40
- parentId: null,
41
- visible: true,
42
- metadata: {},
43
- polygon: { type: 'polygon', points },
44
- children: [],
45
- } as unknown as AnyNode
46
- }
47
-
48
- describe('computeSceneBoundsXZ', () => {
49
- test('returns null when given an empty array', () => {
50
- expect(computeSceneBoundsXZ([])).toBeNull()
51
- })
52
-
53
- test('returns null when no geometry is found on any node', () => {
54
- const barren = [
55
- {
56
- object: 'node',
57
- id: 'building_1',
58
- type: 'building',
59
- parentId: null,
60
- visible: true,
61
- metadata: {},
62
- children: [],
63
- } as unknown as AnyNode,
64
- ]
65
- expect(computeSceneBoundsXZ(barren)).toBeNull()
66
- })
67
-
68
- test('computes bounds from wall endpoints', () => {
69
- const nodes: AnyNode[] = [makeWall([0, 0], [4, 0]), makeWall([4, 0], [4, 3])]
70
- const bounds = computeSceneBoundsXZ(nodes)
71
- expect(bounds).not.toBeNull()
72
- expect(bounds!.min).toEqual([0, 0])
73
- expect(bounds!.max).toEqual([4, 3])
74
- expect(bounds!.size).toEqual([4, 3])
75
- expect(bounds!.center).toEqual([2, 1.5])
76
- })
77
-
78
- test('includes zone polygons', () => {
79
- const nodes: AnyNode[] = [
80
- makeZone([
81
- [-10, -5],
82
- [10, -5],
83
- [10, 5],
84
- [-10, 5],
85
- ]),
86
- ]
87
- const bounds = computeSceneBoundsXZ(nodes)
88
- expect(bounds).not.toBeNull()
89
- expect(bounds!.min).toEqual([-10, -5])
90
- expect(bounds!.max).toEqual([10, 5])
91
- expect(bounds!.size).toEqual([20, 10])
92
- })
93
-
94
- test('ignores the default 30×30 site bootstrap polygon', () => {
95
- const nodes: AnyNode[] = [
96
- makeSite([
97
- [-15, -15],
98
- [15, -15],
99
- [15, 15],
100
- [-15, 15],
101
- ]),
102
- makeWall([1, 1], [2, 2]),
103
- ]
104
- const bounds = computeSceneBoundsXZ(nodes)
105
- expect(bounds).not.toBeNull()
106
- // Only the wall should count — the default site polygon is skipped.
107
- expect(bounds!.min).toEqual([1, 1])
108
- expect(bounds!.max).toEqual([2, 2])
109
- })
110
-
111
- test('honours a non-default site polygon', () => {
112
- const nodes: AnyNode[] = [
113
- makeSite([
114
- [-25, -20],
115
- [25, -20],
116
- [25, 20],
117
- [-25, 20],
118
- ]),
119
- ]
120
- const bounds = computeSceneBoundsXZ(nodes)
121
- expect(bounds).not.toBeNull()
122
- expect(bounds!.min).toEqual([-25, -20])
123
- expect(bounds!.max).toEqual([25, 20])
124
- })
125
-
126
- test('combines walls, zones and positions across the flat dict', () => {
127
- const nodes: Record<string, AnyNode> = {
128
- wallA: makeWall([-8, -3], [4, -3]),
129
- wallB: makeWall([4, -3], [4, 6]),
130
- zoneA: makeZone([
131
- [-8, -3],
132
- [4, -3],
133
- [4, 6],
134
- [-8, 6],
135
- ]),
136
- item1: {
137
- object: 'node',
138
- id: 'item_1',
139
- type: 'item',
140
- parentId: null,
141
- visible: true,
142
- metadata: {},
143
- position: [7, 0, 8],
144
- rotation: [0, 0, 0],
145
- scale: [1, 1, 1],
146
- children: [],
147
- asset: {
148
- id: 'a',
149
- category: 'furniture',
150
- name: 'Chair',
151
- thumbnail: '',
152
- src: '',
153
- dimensions: [1, 1, 1],
154
- offset: [0, 0, 0],
155
- rotation: [0, 0, 0],
156
- scale: [1, 1, 1],
157
- },
158
- } as unknown as AnyNode,
159
- }
160
- const bounds = computeSceneBoundsXZ(nodes)
161
- expect(bounds).not.toBeNull()
162
- expect(bounds!.min).toEqual([-8, -3])
163
- expect(bounds!.max).toEqual([7, 8])
164
- })
165
-
166
- test('handles a single degenerate point with a minimum extent', () => {
167
- const nodes: AnyNode[] = [makeWall([2, 2], [2, 2])]
168
- const bounds = computeSceneBoundsXZ(nodes)
169
- expect(bounds).not.toBeNull()
170
- expect(bounds!.size[0]).toBeGreaterThan(0)
171
- expect(bounds!.size[1]).toBeGreaterThan(0)
172
- expect(bounds!.center).toEqual([2, 2])
173
- })
174
-
175
- test('skips non-finite coordinates', () => {
176
- const nodes: AnyNode[] = [makeWall([Number.NaN, 0], [4, 2]), makeWall([0, 0], [1, 1])]
177
- const bounds = computeSceneBoundsXZ(nodes)
178
- expect(bounds).not.toBeNull()
179
- // NaN should be ignored; the usable points are (4,2), (0,0), (1,1).
180
- expect(bounds!.min).toEqual([0, 0])
181
- expect(bounds!.max).toEqual([4, 2])
182
- })
183
- })
@@ -1,169 +0,0 @@
1
- /**
2
- * Scene bounds in the X/Z plane.
3
- *
4
- * Used by the auto-frame hook to fit the camera onto a freshly loaded scene
5
- * (see `../hooks/use-auto-frame`). The hook subscribes to the core scene
6
- * store and, when `nodes` transitions from empty → non-empty, fires a
7
- * `camera-controls:fit-scene` event on the core event bus carrying the
8
- * computed bounds.
9
- *
10
- * This module contains no rendering code: it only walks the flat-dict node
11
- * tree and derives an axis-aligned bounding box on the XZ (plan) plane.
12
- */
13
-
14
- import type { AnyNode } from '@pascal-app/core/schema'
15
-
16
- export type SceneBoundsXZ = {
17
- /** Min [x, z] in world units (meters). */
18
- min: [number, number]
19
- /** Max [x, z] in world units (meters). */
20
- max: [number, number]
21
- /** Center [x, z] = (min + max) / 2. */
22
- center: [number, number]
23
- /** Size [w, d] = max - min. */
24
- size: [number, number]
25
- }
26
-
27
- // A very small guard against degenerate bounds (e.g. a single wall of zero length).
28
- const MIN_BOUNDS_EXTENT = 0.0001
29
-
30
- function extendPoint(
31
- acc: { minX: number; minZ: number; maxX: number; maxZ: number; hasPoint: boolean },
32
- x: unknown,
33
- z: unknown,
34
- ): void {
35
- if (typeof x !== 'number' || typeof z !== 'number') return
36
- if (!(Number.isFinite(x) && Number.isFinite(z))) return
37
- if (x < acc.minX) acc.minX = x
38
- if (x > acc.maxX) acc.maxX = x
39
- if (z < acc.minZ) acc.minZ = z
40
- if (z > acc.maxZ) acc.maxZ = z
41
- acc.hasPoint = true
42
- }
43
-
44
- /**
45
- * Compute the axis-aligned XZ bounds of a scene.
46
- *
47
- * Walks every node and extracts 2D footprint points from the fields most
48
- * nodes carry:
49
- * - `start`/`end` → wall and fence endpoints in level coordinates.
50
- * - `polygon` → zone, slab, site-boundary polygons.
51
- * - `position` → building/item/door/window position; uses [x, z] only.
52
- *
53
- * Site-node polygons are intentionally excluded when they are the default
54
- * 30×30 bootstrap polygon — otherwise a brand-new empty scene would frame
55
- * an empty square around the origin. We still include site polygons that
56
- * look intentional (> 4 points, or any point outside the ±15 m default).
57
- *
58
- * Returns `null` if no usable geometry was found.
59
- */
60
- export function computeSceneBoundsXZ(
61
- nodes: AnyNode[] | Record<string, AnyNode>,
62
- ): SceneBoundsXZ | null {
63
- const list: AnyNode[] = Array.isArray(nodes) ? nodes : Object.values(nodes)
64
- if (list.length === 0) return null
65
-
66
- const acc = {
67
- minX: Number.POSITIVE_INFINITY,
68
- minZ: Number.POSITIVE_INFINITY,
69
- maxX: Number.NEGATIVE_INFINITY,
70
- maxZ: Number.NEGATIVE_INFINITY,
71
- hasPoint: false,
72
- }
73
-
74
- for (const node of list) {
75
- if (!node || typeof node !== 'object') continue
76
- const anyNode = node as unknown as Record<string, unknown>
77
-
78
- // Wall / fence endpoints in level coordinates.
79
- const start = anyNode.start as unknown
80
- const end = anyNode.end as unknown
81
- if (Array.isArray(start) && start.length >= 2) extendPoint(acc, start[0], start[1])
82
- if (Array.isArray(end) && end.length >= 2) extendPoint(acc, end[0], end[1])
83
-
84
- // Zone / slab polygons (and explicit polygon-shaped site boundaries).
85
- const polygon = anyNode.polygon as unknown
86
- if (Array.isArray(polygon)) {
87
- // Zones/slabs expose a plain array of [x,z] tuples. Site nodes nest the
88
- // points under `polygon.points` (a discriminated PropertyLineData shape).
89
- for (const point of polygon) {
90
- if (Array.isArray(point) && point.length >= 2) {
91
- extendPoint(acc, point[0], point[1])
92
- }
93
- }
94
- } else if (
95
- polygon &&
96
- typeof polygon === 'object' &&
97
- Array.isArray((polygon as { points?: unknown }).points)
98
- ) {
99
- // Site nodes only: skip the default bootstrap square so a blank scene
100
- // isn't auto-framed around an empty ±15 m box. Include any other site
101
- // polygon (more than 4 points, or any coordinate beyond the default).
102
- const points = (polygon as { points: unknown[] }).points
103
- if (node.type === 'site' && isDefaultSitePolygon(points)) {
104
- // Skip — default bootstrap polygon.
105
- } else {
106
- for (const point of points) {
107
- if (Array.isArray(point) && point.length >= 2) {
108
- extendPoint(acc, point[0], point[1])
109
- }
110
- }
111
- }
112
- }
113
-
114
- // Position on the XZ plane (3D position = [x, y, z]).
115
- const position = anyNode.position as unknown
116
- if (Array.isArray(position) && position.length >= 3) {
117
- extendPoint(acc, position[0], position[2])
118
- }
119
- }
120
-
121
- if (!acc.hasPoint) return null
122
-
123
- // Ensure a minimum extent so a single-point scene still yields a box.
124
- let minX = acc.minX
125
- let minZ = acc.minZ
126
- let maxX = acc.maxX
127
- let maxZ = acc.maxZ
128
- if (maxX - minX < MIN_BOUNDS_EXTENT) {
129
- const cx = (minX + maxX) / 2
130
- minX = cx - MIN_BOUNDS_EXTENT / 2
131
- maxX = cx + MIN_BOUNDS_EXTENT / 2
132
- }
133
- if (maxZ - minZ < MIN_BOUNDS_EXTENT) {
134
- const cz = (minZ + maxZ) / 2
135
- minZ = cz - MIN_BOUNDS_EXTENT / 2
136
- maxZ = cz + MIN_BOUNDS_EXTENT / 2
137
- }
138
-
139
- const centerX = (minX + maxX) / 2
140
- const centerZ = (minZ + maxZ) / 2
141
- return {
142
- min: [minX, minZ],
143
- max: [maxX, maxZ],
144
- center: [centerX, centerZ],
145
- size: [maxX - minX, maxZ - minZ],
146
- }
147
- }
148
-
149
- /**
150
- * Matches the `SiteNode` bootstrap polygon defined in
151
- * `packages/core/src/schema/nodes/site.ts` (a 30×30 square at the origin).
152
- * We ignore it so the default scene doesn't "auto-frame" onto an empty box.
153
- */
154
- function isDefaultSitePolygon(points: unknown[]): boolean {
155
- if (points.length !== 4) return false
156
- const expected: [number, number][] = [
157
- [-15, -15],
158
- [15, -15],
159
- [15, 15],
160
- [-15, 15],
161
- ]
162
- for (let i = 0; i < 4; i++) {
163
- const p = points[i]
164
- const e = expected[i]!
165
- if (!Array.isArray(p) || p.length < 2) return false
166
- if (p[0] !== e[0] || p[1] !== e[1]) return false
167
- }
168
- return true
169
- }
@@ -1,9 +0,0 @@
1
- // Keys typed into a field (the room-name combobox, any input, an open dialog)
2
- // belong to that field, never to a canvas gesture.
3
- const TYPING_TARGET =
4
- 'input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="combobox"], [role="textbox"], [role="dialog"], [role="alertdialog"]'
5
-
6
- export function isTypingTarget(target: EventTarget | null) {
7
- const element = target as { closest?: (selector: string) => unknown; isContentEditable?: boolean }
8
- return !!element && (element.isContentEditable === true || !!element.closest?.(TYPING_TARGET))
9
- }