@pascal-app/core 0.9.1 → 1.0.0-beta.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.
- package/README.md +17 -10
- package/dist/events/bus.d.ts +49 -2
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/scene-registry/item-clip-registry.d.ts +18 -0
- package/dist/hooks/scene-registry/item-clip-registry.d.ts.map +1 -0
- package/dist/hooks/scene-registry/item-clip-registry.js +10 -0
- package/dist/hooks/scene-registry/scene-registry.d.ts +8 -1
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +27 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +17 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +61 -8
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +135 -28
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +427 -271
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +46 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +208 -9
- package/dist/hooks/spatial-grid/support-host-id.d.ts +3 -0
- package/dist/hooks/spatial-grid/support-host-id.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-id.js +2 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts +51 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-patch.js +164 -0
- package/dist/index.d.ts +33 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -10
- package/dist/lib/level-name.d.ts +4 -0
- package/dist/lib/level-name.d.ts.map +1 -0
- package/dist/lib/level-name.js +10 -0
- package/dist/lib/measurement-geometry.d.ts +23 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -0
- package/dist/lib/measurement-geometry.js +249 -0
- package/dist/lib/polygon-geometry.d.ts +0 -1
- package/dist/lib/polygon-geometry.d.ts.map +1 -1
- package/dist/lib/polygon-geometry.js +0 -18
- package/dist/lib/selection-proxy.d.ts +4 -0
- package/dist/lib/selection-proxy.d.ts.map +1 -0
- package/dist/lib/selection-proxy.js +12 -0
- package/dist/lib/slab-polygon.d.ts +31 -2
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +557 -31
- package/dist/lib/slots.d.ts +14 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +26 -0
- package/dist/lib/space-detection.d.ts +40 -6
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +574 -192
- package/dist/lib/terrain-brush.d.ts +163 -0
- package/dist/lib/terrain-brush.d.ts.map +1 -0
- package/dist/lib/terrain-brush.js +359 -0
- package/dist/lib/terrain-codec.d.ts +51 -0
- package/dist/lib/terrain-codec.d.ts.map +1 -0
- package/dist/lib/terrain-codec.js +167 -0
- package/dist/lib/terrain-field.d.ts +150 -0
- package/dist/lib/terrain-field.d.ts.map +1 -0
- package/dist/lib/terrain-field.js +248 -0
- package/dist/lib/terrain-raycast.d.ts +44 -0
- package/dist/lib/terrain-raycast.d.ts.map +1 -0
- package/dist/lib/terrain-raycast.js +188 -0
- package/dist/lib/terrain-source.d.ts +60 -0
- package/dist/lib/terrain-source.d.ts.map +1 -0
- package/dist/lib/terrain-source.js +90 -0
- package/dist/lib/terrain-support.d.ts +60 -0
- package/dist/lib/terrain-support.d.ts.map +1 -0
- package/dist/lib/terrain-support.js +150 -0
- package/dist/lib/wall-distance.d.ts +60 -0
- package/dist/lib/wall-distance.d.ts.map +1 -0
- package/dist/lib/wall-distance.js +85 -0
- package/dist/lib/zone-quantities.d.ts +21 -0
- package/dist/lib/zone-quantities.d.ts.map +1 -0
- package/dist/lib/zone-quantities.js +428 -0
- package/dist/material-library.d.ts +28 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +2233 -441
- package/dist/registry/handles.d.ts +91 -3
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +3 -3
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/registry/registry.d.ts +46 -3
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +82 -1
- package/dist/registry/subtree.d.ts.map +1 -1
- package/dist/registry/subtree.js +8 -1
- package/dist/registry/types.d.ts +781 -39
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/schema/index.d.ts +27 -8
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +23 -6
- package/dist/schema/material.d.ts +3 -2
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +7 -5
- package/dist/schema/nodes/box-vent.d.ts +2 -2
- package/dist/schema/nodes/cabinet.d.ts +536 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -0
- package/dist/schema/nodes/cabinet.js +139 -0
- package/dist/schema/nodes/ceiling.d.ts +4 -3
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +11 -1
- package/dist/schema/nodes/chimney.d.ts +4 -4
- package/dist/schema/nodes/column.d.ts +4 -2
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +5 -0
- package/dist/schema/nodes/construction-dimension.d.ts +195 -0
- package/dist/schema/nodes/construction-dimension.d.ts.map +1 -0
- package/dist/schema/nodes/construction-dimension.js +151 -0
- package/dist/schema/nodes/cupola.d.ts +2 -2
- package/dist/schema/nodes/door.d.ts +42 -5
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +32 -0
- package/dist/schema/nodes/dormer.d.ts +8 -8
- package/dist/schema/nodes/dormer.js +1 -1
- package/dist/schema/nodes/downspout.d.ts +2 -2
- package/dist/schema/nodes/duct-fitting.d.ts +91 -0
- package/dist/schema/nodes/duct-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/duct-fitting.js +92 -0
- package/dist/schema/nodes/duct-segment.d.ts +61 -0
- package/dist/schema/nodes/duct-segment.d.ts.map +1 -0
- package/dist/schema/nodes/duct-segment.js +73 -0
- package/dist/schema/nodes/duct-terminal.d.ts +58 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -0
- package/dist/schema/nodes/duct-terminal.js +53 -0
- package/dist/schema/nodes/elevator.d.ts +3 -2
- package/dist/schema/nodes/elevator.d.ts.map +1 -1
- package/dist/schema/nodes/elevator.js +3 -0
- package/dist/schema/nodes/eyebrow-vent.d.ts +2 -2
- package/dist/schema/nodes/fence.d.ts +20 -2
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +33 -2
- package/dist/schema/nodes/gutter.d.ts +2 -2
- package/dist/schema/nodes/hvac-equipment.d.ts +64 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -0
- package/dist/schema/nodes/hvac-equipment.js +57 -0
- package/dist/schema/nodes/item.d.ts +9 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +24 -0
- package/dist/schema/nodes/level.d.ts +2 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +12 -31
- package/dist/schema/nodes/lineset.d.ts +42 -0
- package/dist/schema/nodes/lineset.d.ts.map +1 -0
- package/dist/schema/nodes/lineset.js +38 -0
- package/dist/schema/nodes/liquid-line.d.ts +34 -0
- package/dist/schema/nodes/liquid-line.d.ts.map +1 -0
- package/dist/schema/nodes/liquid-line.js +24 -0
- package/dist/schema/nodes/measurement.d.ts +306 -0
- package/dist/schema/nodes/measurement.d.ts.map +1 -0
- package/dist/schema/nodes/measurement.js +87 -0
- package/dist/schema/nodes/pipe-fitting.d.ts +56 -0
- package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-fitting.js +45 -0
- package/dist/schema/nodes/pipe-segment.d.ts +48 -0
- package/dist/schema/nodes/pipe-segment.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-segment.js +36 -0
- package/dist/schema/nodes/pipe-trap.d.ts +43 -0
- package/dist/schema/nodes/pipe-trap.d.ts.map +1 -0
- package/dist/schema/nodes/pipe-trap.js +36 -0
- package/dist/schema/nodes/ridge-vent.d.ts +18 -3
- package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
- package/dist/schema/nodes/ridge-vent.js +221 -3
- package/dist/schema/nodes/roof-segment-shape.d.ts +90 -0
- package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-shape.js +318 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts +101 -0
- package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment-walls.js +330 -0
- package/dist/schema/nodes/roof-segment.d.ts +84 -8
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +290 -5
- package/dist/schema/nodes/roof.d.ts +8 -8
- package/dist/schema/nodes/shelf.d.ts +4 -2
- package/dist/schema/nodes/shelf.d.ts.map +1 -1
- package/dist/schema/nodes/shelf.js +8 -0
- package/dist/schema/nodes/site.d.ts +9 -0
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/site.js +8 -6
- package/dist/schema/nodes/skylight.d.ts +10 -10
- package/dist/schema/nodes/slab.d.ts +8 -2
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +18 -2
- package/dist/schema/nodes/solar-panel.d.ts +4 -4
- package/dist/schema/nodes/spawn.d.ts +1 -0
- package/dist/schema/nodes/spawn.d.ts.map +1 -1
- package/dist/schema/nodes/spawn.js +2 -0
- package/dist/schema/nodes/stair-segment.d.ts +4 -4
- package/dist/schema/nodes/stair.d.ts +16 -13
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +11 -1
- package/dist/schema/nodes/structural-grid.d.ts +27 -0
- package/dist/schema/nodes/structural-grid.d.ts.map +1 -0
- package/dist/schema/nodes/structural-grid.js +17 -0
- package/dist/schema/nodes/turbine-vent.d.ts +2 -2
- package/dist/schema/nodes/wall.d.ts +248 -6
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +266 -0
- package/dist/schema/nodes/window.d.ts +40 -3
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +30 -0
- package/dist/schema/nodes/zone.d.ts +22 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +21 -0
- package/dist/schema/scene-material.d.ts +41 -0
- package/dist/schema/scene-material.d.ts.map +1 -0
- package/dist/schema/scene-material.js +9 -0
- package/dist/schema/terrain.d.ts +28 -0
- package/dist/schema/terrain.d.ts.map +1 -0
- package/dist/schema/terrain.js +30 -0
- package/dist/schema/types.d.ts +1300 -97
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +27 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts +80 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.js +89 -0
- package/dist/services/alignment-anchors.d.ts.map +1 -1
- package/dist/services/alignment-anchors.js +30 -1
- package/dist/services/alignment.d.ts +5 -0
- package/dist/services/alignment.d.ts.map +1 -1
- package/dist/services/alignment.js +2 -0
- package/dist/services/hosting.d.ts +8 -0
- package/dist/services/hosting.d.ts.map +1 -1
- package/dist/services/hosting.js +13 -4
- package/dist/services/index.d.ts +9 -2
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +9 -2
- package/dist/services/level-height.d.ts +27 -0
- package/dist/services/level-height.d.ts.map +1 -0
- package/dist/services/level-height.js +94 -0
- package/dist/services/opening-guides.d.ts +141 -0
- package/dist/services/opening-guides.d.ts.map +1 -0
- package/dist/services/opening-guides.js +267 -0
- package/dist/services/port-connectivity.d.ts +115 -0
- package/dist/services/port-connectivity.d.ts.map +1 -0
- package/dist/services/port-connectivity.js +300 -0
- package/dist/services/riser-diagram.d.ts +40 -0
- package/dist/services/riser-diagram.d.ts.map +1 -0
- package/dist/services/riser-diagram.js +110 -0
- package/dist/services/snap.d.ts +9 -1
- package/dist/services/snap.d.ts.map +1 -1
- package/dist/services/snap.js +21 -1
- package/dist/services/storey.d.ts +103 -0
- package/dist/services/storey.d.ts.map +1 -0
- package/dist/services/storey.js +296 -0
- package/dist/services/system-graph.d.ts +30 -0
- package/dist/services/system-graph.d.ts.map +1 -0
- package/dist/services/system-graph.js +164 -0
- package/dist/services/validate-dwv.d.ts +32 -0
- package/dist/services/validate-dwv.d.ts.map +1 -0
- package/dist/services/validate-dwv.js +118 -0
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +141 -4
- package/dist/store/history-control.d.ts +31 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +130 -0
- package/dist/store/use-live-terrain.d.ts +65 -0
- package/dist/store/use-live-terrain.d.ts.map +1 -0
- package/dist/store/use-live-terrain.js +31 -0
- package/dist/store/use-live-transforms.d.ts +8 -0
- package/dist/store/use-live-transforms.d.ts.map +1 -1
- package/dist/store/use-scene.d.ts +47 -3
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +992 -55
- package/dist/systems/elevator/elevator-opening-system.d.ts +1 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-opening-system.js +27 -21
- package/dist/systems/elevator/elevator-service.d.ts +0 -2
- package/dist/systems/elevator/elevator-service.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-service.js +2 -24
- package/dist/systems/fence/fence-centerline.d.ts +12 -0
- package/dist/systems/fence/fence-centerline.d.ts.map +1 -0
- package/dist/systems/fence/fence-centerline.js +37 -0
- package/dist/systems/fence/fence-spline.d.ts +39 -0
- package/dist/systems/fence/fence-spline.d.ts.map +1 -0
- package/dist/systems/fence/fence-spline.js +196 -0
- package/dist/systems/slab/slab-placement.d.ts +11 -0
- package/dist/systems/slab/slab-placement.d.ts.map +1 -0
- package/dist/systems/slab/slab-placement.js +14 -0
- package/dist/systems/slab/slab-support.d.ts +137 -0
- package/dist/systems/slab/slab-support.d.ts.map +1 -0
- package/dist/systems/slab/slab-support.js +557 -0
- package/dist/systems/stair/stair-footprint.d.ts.map +1 -1
- package/dist/systems/stair/stair-footprint.js +21 -11
- package/dist/systems/stair/stair-opening-preview.d.ts +1300 -505
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +19 -33
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-system.js +32 -4
- package/dist/systems/stair/stair-rise.d.ts +22 -0
- package/dist/systems/stair/stair-rise.d.ts.map +1 -0
- package/dist/systems/stair/stair-rise.js +79 -0
- package/dist/systems/wall/wall-curve.d.ts +10 -0
- package/dist/systems/wall/wall-curve.d.ts.map +1 -1
- package/dist/systems/wall/wall-curve.js +1 -1
- package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
- package/dist/systems/wall/wall-mitering.js +44 -8
- package/dist/systems/wall/wall-top.d.ts +40 -0
- package/dist/systems/wall/wall-top.d.ts.map +1 -0
- package/dist/systems/wall/wall-top.js +46 -0
- package/dist/utils/clone-scene-graph.d.ts +1 -0
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +56 -5
- package/dist/utils/heal-scene-graph.d.ts +18 -0
- package/dist/utils/heal-scene-graph.d.ts.map +1 -0
- package/dist/utils/heal-scene-graph.js +106 -0
- package/dist/validation/validate-build-json.d.ts +3 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +90 -5
- package/package.json +4 -4
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +0 -2
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +0 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +0 -273
- package/dist/lib/space-detection-pause.test.d.ts +0 -2
- package/dist/lib/space-detection-pause.test.d.ts.map +0 -1
- package/dist/lib/space-detection-pause.test.js +0 -42
- package/dist/lib/space-detection.test.d.ts +0 -2
- package/dist/lib/space-detection.test.d.ts.map +0 -1
- package/dist/lib/space-detection.test.js +0 -77
- package/dist/registry/registry.test.d.ts +0 -2
- package/dist/registry/registry.test.d.ts.map +0 -1
- package/dist/registry/registry.test.js +0 -183
- package/dist/registry/relations-resolver.test.d.ts +0 -2
- package/dist/registry/relations-resolver.test.d.ts.map +0 -1
- package/dist/registry/relations-resolver.test.js +0 -183
- package/dist/registry/scene-api.test.d.ts +0 -2
- package/dist/registry/scene-api.test.d.ts.map +0 -1
- package/dist/registry/scene-api.test.js +0 -183
- package/dist/registry/subtree.test.d.ts +0 -2
- package/dist/registry/subtree.test.d.ts.map +0 -1
- package/dist/registry/subtree.test.js +0 -133
- package/dist/schema/asset-url.test.d.ts +0 -2
- package/dist/schema/asset-url.test.d.ts.map +0 -1
- package/dist/schema/asset-url.test.js +0 -134
- package/dist/services/alignment-anchors.test.d.ts +0 -2
- package/dist/services/alignment-anchors.test.d.ts.map +0 -1
- package/dist/services/alignment-anchors.test.js +0 -383
- package/dist/services/alignment.test.d.ts +0 -2
- package/dist/services/alignment.test.d.ts.map +0 -1
- package/dist/services/alignment.test.js +0 -92
- package/dist/services/drag-session.test.d.ts +0 -2
- package/dist/services/drag-session.test.d.ts.map +0 -1
- package/dist/services/drag-session.test.js +0 -219
- package/dist/services/hosting.test.d.ts +0 -2
- package/dist/services/hosting.test.d.ts.map +0 -1
- package/dist/services/hosting.test.js +0 -199
- package/dist/services/movement.test.d.ts +0 -2
- package/dist/services/movement.test.d.ts.map +0 -1
- package/dist/services/movement.test.js +0 -133
- package/dist/services/single-undo-dance.test.d.ts +0 -2
- package/dist/services/single-undo-dance.test.d.ts.map +0 -1
- package/dist/services/single-undo-dance.test.js +0 -210
- package/dist/services/snap.test.d.ts +0 -2
- package/dist/services/snap.test.d.ts.map +0 -1
- package/dist/services/snap.test.js +0 -95
- package/dist/store/actions/node-mutation-sanitize.test.d.ts +0 -2
- package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +0 -1
- package/dist/store/actions/node-mutation-sanitize.test.js +0 -147
- package/dist/store/actions/reparent.test.d.ts +0 -2
- package/dist/store/actions/reparent.test.d.ts.map +0 -1
- package/dist/store/actions/reparent.test.js +0 -212
- package/dist/store/use-scene-elevator-migration.test.d.ts +0 -2
- package/dist/store/use-scene-elevator-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-elevator-migration.test.js +0 -109
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-opening-sync.test.js +0 -146
- package/dist/systems/elevator/elevator-runtime.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-runtime.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-runtime.test.js +0 -64
- package/dist/systems/stair/stair-opening-preview.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-preview.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-preview.test.js +0 -80
- package/dist/systems/stair/stair-opening-sync.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-sync.test.js +0 -446
- package/dist/utils/clone-scene-graph.test.d.ts +0 -2
- package/dist/utils/clone-scene-graph.test.d.ts.map +0 -1
- package/dist/utils/clone-scene-graph.test.js +0 -59
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { nodeRegistry } from '../../registry/registry';
|
|
2
|
+
import { AnyNode as AnyNodeSchema, createDefaultRidgeVentsForSegment, getEffectiveWallSurfaceMaterial, getWallSurfaceMaterialSignature, isAutoRidgeVentEnabled, isDefaultRidgeVentNode, } from '../../schema';
|
|
3
|
+
const DEFAULT_RIDGE_VENT_REFRESH_FIELDS = new Set([
|
|
4
|
+
'roofType',
|
|
5
|
+
'width',
|
|
6
|
+
'depth',
|
|
7
|
+
'pitch',
|
|
8
|
+
'overhang',
|
|
9
|
+
'wallThickness',
|
|
10
|
+
'shingleThickness',
|
|
11
|
+
'gambrelLowerWidthRatio',
|
|
12
|
+
'mansardSteepWidthRatio',
|
|
13
|
+
'dutchHipWidthRatio',
|
|
14
|
+
'dutchWaistLengthRatio',
|
|
15
|
+
'dutchGabletRake',
|
|
16
|
+
]);
|
|
2
17
|
const NUMBER_FORMAT_BOUNDS = {
|
|
3
18
|
safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
|
|
4
19
|
int32: [-2147483648, 2147483647],
|
|
@@ -328,8 +343,21 @@ function parseCreatedNode(node, parentId) {
|
|
|
328
343
|
warnSanitizedNodeMutation('create', node.id, sanitized.issues);
|
|
329
344
|
return sanitized.value;
|
|
330
345
|
}
|
|
346
|
+
// An explicit `key: undefined` in update data REMOVES the key: optional
|
|
347
|
+
// fields like wall.height encode a mode by their absence (absent =
|
|
348
|
+
// plane-bound top), and zod's safeParse echoes explicit-undefined keys, so
|
|
349
|
+
// a plain spread would leave a lingering own key that breaks `'height' in
|
|
350
|
+
// node` checks.
|
|
351
|
+
function mergeNodeUpdate(currentNode, patch) {
|
|
352
|
+
const merged = { ...currentNode, ...patch };
|
|
353
|
+
for (const key of Object.keys(patch)) {
|
|
354
|
+
if (patch[key] === undefined)
|
|
355
|
+
delete merged[key];
|
|
356
|
+
}
|
|
357
|
+
return merged;
|
|
358
|
+
}
|
|
331
359
|
function parseUpdatedNode(currentNode, data) {
|
|
332
|
-
const candidate =
|
|
360
|
+
const candidate = mergeNodeUpdate(currentNode, data);
|
|
333
361
|
const parsed = AnyNodeSchema.safeParse(candidate);
|
|
334
362
|
if (parsed.success)
|
|
335
363
|
return parsed.data;
|
|
@@ -339,7 +367,35 @@ function parseUpdatedNode(currentNode, data) {
|
|
|
339
367
|
return candidate;
|
|
340
368
|
}
|
|
341
369
|
warnSanitizedNodeMutation('update', currentNode.id, sanitized.issues);
|
|
342
|
-
return
|
|
370
|
+
return mergeNodeUpdate(currentNode, sanitized.value);
|
|
371
|
+
}
|
|
372
|
+
function shouldRefreshDefaultRidgeVents(data) {
|
|
373
|
+
return Object.keys(data).some((key) => DEFAULT_RIDGE_VENT_REFRESH_FIELDS.has(key));
|
|
374
|
+
}
|
|
375
|
+
function refreshDefaultRidgeVentsForSegment(nextNodes, segment) {
|
|
376
|
+
const childIds = Array.isArray(segment.children) ? segment.children : [];
|
|
377
|
+
if (!isAutoRidgeVentEnabled(segment, nextNodes))
|
|
378
|
+
return [];
|
|
379
|
+
const defaultIds = childIds.filter((childId) => isDefaultRidgeVentNode(nextNodes[childId], segment.id));
|
|
380
|
+
const defaultIdSet = new Set(defaultIds);
|
|
381
|
+
for (const id of defaultIds) {
|
|
382
|
+
delete nextNodes[id];
|
|
383
|
+
}
|
|
384
|
+
const nextVents = createDefaultRidgeVentsForSegment(segment);
|
|
385
|
+
for (const vent of nextVents) {
|
|
386
|
+
nextNodes[vent.id] = {
|
|
387
|
+
...vent,
|
|
388
|
+
parentId: segment.id,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
nextNodes[segment.id] = {
|
|
392
|
+
...segment,
|
|
393
|
+
children: [
|
|
394
|
+
...childIds.filter((childId) => !defaultIdSet.has(childId)),
|
|
395
|
+
...nextVents.map((vent) => vent.id),
|
|
396
|
+
],
|
|
397
|
+
};
|
|
398
|
+
return nextVents.map((vent) => vent.id);
|
|
343
399
|
}
|
|
344
400
|
// Track pending RAF for updateNodesAction to prevent multiple queued callbacks
|
|
345
401
|
let pendingRafId = null;
|
|
@@ -370,7 +426,10 @@ function areWallStylesCompatible(a, b) {
|
|
|
370
426
|
return ((a.parentId ?? null) === (b.parentId ?? null) &&
|
|
371
427
|
Math.abs((a.curveOffset ?? 0) - (b.curveOffset ?? 0)) <= 1e-6 &&
|
|
372
428
|
Math.abs((a.thickness ?? 0.2) - (b.thickness ?? 0.2)) <= 1e-6 &&
|
|
373
|
-
|
|
429
|
+
// Absent height means plane-bound (follows the storey), which must never
|
|
430
|
+
// merge with an explicit height — even one that currently matches the plane.
|
|
431
|
+
(a.height == null) === (b.height == null) &&
|
|
432
|
+
Math.abs((a.height ?? 0) - (b.height ?? 0)) <= 1e-6 &&
|
|
374
433
|
aInterior === bInterior &&
|
|
375
434
|
aExterior === bExterior &&
|
|
376
435
|
a.frontSide === b.frontSide &&
|
|
@@ -575,6 +634,11 @@ export const applyNodeChangesAction = (set, get, changes) => {
|
|
|
575
634
|
}
|
|
576
635
|
}
|
|
577
636
|
nextNodes[id] = updatedNode;
|
|
637
|
+
if (updatedNode.type === 'roof-segment' && shouldRefreshDefaultRidgeVents(data)) {
|
|
638
|
+
for (const ventId of refreshDefaultRidgeVentsForSegment(nextNodes, updatedNode)) {
|
|
639
|
+
nodesToMarkDirty.add(ventId);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
578
642
|
nodesToMarkDirty.add(id);
|
|
579
643
|
}
|
|
580
644
|
for (const { node, parentId } of createOps) {
|
|
@@ -659,6 +723,7 @@ export const updateNodesAction = (set, get, updates) => {
|
|
|
659
723
|
if (get().readOnly)
|
|
660
724
|
return;
|
|
661
725
|
const parentsToUpdate = new Set();
|
|
726
|
+
const extraNodesToUpdate = new Set();
|
|
662
727
|
set((state) => {
|
|
663
728
|
const nextNodes = { ...state.nodes };
|
|
664
729
|
for (const { id, data } of updates) {
|
|
@@ -702,6 +767,11 @@ export const updateNodesAction = (set, get, updates) => {
|
|
|
702
767
|
}
|
|
703
768
|
// Apply the update
|
|
704
769
|
nextNodes[id] = updatedNode;
|
|
770
|
+
if (updatedNode.type === 'roof-segment' && shouldRefreshDefaultRidgeVents(data)) {
|
|
771
|
+
for (const ventId of refreshDefaultRidgeVentsForSegment(nextNodes, updatedNode)) {
|
|
772
|
+
extraNodesToUpdate.add(ventId);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
705
775
|
}
|
|
706
776
|
return { nodes: nextNodes };
|
|
707
777
|
});
|
|
@@ -712,6 +782,9 @@ export const updateNodesAction = (set, get, updates) => {
|
|
|
712
782
|
for (const pId of parentsToUpdate) {
|
|
713
783
|
pendingUpdates.add(pId);
|
|
714
784
|
}
|
|
785
|
+
for (const id of extraNodesToUpdate) {
|
|
786
|
+
pendingUpdates.add(id);
|
|
787
|
+
}
|
|
715
788
|
if (pendingRafId !== null) {
|
|
716
789
|
cancelAnimationFrame(pendingRafId);
|
|
717
790
|
}
|
|
@@ -728,6 +801,7 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
728
801
|
return;
|
|
729
802
|
const parentsToMarkDirty = new Set();
|
|
730
803
|
const nodesToMarkDirty = new Set();
|
|
804
|
+
const deletedIds = new Set();
|
|
731
805
|
const mergePlans = buildWallMergePlans(get().nodes, ids);
|
|
732
806
|
set((state) => {
|
|
733
807
|
const nextNodes = { ...state.nodes };
|
|
@@ -741,6 +815,13 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
741
815
|
return;
|
|
742
816
|
allIds.add(id);
|
|
743
817
|
const node = nextNodes[id];
|
|
818
|
+
const cascadeDeletes = node
|
|
819
|
+
? nodeRegistry.get(node.type)?.parametrics?.onDeleteCascade?.(node, nextNodes, allIds)
|
|
820
|
+
: null;
|
|
821
|
+
if (cascadeDeletes) {
|
|
822
|
+
for (const companionId of cascadeDeletes)
|
|
823
|
+
collect(companionId);
|
|
824
|
+
}
|
|
744
825
|
if (node && 'children' in node) {
|
|
745
826
|
for (const cid of node.children)
|
|
746
827
|
collect(cid);
|
|
@@ -751,6 +832,29 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
751
832
|
for (const plan of mergePlans) {
|
|
752
833
|
allIds.add(plan.secondaryWallId);
|
|
753
834
|
}
|
|
835
|
+
for (const id of allIds)
|
|
836
|
+
deletedIds.add(id);
|
|
837
|
+
// Let each deleted kind undo what it imposed on its neighbours (e.g. an
|
|
838
|
+
// auto-inserted elbow re-extends the duct runs it trimmed back onto the
|
|
839
|
+
// corner it replaced). Read against pre-deletion `nextNodes`; skip
|
|
840
|
+
// patches that target a node also being deleted.
|
|
841
|
+
for (const id of allIds) {
|
|
842
|
+
const node = nextNodes[id];
|
|
843
|
+
if (!node)
|
|
844
|
+
continue;
|
|
845
|
+
const onDelete = nodeRegistry.get(node.type)?.parametrics?.onDelete;
|
|
846
|
+
if (!onDelete)
|
|
847
|
+
continue;
|
|
848
|
+
for (const { id: targetId, data } of onDelete(node, nextNodes)) {
|
|
849
|
+
if (allIds.has(targetId))
|
|
850
|
+
continue;
|
|
851
|
+
const target = nextNodes[targetId];
|
|
852
|
+
if (!target)
|
|
853
|
+
continue;
|
|
854
|
+
nextNodes[targetId] = { ...target, ...data };
|
|
855
|
+
nodesToMarkDirty.add(targetId);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
754
858
|
for (const plan of mergePlans) {
|
|
755
859
|
const primaryWall = nextNodes[plan.primaryWallId];
|
|
756
860
|
if (!(primaryWall && primaryWall.type === 'wall') || allIds.has(plan.primaryWallId)) {
|
|
@@ -773,6 +877,34 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
773
877
|
nodesToMarkDirty.add(update.id);
|
|
774
878
|
}
|
|
775
879
|
}
|
|
880
|
+
// Deleting a slab strips `supportSlabId` / `deckSlabId` references from
|
|
881
|
+
// surviving nodes in the same undo commit (mirrors the collectionIds
|
|
882
|
+
// cleanup below), so those nodes re-elect their support / re-derive
|
|
883
|
+
// their rise. Deletion is the ONLY writer — a host merely reshaped away
|
|
884
|
+
// keeps the field and the read path falls back, letting hosting resume
|
|
885
|
+
// if the slab returns.
|
|
886
|
+
const deletedSlabIds = new Set();
|
|
887
|
+
for (const id of allIds) {
|
|
888
|
+
if (nextNodes[id]?.type === 'slab')
|
|
889
|
+
deletedSlabIds.add(id);
|
|
890
|
+
}
|
|
891
|
+
if (deletedSlabIds.size > 0) {
|
|
892
|
+
for (const [nodeId, node] of Object.entries(nextNodes)) {
|
|
893
|
+
if (allIds.has(nodeId))
|
|
894
|
+
continue;
|
|
895
|
+
const patch = {};
|
|
896
|
+
const hostId = node.supportSlabId;
|
|
897
|
+
if (hostId && deletedSlabIds.has(hostId))
|
|
898
|
+
patch.supportSlabId = undefined;
|
|
899
|
+
const deckId = node.deckSlabId;
|
|
900
|
+
if (deckId && deletedSlabIds.has(deckId))
|
|
901
|
+
patch.deckSlabId = undefined;
|
|
902
|
+
if (Object.keys(patch).length > 0) {
|
|
903
|
+
nextNodes[nodeId] = { ...node, ...patch };
|
|
904
|
+
nodesToMarkDirty.add(nodeId);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
}
|
|
776
908
|
for (const id of allIds) {
|
|
777
909
|
const node = nextNodes[id];
|
|
778
910
|
if (!node)
|
|
@@ -805,6 +937,11 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
805
937
|
}
|
|
806
938
|
return { nodes: nextNodes, rootNodeIds: nextRootIds, collections: nextCollections };
|
|
807
939
|
});
|
|
940
|
+
// Deleted ids must leave the dirty set: every consumer skips missing
|
|
941
|
+
// nodes without clearing them, so a mark on a deleted node would sit in
|
|
942
|
+
// the set (and defeat the consumers' empty-set early exit) forever.
|
|
943
|
+
for (const id of deletedIds)
|
|
944
|
+
get().clearDirty(id);
|
|
808
945
|
// Mark affected nodes dirty: parents of deleted nodes and their remaining children
|
|
809
946
|
// (e.g. deleting a slab affects sibling walls via level elevation changes)
|
|
810
947
|
parentsToMarkDirty.forEach((parentId) => {
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
import type { Collection, CollectionId } from '../schema/collections';
|
|
2
|
+
import type { SceneMaterial, SceneMaterialId } from '../schema/scene-material';
|
|
3
|
+
import type { AnyNode, AnyNodeId } from '../schema/types';
|
|
4
|
+
export type SceneSnapshot = {
|
|
5
|
+
nodes: Record<AnyNodeId, AnyNode>;
|
|
6
|
+
rootNodeIds: AnyNodeId[];
|
|
7
|
+
collections: Record<CollectionId, Collection>;
|
|
8
|
+
materials: Record<SceneMaterialId, SceneMaterial>;
|
|
9
|
+
installedPlugins: string[];
|
|
10
|
+
};
|
|
11
|
+
export type SceneCommitOrigin = 'local' | 'load' | 'host';
|
|
12
|
+
export type SceneCommit = {
|
|
13
|
+
origin: SceneCommitOrigin;
|
|
14
|
+
before: SceneSnapshot;
|
|
15
|
+
current: SceneSnapshot;
|
|
16
|
+
};
|
|
17
|
+
export type SceneCommitListener = (commit: SceneCommit) => void;
|
|
1
18
|
type TemporalStoreLike = {
|
|
2
19
|
temporal: {
|
|
3
20
|
getState(): {
|
|
@@ -6,9 +23,23 @@ type TemporalStoreLike = {
|
|
|
6
23
|
};
|
|
7
24
|
};
|
|
8
25
|
};
|
|
26
|
+
type TemporalHistoryStoreLike<TPastState> = {
|
|
27
|
+
temporal: {
|
|
28
|
+
getState(): {
|
|
29
|
+
pastStates: TPastState[];
|
|
30
|
+
};
|
|
31
|
+
setState(state: {
|
|
32
|
+
pastStates: TPastState[];
|
|
33
|
+
}): void;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export declare function areSceneSnapshotsEqual(left: SceneSnapshot, right: SceneSnapshot): boolean;
|
|
37
|
+
export declare function subscribeSceneCommits(listener: SceneCommitListener): () => void;
|
|
38
|
+
export declare function notifySceneCommit(commit: SceneCommit): void;
|
|
9
39
|
export declare function pauseSceneHistory(sceneStore: TemporalStoreLike): void;
|
|
10
40
|
export declare function resumeSceneHistory(sceneStore: TemporalStoreLike): void;
|
|
11
41
|
export declare function getSceneHistoryPauseDepth(): number;
|
|
12
42
|
export declare function resetSceneHistoryPauseDepth(): void;
|
|
43
|
+
export declare function runAsSingleSceneHistoryStep<TPastState, TResult>(sceneStore: TemporalHistoryStoreLike<TPastState>, run: () => TResult): TResult;
|
|
13
44
|
export {};
|
|
14
45
|
//# sourceMappingURL=history-control.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-control.d.ts","sourceRoot":"","sources":["../../src/store/history-control.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"history-control.d.ts","sourceRoot":"","sources":["../../src/store/history-control.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAIzD,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACjC,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAC7C,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;IACjD,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEzD,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,iBAAiB,CAAA;IACzB,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,aAAa,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;AAE/D,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE;QACR,QAAQ,IAAI;YACV,KAAK,IAAI,IAAI,CAAA;YACb,MAAM,IAAI,IAAI,CAAA;SACf,CAAA;KACF,CAAA;CACF,CAAA;AAED,KAAK,wBAAwB,CAAC,UAAU,IAAI;IAC1C,QAAQ,EAAE;QACR,QAAQ,IAAI;YACV,UAAU,EAAE,UAAU,EAAE,CAAA;SACzB,CAAA;QACD,QAAQ,CAAC,KAAK,EAAE;YAAE,UAAU,EAAE,UAAU,EAAE,CAAA;SAAE,GAAG,IAAI,CAAA;KACpD,CAAA;CACF,CAAA;AA+BD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAQzF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAK/E;AAYD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAiB3D;AAyBD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAKrE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAStE;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAkBD,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,OAAO,EAC7D,UAAU,EAAE,wBAAwB,CAAC,UAAU,CAAC,EAChD,GAAG,EAAE,MAAM,OAAO,GACjB,OAAO,CAuBT"}
|
|
@@ -1,4 +1,92 @@
|
|
|
1
1
|
let sceneHistoryPauseDepth = 0;
|
|
2
|
+
const sceneCommitListeners = new Set();
|
|
3
|
+
let sceneCommitTransactionDepth = 0;
|
|
4
|
+
let pendingSceneCommit = null;
|
|
5
|
+
function areSemanticValuesEqual(left, right) {
|
|
6
|
+
if (Object.is(left, right))
|
|
7
|
+
return true;
|
|
8
|
+
if (typeof left !== typeof right || left === null || right === null)
|
|
9
|
+
return false;
|
|
10
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
11
|
+
if (!(Array.isArray(left) && Array.isArray(right)) || left.length !== right.length)
|
|
12
|
+
return false;
|
|
13
|
+
return left.every((value, index) => areSemanticValuesEqual(value, right[index]));
|
|
14
|
+
}
|
|
15
|
+
if (typeof left !== 'object' || typeof right !== 'object')
|
|
16
|
+
return false;
|
|
17
|
+
const leftRecord = left;
|
|
18
|
+
const rightRecord = right;
|
|
19
|
+
const leftKeys = Object.keys(leftRecord);
|
|
20
|
+
const rightKeys = Object.keys(rightRecord);
|
|
21
|
+
if (leftKeys.length !== rightKeys.length)
|
|
22
|
+
return false;
|
|
23
|
+
for (const key of leftKeys) {
|
|
24
|
+
if (!(key in rightRecord) || !areSemanticValuesEqual(leftRecord[key], rightRecord[key])) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
export function areSceneSnapshotsEqual(left, right) {
|
|
31
|
+
return (areSemanticValuesEqual(left.nodes, right.nodes) &&
|
|
32
|
+
areSemanticValuesEqual(left.rootNodeIds, right.rootNodeIds) &&
|
|
33
|
+
areSemanticValuesEqual(left.collections, right.collections) &&
|
|
34
|
+
areSemanticValuesEqual(left.materials, right.materials) &&
|
|
35
|
+
areSemanticValuesEqual(left.installedPlugins, right.installedPlugins));
|
|
36
|
+
}
|
|
37
|
+
export function subscribeSceneCommits(listener) {
|
|
38
|
+
sceneCommitListeners.add(listener);
|
|
39
|
+
return () => {
|
|
40
|
+
sceneCommitListeners.delete(listener);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function emitSceneCommit(commit) {
|
|
44
|
+
for (const listener of [...sceneCommitListeners]) {
|
|
45
|
+
try {
|
|
46
|
+
listener(commit);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('[Scene] Scene commit listener failed', error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function notifySceneCommit(commit) {
|
|
54
|
+
if (areSceneSnapshotsEqual(commit.before, commit.current))
|
|
55
|
+
return;
|
|
56
|
+
if (sceneCommitTransactionDepth > 0) {
|
|
57
|
+
if (pendingSceneCommit) {
|
|
58
|
+
pendingSceneCommit = {
|
|
59
|
+
origin: pendingSceneCommit.origin,
|
|
60
|
+
before: pendingSceneCommit.before,
|
|
61
|
+
current: commit.current,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
pendingSceneCommit = commit;
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
emitSceneCommit(commit);
|
|
70
|
+
}
|
|
71
|
+
function beginSceneCommitTransaction() {
|
|
72
|
+
sceneCommitTransactionDepth += 1;
|
|
73
|
+
}
|
|
74
|
+
function pendingSceneCommitIsNoOp() {
|
|
75
|
+
return Boolean(pendingSceneCommit &&
|
|
76
|
+
areSceneSnapshotsEqual(pendingSceneCommit.before, pendingSceneCommit.current));
|
|
77
|
+
}
|
|
78
|
+
function endSceneCommitTransaction() {
|
|
79
|
+
if (sceneCommitTransactionDepth === 0)
|
|
80
|
+
return;
|
|
81
|
+
sceneCommitTransactionDepth -= 1;
|
|
82
|
+
if (sceneCommitTransactionDepth > 0)
|
|
83
|
+
return;
|
|
84
|
+
const commit = pendingSceneCommit;
|
|
85
|
+
pendingSceneCommit = null;
|
|
86
|
+
if (commit && !areSceneSnapshotsEqual(commit.before, commit.current)) {
|
|
87
|
+
emitSceneCommit(commit);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
2
90
|
export function pauseSceneHistory(sceneStore) {
|
|
3
91
|
if (sceneHistoryPauseDepth === 0) {
|
|
4
92
|
sceneStore.temporal.getState().pause();
|
|
@@ -20,3 +108,45 @@ export function getSceneHistoryPauseDepth() {
|
|
|
20
108
|
export function resetSceneHistoryPauseDepth() {
|
|
21
109
|
sceneHistoryPauseDepth = 0;
|
|
22
110
|
}
|
|
111
|
+
function retainedPastStateCount(before, after) {
|
|
112
|
+
for (let start = 0; start < before.length; start += 1) {
|
|
113
|
+
const retained = before.length - start;
|
|
114
|
+
if (retained > after.length)
|
|
115
|
+
continue;
|
|
116
|
+
let matches = true;
|
|
117
|
+
for (let index = 0; index < retained; index += 1) {
|
|
118
|
+
if (before[start + index] !== after[index]) {
|
|
119
|
+
matches = false;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (matches)
|
|
124
|
+
return retained;
|
|
125
|
+
}
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
export function runAsSingleSceneHistoryStep(sceneStore, run) {
|
|
129
|
+
const beforePastStates = sceneStore.temporal.getState().pastStates;
|
|
130
|
+
beginSceneCommitTransaction();
|
|
131
|
+
try {
|
|
132
|
+
const result = run();
|
|
133
|
+
const afterPastStates = sceneStore.temporal.getState().pastStates;
|
|
134
|
+
const retainedCount = retainedPastStateCount(beforePastStates, afterPastStates);
|
|
135
|
+
const addedCount = afterPastStates.length - retainedCount;
|
|
136
|
+
if (addedCount > 0 && pendingSceneCommitIsNoOp()) {
|
|
137
|
+
sceneStore.temporal.setState({ pastStates: afterPastStates.slice(0, retainedCount) });
|
|
138
|
+
}
|
|
139
|
+
else if (addedCount > 1) {
|
|
140
|
+
const firstAddedState = afterPastStates[retainedCount];
|
|
141
|
+
if (firstAddedState !== undefined) {
|
|
142
|
+
sceneStore.temporal.setState({
|
|
143
|
+
pastStates: [...afterPastStates.slice(0, retainedCount), firstAddedState],
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
endSceneCommitTransaction();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { HeightPatch, TerrainField } from '../lib/terrain-field';
|
|
2
|
+
/**
|
|
3
|
+
* In-progress terrain edits, held as a live `TerrainField` rather than as node
|
|
4
|
+
* data.
|
|
5
|
+
*
|
|
6
|
+
* This is the sculpting analogue of `useLiveNodeOverrides`, and it exists because
|
|
7
|
+
* that store cannot be reused here. An override stores *node* values, so a live
|
|
8
|
+
* terrain override would have to be a `TerrainData` — meaning every dab of a
|
|
9
|
+
* brush would base64-encode the whole field, ~11 KB at 65² and ~44 KB at 129²,
|
|
10
|
+
* dozens of times a second. Holding the decoded field instead makes a dab cost
|
|
11
|
+
* one `applyHeightPatch` (a typed-array copy) and nothing else.
|
|
12
|
+
*
|
|
13
|
+
* The store also carries the **stroke's starting field**, which is what makes the
|
|
14
|
+
* saturating stroke model possible: a brush computes `snapshot + delta · mask`
|
|
15
|
+
* rather than accumulating onto the current field, so re-crossing your own stroke
|
|
16
|
+
* cannot compound. Without a snapshot the same drag deposits material twice
|
|
17
|
+
* wherever it overlaps itself, which is the single most common way a sculpt tool
|
|
18
|
+
* feels wrong.
|
|
19
|
+
*
|
|
20
|
+
* `lastPatch` is how the renderer knows what to upload: it takes the patch,
|
|
21
|
+
* pushes exactly those rows, and never diffs the whole field.
|
|
22
|
+
*/
|
|
23
|
+
export type LiveTerrainStroke = {
|
|
24
|
+
/** The field as it was at pointer-down. Never mutated during the stroke. */
|
|
25
|
+
readonly snapshot: TerrainField;
|
|
26
|
+
/** The field as of the most recent dab — what the renderer and readers see. */
|
|
27
|
+
readonly field: TerrainField;
|
|
28
|
+
/**
|
|
29
|
+
* The most recent dab's patch, or null right after `begin`. The renderer
|
|
30
|
+
* consumes this for the dirty-rect upload; a null means "nothing new to push".
|
|
31
|
+
*/
|
|
32
|
+
readonly lastPatch: HeightPatch | null;
|
|
33
|
+
};
|
|
34
|
+
type LiveTerrainState = {
|
|
35
|
+
/** Keyed by site node id — a scene can hold more than one site. */
|
|
36
|
+
strokes: Map<string, LiveTerrainStroke>;
|
|
37
|
+
/**
|
|
38
|
+
* Start a stroke from `field`.
|
|
39
|
+
*
|
|
40
|
+
* A second `begin` for the same site *replaces* the stroke rather than being
|
|
41
|
+
* rejected — and that is a hazard, not idempotence, which is why it is spelled
|
|
42
|
+
* out here: the caller passes the field it is currently reading, and mid-stroke
|
|
43
|
+
* that field is the live one, dabs included. So a re-begin adopts uncommitted
|
|
44
|
+
* dabs as the new stroke's snapshot, where they become the saturating baseline
|
|
45
|
+
* and get persisted by the next commit — visible on screen the whole time, yet
|
|
46
|
+
* absent from history and unreachable by undo.
|
|
47
|
+
*
|
|
48
|
+
* `advance` takes the opposite stance for the same reason (a dab with no stroke
|
|
49
|
+
* is ignored rather than inventing a snapshot): the invariant is that a snapshot
|
|
50
|
+
* only ever comes from a deliberate stroke boundary. Callers own the boundary —
|
|
51
|
+
* `end` first, or don't begin.
|
|
52
|
+
*/
|
|
53
|
+
begin(siteId: string, field: TerrainField): void;
|
|
54
|
+
/** Record a dab. `field` must be the result of applying `patch`. */
|
|
55
|
+
advance(siteId: string, field: TerrainField, patch: HeightPatch): void;
|
|
56
|
+
/** The live field for a site, or undefined when no stroke is in flight. */
|
|
57
|
+
fieldOf(siteId: string): TerrainField | undefined;
|
|
58
|
+
strokeOf(siteId: string): LiveTerrainStroke | undefined;
|
|
59
|
+
/** End the stroke. The caller persists the field first if it wants to keep it. */
|
|
60
|
+
end(siteId: string): void;
|
|
61
|
+
endAll(): void;
|
|
62
|
+
};
|
|
63
|
+
declare const useLiveTerrain: import("zustand").UseBoundStore<import("zustand").StoreApi<LiveTerrainState>>;
|
|
64
|
+
export default useLiveTerrain;
|
|
65
|
+
//# sourceMappingURL=use-live-terrain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-live-terrain.d.ts","sourceRoot":"","sources":["../../src/store/use-live-terrain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAErE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;CACvC,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IACvC;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAChD,oEAAoE;IACpE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACtE,2EAA2E;IAC3E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAA;IACvD,kFAAkF;IAClF,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,QAAA,MAAM,cAAc,+EAkCjB,CAAA;AAEH,eAAe,cAAc,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
const useLiveTerrain = create((set, get) => ({
|
|
3
|
+
strokes: new Map(),
|
|
4
|
+
begin: (siteId, field) => set((state) => {
|
|
5
|
+
const next = new Map(state.strokes);
|
|
6
|
+
next.set(siteId, { snapshot: field, field, lastPatch: null });
|
|
7
|
+
return { strokes: next };
|
|
8
|
+
}),
|
|
9
|
+
advance: (siteId, field, patch) => set((state) => {
|
|
10
|
+
const current = state.strokes.get(siteId);
|
|
11
|
+
// A dab with no stroke is a bug in the caller, not something to paper over
|
|
12
|
+
// by inventing a snapshot — that would silently disable the saturating
|
|
13
|
+
// model and reintroduce compounding.
|
|
14
|
+
if (!current)
|
|
15
|
+
return state;
|
|
16
|
+
const next = new Map(state.strokes);
|
|
17
|
+
next.set(siteId, { snapshot: current.snapshot, field, lastPatch: patch });
|
|
18
|
+
return { strokes: next };
|
|
19
|
+
}),
|
|
20
|
+
fieldOf: (siteId) => get().strokes.get(siteId)?.field,
|
|
21
|
+
strokeOf: (siteId) => get().strokes.get(siteId),
|
|
22
|
+
end: (siteId) => set((state) => {
|
|
23
|
+
if (!state.strokes.has(siteId))
|
|
24
|
+
return state;
|
|
25
|
+
const next = new Map(state.strokes);
|
|
26
|
+
next.delete(siteId);
|
|
27
|
+
return { strokes: next };
|
|
28
|
+
}),
|
|
29
|
+
endAll: () => set((state) => (state.strokes.size === 0 ? state : { strokes: new Map() })),
|
|
30
|
+
}));
|
|
31
|
+
export default useLiveTerrain;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
export type LiveTransform = {
|
|
2
2
|
position: [number, number, number];
|
|
3
3
|
rotation: number;
|
|
4
|
+
/**
|
|
5
|
+
* Pointer-decided support cap (level-local Y) published by 3D drags:
|
|
6
|
+
* the elevation of the surface the cursor ray actually points at. The
|
|
7
|
+
* floor-elevation system passes it to the slab-support election so a
|
|
8
|
+
* deck above the aimed-at floor never lifts the dragged node. Absent
|
|
9
|
+
* for 2D floorplan drags (no camera ray) — election stays uncapped.
|
|
10
|
+
*/
|
|
11
|
+
supportElevationCap?: number;
|
|
4
12
|
};
|
|
5
13
|
type LiveTransformState = {
|
|
6
14
|
transforms: Map<string, LiveTransform>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-live-transforms.d.ts","sourceRoot":"","sources":["../../src/store/use-live-transforms.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"use-live-transforms.d.ts","sourceRoot":"","sources":["../../src/store/use-live-transforms.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACtC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;IACnD,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAA;IAC9C,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,IAAI,IAAI,CAAA;CACjB,CAAA;AAED,QAAA,MAAM,iBAAiB,iFAgBpB,CAAA;AAEH,eAAe,iBAAiB,CAAA"}
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
import type { TemporalState } from 'zundo';
|
|
2
2
|
import { type StoreApi, type UseBoundStore } from 'zustand';
|
|
3
3
|
import type { Collection, CollectionId } from '../schema/collections';
|
|
4
|
-
import
|
|
4
|
+
import { SceneMaterial, type SceneMaterialId } from '../schema/scene-material';
|
|
5
|
+
import { type AnyNode, type AnyNodeId } from '../schema/types';
|
|
6
|
+
import { type SceneCommitOrigin, type SceneSnapshot } from './history-control';
|
|
5
7
|
export type SceneState = {
|
|
6
8
|
nodes: Record<AnyNodeId, AnyNode>;
|
|
7
9
|
rootNodeIds: AnyNodeId[];
|
|
8
10
|
dirtyNodes: Set<AnyNodeId>;
|
|
9
11
|
collections: Record<CollectionId, Collection>;
|
|
12
|
+
materials: Record<SceneMaterialId, SceneMaterial>;
|
|
13
|
+
installedPlugins: string[];
|
|
14
|
+
hasExplicitPluginInstallState: boolean;
|
|
10
15
|
readOnly: boolean;
|
|
11
16
|
setReadOnly: (readOnly: boolean) => void;
|
|
12
17
|
loadScene: () => void;
|
|
13
18
|
clearScene: () => void;
|
|
14
19
|
unloadScene: () => void;
|
|
15
|
-
setScene: (nodes: Record<AnyNodeId, AnyNode>, rootNodeIds: AnyNodeId[]
|
|
20
|
+
setScene: (nodes: Record<AnyNodeId, AnyNode>, rootNodeIds: AnyNodeId[], extra?: {
|
|
21
|
+
collections?: Record<CollectionId, Collection>;
|
|
22
|
+
materials?: Record<SceneMaterialId, SceneMaterial>;
|
|
23
|
+
installedPlugins?: string[];
|
|
24
|
+
hasExplicitPluginInstallState?: boolean;
|
|
25
|
+
}) => void;
|
|
26
|
+
setInstalledPlugins: (pluginIds: string[], options?: {
|
|
27
|
+
explicit?: boolean;
|
|
28
|
+
}) => void;
|
|
16
29
|
markDirty: (id: AnyNodeId) => void;
|
|
17
30
|
clearDirty: (id: AnyNodeId) => void;
|
|
18
31
|
createNode: (node: AnyNode, parentId?: AnyNodeId) => void;
|
|
@@ -43,11 +56,42 @@ export type SceneState = {
|
|
|
43
56
|
updateCollection: (id: CollectionId, data: Partial<Omit<Collection, 'id'>>) => void;
|
|
44
57
|
addToCollection: (id: CollectionId, nodeId: AnyNodeId) => void;
|
|
45
58
|
removeFromCollection: (id: CollectionId, nodeId: AnyNodeId) => void;
|
|
59
|
+
addSceneMaterial: (material: SceneMaterial) => void;
|
|
60
|
+
updateSceneMaterial: (id: SceneMaterialId, data: Partial<Omit<SceneMaterial, 'id'>>) => void;
|
|
61
|
+
removeSceneMaterial: (id: SceneMaterialId) => void;
|
|
46
62
|
};
|
|
47
63
|
type UseSceneStore = UseBoundStore<StoreApi<SceneState>> & {
|
|
48
|
-
temporal: StoreApi<TemporalState<Pick<SceneState, 'nodes' | 'rootNodeIds' | 'collections'>>>;
|
|
64
|
+
temporal: StoreApi<TemporalState<Pick<SceneState, 'nodes' | 'rootNodeIds' | 'collections' | 'materials' | 'installedPlugins'>>>;
|
|
49
65
|
};
|
|
50
66
|
declare const useScene: UseSceneStore;
|
|
51
67
|
export default useScene;
|
|
68
|
+
export declare function acquireSceneReadOnlyLease(): () => void;
|
|
69
|
+
export type SceneNodePatch = {
|
|
70
|
+
id: AnyNodeId;
|
|
71
|
+
data: Partial<AnyNode>;
|
|
72
|
+
removeFields: string[];
|
|
73
|
+
};
|
|
74
|
+
export type SceneMaterialPatch = {
|
|
75
|
+
id: SceneMaterialId;
|
|
76
|
+
material: SceneMaterial | null;
|
|
77
|
+
};
|
|
78
|
+
export type ScenePatch = {
|
|
79
|
+
materialChanges: SceneMaterialPatch[];
|
|
80
|
+
nodeUpdates: SceneNodePatch[];
|
|
81
|
+
};
|
|
82
|
+
export type SceneNodeStructuralPatch = {
|
|
83
|
+
node: AnyNode;
|
|
84
|
+
position: number;
|
|
85
|
+
};
|
|
86
|
+
export type SceneOperationPatch = ScenePatch & {
|
|
87
|
+
nodeCreates: SceneNodeStructuralPatch[];
|
|
88
|
+
nodeDeletes: SceneNodeStructuralPatch[];
|
|
89
|
+
};
|
|
90
|
+
export declare function applySceneOperationPatch(changes: SceneOperationPatch): boolean;
|
|
91
|
+
export declare function applyScenePatch(changes: ScenePatch): boolean;
|
|
92
|
+
export type ApplySceneSnapshotOptions = {
|
|
93
|
+
origin: Extract<SceneCommitOrigin, 'load' | 'host'>;
|
|
94
|
+
};
|
|
95
|
+
export declare function applySceneSnapshot(snapshot: SceneSnapshot, options: ApplySceneSnapshotOptions): boolean;
|
|
52
96
|
export declare function clearSceneHistory(): void;
|
|
53
97
|
//# sourceMappingURL=use-scene.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAInE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAoBrE,OAAO,EAEL,aAAa,EACb,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAA4B,MAAM,iBAAiB,CAAA;AAOxF,OAAO,EAOL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAA;AA+nC1B,MAAM,MAAM,UAAU,GAAG;IAEvB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAGjC,WAAW,EAAE,SAAS,EAAE,CAAA;IAGxB,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;IAG1B,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAC7C,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;IACjD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,6BAA6B,EAAE,OAAO,CAAA;IAGtC,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAGxC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB,QAAQ,EAAE,CACR,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,WAAW,EAAE,SAAS,EAAE,EACxB,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;QAClD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;QAC3B,6BAA6B,CAAC,EAAE,OAAO,CAAA;KACxC,KACE,IAAI,CAAA;IACT,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IAEpF,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAEnC,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;IACzD,WAAW,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IACrE,gBAAgB,EAAE,CAAC,OAAO,EAAE;QAC1B,MAAM,CAAC,EAAE;YAAE,IAAI,EAAE,OAAO,CAAC;YAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;SAAE,EAAE,CAAA;QAClD,MAAM,CAAC,EAAE;YAAE,EAAE,EAAE,SAAS,CAAC;YAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;SAAE,EAAE,CAAA;QACpD,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;KACrB,KAAK,IAAI,CAAA;IAEV,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC3D,WAAW,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IAE3E,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IAGvC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,YAAY,CAAA;IACvE,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;IAC5C,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,CAAA;IACnF,eAAe,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAC9D,oBAAoB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAGnE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAA;IACnD,mBAAmB,EAAE,CAAC,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,CAAA;IAC5F,mBAAmB,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,IAAI,CAAA;CACnD,CAAA;AAID,KAAK,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG;IACzD,QAAQ,EAAE,QAAQ,CAChB,aAAa,CACX,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,kBAAkB,CAAC,CAC7F,CACF,CAAA;CACF,CAAA;AAYD,QAAA,MAAM,QAAQ,EAAE,aAqTf,CAAA;AAED,eAAe,QAAQ,CAAA;AAKvB,wBAAgB,yBAAyB,IAAI,MAAM,IAAI,CAgBtD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,eAAe,CAAA;IACnB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,eAAe,EAAE,kBAAkB,EAAE,CAAA;IACrC,WAAW,EAAE,cAAc,EAAE,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG;IAC7C,WAAW,EAAE,wBAAwB,EAAE,CAAA;IACvC,WAAW,EAAE,wBAAwB,EAAE,CAAA;CACxC,CAAA;AAkRD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CA0E9E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAM5D;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;CACpD,CAAA;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAyBT;AAOD,wBAAgB,iBAAiB,SAYhC"}
|