@crystaldesign/real-time-viewer-next 26.13.0-beta.2 → 26.13.0-beta.21

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 (47) hide show
  1. package/build/esm/{DeckCutoutSubsystem-6453a4f4.js → DeckCutoutSubsystem-8b702df0.js} +208 -11
  2. package/build/esm/{SunLensflare-46fa6ee8.js → SunLensflare-0676ae6e.js} +1 -1
  3. package/build/esm/{WaterSurface-10a28566.js → WaterSurface-f3e878b1.js} +4 -3
  4. package/build/esm/{index-428fd8ca.js → index-6f58b1ed.js} +219 -49
  5. package/build/esm/index.js +1 -1
  6. package/build/types/real-time-viewer-next/src/config/environment.config.d.ts +1 -0
  7. package/build/types/real-time-viewer-next/src/config/environment.config.d.ts.map +1 -1
  8. package/build/types/real-time-viewer-next/src/core/ArticleSettleTracker.d.ts +12 -0
  9. package/build/types/real-time-viewer-next/src/core/ArticleSettleTracker.d.ts.map +1 -0
  10. package/build/types/real-time-viewer-next/src/core/SceneRenderer.d.ts.map +1 -1
  11. package/build/types/real-time-viewer-next/src/core/camera/CameraController.d.ts.map +1 -1
  12. package/build/types/real-time-viewer-next/src/core/camera/useCameraActions.d.ts +2 -1
  13. package/build/types/real-time-viewer-next/src/core/camera/useCameraActions.d.ts.map +1 -1
  14. package/build/types/real-time-viewer-next/src/core/camera/useCameraConstraints.d.ts.map +1 -1
  15. package/build/types/real-time-viewer-next/src/core/dimension-lines/DimensionLines3D.d.ts.map +1 -1
  16. package/build/types/real-time-viewer-next/src/core/environment/deckCutout/DeckCutoutArticleSync.d.ts.map +1 -1
  17. package/build/types/real-time-viewer-next/src/core/environment/deckCutout/articleFootprint.d.ts.map +1 -1
  18. package/build/types/real-time-viewer-next/src/core/environment/deckCutout/measureArticle.d.ts +16 -0
  19. package/build/types/real-time-viewer-next/src/core/environment/deckCutout/measureArticle.d.ts.map +1 -1
  20. package/build/types/real-time-viewer-next/src/core/environment/deckCutout/measureDiagnostics.d.ts.map +1 -1
  21. package/build/types/real-time-viewer-next/src/core/environment/scene.config.d.ts +21 -0
  22. package/build/types/real-time-viewer-next/src/core/environment/scene.config.d.ts.map +1 -1
  23. package/build/types/real-time-viewer-next/src/core/shadows/useShadowDirty.d.ts.map +1 -1
  24. package/build/types/real-time-viewer-next/src/core/water/WaterSurfaceRenderer.d.ts.map +1 -1
  25. package/build/types/real-time-viewer-next/src/presets/villa-cliff.d.ts.map +1 -1
  26. package/build/types/real-time-viewer-next/src/store/slices/camera.d.ts +6 -1
  27. package/build/types/real-time-viewer-next/src/store/slices/camera.d.ts.map +1 -1
  28. package/build/types/real-time-viewer-next/src/store/slices/selection.d.ts +5 -2
  29. package/build/types/real-time-viewer-next/src/store/slices/selection.d.ts.map +1 -1
  30. package/build/types/real-time-viewer-next/src/store/slices/versions.d.ts +9 -0
  31. package/build/types/real-time-viewer-next/src/store/slices/versions.d.ts.map +1 -1
  32. package/build/types/real-time-viewer-next/src/types/camera.d.ts +9 -6
  33. package/build/types/real-time-viewer-next/src/types/camera.d.ts.map +1 -1
  34. package/build/types/real-time-viewer-next/src/utils/cameraFraming.d.ts +7 -0
  35. package/build/types/real-time-viewer-next/src/utils/cameraFraming.d.ts.map +1 -1
  36. package/build/types/real-time-viewer-next/src/utils/cameraFraming.test.d.ts +2 -0
  37. package/build/types/real-time-viewer-next/src/utils/cameraFraming.test.d.ts.map +1 -0
  38. package/build/types/real-time-viewer-next/src/utils/geoTargets.d.ts +30 -0
  39. package/build/types/real-time-viewer-next/src/utils/geoTargets.d.ts.map +1 -0
  40. package/build/umd/463.real-time-viewer-next.umd.min.js +1 -1
  41. package/build/umd/99.real-time-viewer-next.umd.min.js +2 -0
  42. package/build/umd/99.real-time-viewer-next.umd.min.js.LICENSE.txt +1 -0
  43. package/build/umd/real-time-viewer-next.umd.min.js +1 -1
  44. package/build/umd/report.html +1 -1
  45. package/package.json +6 -2
  46. package/build/umd/673.real-time-viewer-next.umd.min.js +0 -2
  47. package/build/umd/673.real-time-viewer-next.umd.min.js.LICENSE.txt +0 -1
@@ -3486,7 +3486,14 @@ var DECK_CUTOUT_ARTICLE_RULE_CONFIG = field.group({
3486
3486
  * How far (m) below the deck top the geometry projection reaches — captures the rim, ignores the
3487
3487
  * sunk basin body.
3488
3488
  */
3489
- footprintSliceDepth: field.number(0.35)
3489
+ footprintSliceDepth: field.number(0.35),
3490
+ /**
3491
+ * Shape the cutout from these geos only: comma-separated catalog geo-name prefixes (`GEO_Pool`
3492
+ * matches `GEO_Pool`, `GEO_Pool_Rim`, …). The traced outline, the rim that places the article and
3493
+ * sizes the water, and the fallback rect then describe the basin alone, not the stairs or cover the
3494
+ * same article ships with. '' = the whole article; a prefix matching no geo falls back to it.
3495
+ */
3496
+ geoPrefix: field.value('')
3490
3497
  });
3491
3498
 
3492
3499
  /**
@@ -4434,7 +4441,7 @@ var chunk$2;
4434
4441
  /** Memoized so the preload and the lazy mount share ONE chunk request. */
4435
4442
  function loadChunk$2() {
4436
4443
  var _chunk;
4437
- return (_chunk = chunk$2) !== null && _chunk !== void 0 ? _chunk : chunk$2 = import('./WaterSurface-10a28566.js');
4444
+ return (_chunk = chunk$2) !== null && _chunk !== void 0 ? _chunk : chunk$2 = import('./WaterSurface-f3e878b1.js');
4438
4445
  }
4439
4446
 
4440
4447
  /**
@@ -4469,7 +4476,7 @@ var chunk$1;
4469
4476
  /** Memoized so the preload and the lazy mount share ONE chunk request. */
4470
4477
  function loadChunk$1() {
4471
4478
  var _chunk;
4472
- return (_chunk = chunk$1) !== null && _chunk !== void 0 ? _chunk : chunk$1 = import('./DeckCutoutSubsystem-6453a4f4.js');
4479
+ return (_chunk = chunk$1) !== null && _chunk !== void 0 ? _chunk : chunk$1 = import('./DeckCutoutSubsystem-8b702df0.js');
4473
4480
  }
4474
4481
 
4475
4482
  /**
@@ -4514,7 +4521,7 @@ var chunk;
4514
4521
  /** Memoized so the preload and the lazy mount share ONE chunk request. */
4515
4522
  function loadChunk() {
4516
4523
  var _chunk;
4517
- return (_chunk = chunk) !== null && _chunk !== void 0 ? _chunk : chunk = import('./SunLensflare-46fa6ee8.js');
4524
+ return (_chunk = chunk) !== null && _chunk !== void 0 ? _chunk : chunk = import('./SunLensflare-0676ae6e.js');
4518
4525
  }
4519
4526
 
4520
4527
  /**
@@ -7537,7 +7544,7 @@ var createSelectionSlice = function createSelectionSlice(set, get) {
7537
7544
  frontOnElementName: frontOnElementName
7538
7545
  });
7539
7546
  },
7540
- refocusFocused: function refocusFocused() {
7547
+ refocusFocused: function refocusFocused(follow) {
7541
7548
  var _get$cameraConfig$sel3;
7542
7549
  var elementName = get().focusedElementName;
7543
7550
  if (!elementName) return;
@@ -7551,7 +7558,8 @@ var createSelectionSlice = function createSelectionSlice(set, get) {
7551
7558
  type: type,
7552
7559
  elevation: elevation,
7553
7560
  frontOn: frontOn,
7554
- paddingScale: paddingScale
7561
+ paddingScale: paddingScale,
7562
+ follow: follow
7555
7563
  });
7556
7564
  if (!((_get$cameraConfig$sel3 = get().cameraConfig.selectionMovesCamera) !== null && _get$cameraConfig$sel3 !== void 0 ? _get$cameraConfig$sel3 : DEFAULT_CAMERA_CONFIG.selectionMovesCamera)) return;
7557
7565
  get().enqueueCameraAction({
@@ -7559,7 +7567,8 @@ var createSelectionSlice = function createSelectionSlice(set, get) {
7559
7567
  elementName: elementName,
7560
7568
  focusElevationDeg: elevation,
7561
7569
  frontOn: frontOn,
7562
- paddingScale: paddingScale
7570
+ paddingScale: paddingScale,
7571
+ follow: follow
7563
7572
  });
7564
7573
  },
7565
7574
  resolveElementName: function resolveElementName(elementId) {
@@ -7618,6 +7627,12 @@ var createVersionsSlice = function createVersionsSlice(set, get) {
7618
7627
  articleVersion: get().articleVersion + 1
7619
7628
  });
7620
7629
  },
7630
+ articleSettledVersion: 0,
7631
+ bumpArticleSettledVersion: function bumpArticleSettledVersion() {
7632
+ return set({
7633
+ articleSettledVersion: get().articleSettledVersion + 1
7634
+ });
7635
+ },
7621
7636
  decorVersion: 0,
7622
7637
  bumpDecorVersion: function bumpDecorVersion() {
7623
7638
  return set({
@@ -9309,16 +9324,20 @@ function useShadowDirty() {
9309
9324
  return s.markShadowsDirty;
9310
9325
  });
9311
9326
 
9312
- // Geometry landed or moved: article geos mounted / pose committed, environment GLB mounted.
9327
+ // Geometry landed or moved: article geos mounted / pose committed, environment GLB mounted, and the
9328
+ // article's placement settled (the deck anchor moves it after its geos mount).
9313
9329
  var articleVersion = useRTVStore$1(function (s) {
9314
9330
  return s.articleVersion;
9315
9331
  });
9332
+ var articleSettledVersion = useRTVStore$1(function (s) {
9333
+ return s.articleSettledVersion;
9334
+ });
9316
9335
  var decorVersion = useRTVStore$1(function (s) {
9317
9336
  return s.decorVersion;
9318
9337
  });
9319
9338
  useEffect(function () {
9320
9339
  markShadowsDirty('scene geometry');
9321
- }, [articleVersion, decorVersion, markShadowsDirty]);
9340
+ }, [articleVersion, articleSettledVersion, decorVersion, markShadowsDirty]);
9322
9341
  var sunDirection = useRTVStore$1(function (s) {
9323
9342
  var sun = s.resolvedEnvironment.lighting.sun;
9324
9343
  return sun === false ? null : sun.direction;
@@ -13887,6 +13906,27 @@ function frameScene(ctx, baseAngle) {
13887
13906
  padding: padding
13888
13907
  };
13889
13908
  }
13909
+
13910
+ /**
13911
+ * `reframeOnSceneChange: 'follow'`: the camera keeps its current view direction and its zoom
13912
+ * relative to the recipe's fit, around the recipe's (re-derived) look-at point. `basisDistance` is the
13913
+ * fit distance the recipe produced before the change — a camera at half of that stays at half of the
13914
+ * new one.
13915
+ */
13916
+ function followPose(recipe, current, basisDistance) {
13917
+ var offset = current.position.clone().sub(current.target);
13918
+ var currentDistance = offset.length();
13919
+ // Negated `>` so a NaN basis (a fit stored while the canvas had no size) falls back instead of poisoning the pose.
13920
+ if (!(currentDistance > 1e-6) || !(basisDistance > 1e-6)) return {
13921
+ position: recipe.position.clone(),
13922
+ target: recipe.target.clone()
13923
+ };
13924
+ var recipeDistance = recipe.position.distanceTo(recipe.target);
13925
+ return {
13926
+ position: recipe.target.clone().addScaledVector(offset.divideScalar(currentDistance), currentDistance * (recipeDistance / basisDistance)),
13927
+ target: recipe.target.clone()
13928
+ };
13929
+ }
13890
13930
  function frameToResult(frame, aspect, cfg) {
13891
13931
  var dist = frame.radius / fovHalfTan(cfg);
13892
13932
  // The portrait fudge only applies to the isotropic sphere radius; the box-projected
@@ -14754,7 +14794,8 @@ var TWO_D_UP_HINTS = {
14754
14794
  function useCameraActions(controlsRef, animate, opts) {
14755
14795
  var viewMode = opts.viewMode,
14756
14796
  frameCtx = opts.frameCtx,
14757
- poseBook = opts.poseBook;
14797
+ poseBook = opts.poseBook,
14798
+ animating = opts.animating;
14758
14799
  var cameraConfig = frameCtx.cameraConfig;
14759
14800
  var cameraActionQueue = useRTVStore$1(function (s) {
14760
14801
  return s.cameraActionQueue;
@@ -14767,11 +14808,18 @@ function useCameraActions(controlsRef, animate, opts) {
14767
14808
  // recomputes the live overview so it tracks a scene that may have grown while focused.
14768
14809
  var inFocusRef = useRef(false);
14769
14810
 
14811
+ // Destination of the last fly — the pose a retarget mid-flight must read instead of the in-between camera.
14812
+ var flightEndRef = useRef(null);
14813
+
14770
14814
  // Shared fly: every action animates to a pose and, on arrival, commits the target. Re-enabling
14771
14815
  // OrbitControls is the animation's own business — it holds a controls lock for the whole flight
14772
14816
  // (see {@link controlsLock}). `up2D` selects the top-down up-hint pair; omit for a 3D orbit pose.
14773
14817
  var flyTo = useCallback(function (endPos, endTarget, flyOpts) {
14774
14818
  var _flyOpts$duration;
14819
+ flightEndRef.current = {
14820
+ position: endPos.clone(),
14821
+ target: endTarget.clone()
14822
+ };
14775
14823
  animate({
14776
14824
  endPos: endPos,
14777
14825
  endTarget: endTarget,
@@ -14786,6 +14834,21 @@ function useCameraActions(controlsRef, animate, opts) {
14786
14834
  }
14787
14835
  }, flyOpts !== null && flyOpts !== void 0 && flyOpts.up2D ? TWO_D_UP_HINTS : undefined);
14788
14836
  }, [animate, controlsRef]);
14837
+
14838
+ // Fit distance of the last focus recipe — what a `follow` refocus scales the user's current zoom against.
14839
+ var focusFitDistanceRef = useRef(null);
14840
+
14841
+ /** The user's current view direction and relative zoom around `recipe`'s look-at point (see `followPose`). */
14842
+ var followCurrent = useCallback(function (recipe, basisDistance) {
14843
+ var c = controlsRef.current;
14844
+ if (!c || basisDistance == null) return recipe;
14845
+ // Mid-flight the camera sits between two fits; the zoom the basis belongs to is the flight's destination.
14846
+ var current = animating.current && flightEndRef.current ? flightEndRef.current : {
14847
+ position: c.object.position,
14848
+ target: c.target
14849
+ };
14850
+ return followPose(recipe, current, basisDistance);
14851
+ }, [controlsRef, animating]);
14789
14852
  var processAction = useCallback(function (action) {
14790
14853
  var is2D = viewMode === '2d';
14791
14854
  // In 2D the ONLY programmatic camera motion is the auto-fit (`reframe` / `reset`) — element
@@ -14807,9 +14870,12 @@ function useCameraActions(controlsRef, animate, opts) {
14807
14870
  {
14808
14871
  if (is2D) break;
14809
14872
  inFocusRef.current = true;
14810
- var _result = computeCamera3D(frameCtx, action.elementName, undefined, action.focusElevationDeg, action.frontOn, action.paddingScale);
14873
+ var recipe = computeCamera3D(frameCtx, action.elementName, undefined, action.focusElevationDeg, action.frontOn, action.paddingScale);
14874
+ var basis = focusFitDistanceRef.current;
14875
+ focusFitDistanceRef.current = recipe.position.distanceTo(recipe.target);
14876
+ var _result = action.follow ? followCurrent(recipe, basis) : recipe;
14811
14877
  flyTo(_result.position, _result.target);
14812
- LOG$b.debug('CameraController: focusElement', action.elementName, 'elev=', action.focusElevationDeg);
14878
+ LOG$b.debug('CameraController: focusElement', action.elementName, 'elev=', action.focusElevationDeg, action.follow ? '— follow' : '');
14813
14879
  break;
14814
14880
  }
14815
14881
  case 'unfocus':
@@ -14875,16 +14941,19 @@ function useCameraActions(controlsRef, animate, opts) {
14875
14941
  // saved overview so subsequent `reset` calls honour the new framing too. We
14876
14942
  // deliberately ignore explicit initialPosition/Target — those are a host
14877
14943
  // hard-override, not a framing computation.
14878
- var _result6 = is2D ? computeCamera2D(frameCtx) : computeCamera3D(frameCtx);
14879
- if (viewMode === '3d') poseBook.setOverview3D(_result6.position, _result6.target);
14944
+ var _recipe = is2D ? computeCamera2D(frameCtx) : computeCamera3D(frameCtx);
14945
+ // The saved overview is the last overview fit, so its distance is what `follow` keeps the zoom relative to.
14946
+ var overview3D = poseBook.overview3D;
14947
+ var _result6 = !is2D && action.follow ? followCurrent(_recipe, overview3D.position.distanceTo(overview3D.target)) : _recipe;
14948
+ if (viewMode === '3d') poseBook.setOverview3D(_recipe.position, _recipe.target);
14880
14949
  flyTo(_result6.position, _result6.target, {
14881
14950
  up2D: is2D
14882
14951
  });
14883
- LOG$b.debug('CameraController: reframe world', viewMode);
14952
+ LOG$b.debug("CameraController: reframe world".concat(action.follow ? ' — follow' : ''), viewMode);
14884
14953
  break;
14885
14954
  }
14886
14955
  }
14887
- }, [viewMode, frameCtx, flyTo, poseBook]);
14956
+ }, [viewMode, frameCtx, flyTo, followCurrent, poseBook]);
14888
14957
  useEffect(function () {
14889
14958
  if (cameraActionQueue.length === 0) return;
14890
14959
  var actions = drainCameraActions();
@@ -15176,6 +15245,7 @@ function useCameraConstraints(camera, controlsRef, opts) {
15176
15245
  var collisionTargets = useRef(null);
15177
15246
  var collisionTargetsFor = useRef({
15178
15247
  article: -1,
15248
+ settled: -1,
15179
15249
  decor: -1
15180
15250
  });
15181
15251
  var collisionDir = useRef(new Vector3());
@@ -15209,16 +15279,19 @@ function useCameraConstraints(camera, controlsRef, opts) {
15209
15279
  *
15210
15280
  * Element poses moving between two bumps (mid-drag) are picked up regardless: the raycast reads
15211
15281
  * live world matrices. Only `bounds` goes stale, and only as a slightly-off early-out until the
15212
- * drag-end bump.
15282
+ * next bump — `articleSettledVersion` included, which covers a placement pass (the deck anchor)
15283
+ * moving the article after its geos mounted.
15213
15284
  */
15214
15285
  var ensureCollisionTargets = useCallback(function () {
15215
15286
  var _useRTVStore$getState = useRTVStore$1.getState(),
15216
15287
  articleVersion = _useRTVStore$getState.articleVersion,
15288
+ articleSettledVersion = _useRTVStore$getState.articleSettledVersion,
15217
15289
  decorVersion = _useRTVStore$getState.decorVersion;
15218
15290
  var builtFor = collisionTargetsFor.current;
15219
15291
  var cached = collisionTargets.current;
15220
- if (cached && builtFor.article === articleVersion && builtFor.decor === decorVersion) return cached;
15292
+ if (cached && builtFor.article === articleVersion && builtFor.settled === articleSettledVersion && builtFor.decor === decorVersion) return cached;
15221
15293
  builtFor.article = articleVersion;
15294
+ builtFor.settled = articleSettledVersion;
15222
15295
  builtFor.decor = decorVersion;
15223
15296
  flushPendingBVH();
15224
15297
  var targets = collectCollisionTargets(threeScene);
@@ -15766,6 +15839,16 @@ function CameraController() {
15766
15839
  }
15767
15840
  return 2;
15768
15841
  }, [scene3d]);
15842
+
15843
+ // Placement-dependent camera work keys on the SETTLED article, not on geometry mounting: a
15844
+ // placement pass (the deck-cutout anchor) moves the elements over the frames after the mount.
15845
+ var articleSettledVersion = useRTVStore$1(function (s) {
15846
+ return s.articleSettledVersion;
15847
+ });
15848
+
15849
+ // Orbit-target bounds: the render script's ground-shadow box, widened by where the article actually
15850
+ // settled — the deck anchor can push it well off that footprint, and a look-at point that follows it
15851
+ // must not be clamped back towards the old spot.
15769
15852
  var sceneBBox = useMemo(function () {
15770
15853
  var _scene3d$groundShadow3;
15771
15854
  if (!(scene3d !== null && scene3d !== void 0 && (_scene3d$groundShadow3 = scene3d.groundShadow) !== null && _scene3d$groundShadow3 !== void 0 && _scene3d$groundShadow3.enabled)) return null;
@@ -15777,12 +15860,16 @@ function CameraController() {
15777
15860
  sx = _scene3d$groundShadow5[0],
15778
15861
  sy = _scene3d$groundShadow5[1],
15779
15862
  sz = _scene3d$groundShadow5[2];
15780
- var margin = limits.targetBoundsMargin;
15863
+ var box = new Box3(new Vector3(cx - sx / 2, cy - sy / 2, cz - sz / 2), new Vector3(cx + sx / 2, cy + sy / 2, cz + sz / 2));
15864
+ var content = sceneContentBox(threeScene);
15865
+ if (content) box.union(content);
15866
+ box.expandByScalar(limits.targetBoundsMargin);
15781
15867
  return {
15782
- min: new Vector3(cx - sx / 2 - margin, cy - sy / 2 - margin, cz - sz / 2 - margin),
15783
- max: new Vector3(cx + sx / 2 + margin, cy + sy / 2 + margin, cz + sz / 2 + margin)
15868
+ min: box.min,
15869
+ max: box.max
15784
15870
  };
15785
- }, [scene3d, limits.targetBoundsMargin]);
15871
+ // `articleSettledVersion` is the trigger: the content box is read from the live scene.
15872
+ }, [scene3d, limits.targetBoundsMargin, threeScene, articleSettledVersion]);
15786
15873
 
15787
15874
  // Frame context, shared by all camera hooks.
15788
15875
  var frameCtx = useMemo(function () {
@@ -15808,7 +15895,7 @@ function CameraController() {
15808
15895
  }, [elementCount, scene2dElementCount]);
15809
15896
 
15810
15897
  // Auto-refit the 2D view when the 2D planning changes — a freetext resize (bounds grow/shrink) or an
15811
- // element add/remove. The `articleVersion` content-box reframe below doesn't cover 2D (the 3D geos
15898
+ // element add/remove. The settled-article content-box reframe below doesn't cover 2D (the 3D geos
15812
15899
  // unmount in 2D, so `sceneContentBox` is null), so key off the 2D bounding box directly. The 2D zoom
15813
15900
  // is system-owned (manual zoom is disabled via `limits2d`), so the refit is unconditional: the camera
15814
15901
  // always tracks the planning size. The first observation only baselines (entering 2D is already
@@ -15876,17 +15963,14 @@ function CameraController() {
15876
15963
  }, [isAccessoryMoving]);
15877
15964
 
15878
15965
  // Camera reaction to element add/delete (mains AND accessories — both are `Element#` nodes).
15879
- // Keyed on `articleVersion` (bumped after geometry mounts / a pose commits) so the scene is settled
15880
- // before we frame/measure, and diffs the element name SET.
15966
+ // Keyed on `articleSettledVersion` — geometry mounted AND every placement pass done — so the camera
15967
+ // measures the article where it finally rests, and diffs the element name SET.
15881
15968
  // - FOCUSED → stay focused; follow only when the focused element itself was re-keyed (a move).
15882
15969
  // Following the selection to a newly placed element is driven by the host
15883
15970
  // `selectedElementId` prop (setSelectedElementFromProp), not here.
15884
15971
  // - OVERVIEW (not focused) → re-fit the view to the new element bounding box, but only when that
15885
15972
  // box actually changed (`elementBoxChanged`).
15886
15973
  // Skips the first scene (initial framing already fit it).
15887
- var articleVersion = useRTVStore$1(function (s) {
15888
- return s.articleVersion;
15889
- });
15890
15974
  var prevElementNamesRef = useRef(null);
15891
15975
  var prevElementBoxRef = useRef(null);
15892
15976
  useEffect(function () {
@@ -15954,7 +16038,9 @@ function CameraController() {
15954
16038
  // keeping the camera where the user left it across scene size changes. Selection-driven focus
15955
16039
  // (follow-on-replace, host `selectedElementId`) still moves the camera.
15956
16040
  var reframeOnSceneChange = (_s$cameraConfig$refra = s.cameraConfig.reframeOnSceneChange) !== null && _s$cameraConfig$refra !== void 0 ? _s$cameraConfig$refra : DEFAULT_CAMERA_CONFIG.reframeOnSceneChange;
16041
+ var follow = reframeOnSceneChange === 'follow';
15957
16042
  var selectionMovesCamera = (_s$cameraConfig$selec = s.cameraConfig.selectionMovesCamera) !== null && _s$cameraConfig$selec !== void 0 ? _s$cameraConfig$selec : DEFAULT_CAMERA_CONFIG.selectionMovesCamera;
16043
+ var refitOnChange = boxChanged && settled && !!reframeOnSceneChange;
15958
16044
  if (s.focusedElementName != null) {
15959
16045
  var focusedSurvived = cur.has(s.focusedElementName);
15960
16046
 
@@ -15976,10 +16062,12 @@ function CameraController() {
15976
16062
  s.clearFocus();
15977
16063
  // `clearFocus` already no-ops its own fly when selection must not move the camera; this
15978
16064
  // reframe is a separate grab, so it needs the same gate.
15979
- if (selectionMovesCamera) s.enqueueCameraAction({
15980
- type: 'reframe'
15981
- });
15982
- return;
16065
+ if (selectionMovesCamera) {
16066
+ s.enqueueCameraAction({
16067
+ type: 'reframe'
16068
+ });
16069
+ return;
16070
+ }
15983
16071
  }
15984
16072
 
15985
16073
  // Focused element's own node vanished. Follow to a selectable main among the names added THIS
@@ -15996,12 +16084,19 @@ function CameraController() {
15996
16084
  return st === 'selectable' || st === 'selected';
15997
16085
  });
15998
16086
  if (followName) s.focusOnElement(followName);
15999
- } else if (setUnchanged && boxChanged && settled && reframeOnSceneChange) {
16087
+ }
16088
+ if (!selectionMovesCamera) {
16089
+ // Focus is state only here — the camera never left the overview, so keep fitting that.
16090
+ if (refitOnChange) s.enqueueCameraAction({
16091
+ type: 'reframe',
16092
+ follow: follow
16093
+ });
16094
+ } else if (focusedSurvived && setUnchanged && refitOnChange) {
16000
16095
  // Focused element survived and NOTHING was added/replaced/removed, but its geometry changed
16001
16096
  // (e.g. a size edit shipped as a fresh render script). Re-fit the focus so the camera re-orients
16002
16097
  // to the resized element. Mirrors the overview reframe below; `refocusFocused` recomputes the
16003
16098
  // 2D/3D focus framing for the current view mode.
16004
- s.refocusFocused();
16099
+ s.refocusFocused(follow);
16005
16100
  }
16006
16101
  return;
16007
16102
  }
@@ -16027,13 +16122,14 @@ function CameraController() {
16027
16122
  // Re-fit the overview to the new element bounding box — only when it changed (covers a pure size
16028
16123
  // edit with no add/remove), and never while a drag/rotate is still in progress (the move settles
16029
16124
  // into a new assembly first).
16030
- if (boxChanged && settled && reframeOnSceneChange) {
16125
+ if (refitOnChange) {
16031
16126
  LOG$a.debug('CameraController: element bbox changed in overview → reframe to fit');
16032
16127
  s.enqueueCameraAction({
16033
- type: 'reframe'
16128
+ type: 'reframe',
16129
+ follow: follow
16034
16130
  });
16035
16131
  }
16036
- }, [articleVersion]);
16132
+ }, [articleSettledVersion]);
16037
16133
 
16038
16134
  // Camera creation: proxy + real split.
16039
16135
  //
@@ -16123,7 +16219,8 @@ function CameraController() {
16123
16219
  useCameraActions(controlsRef, animate, {
16124
16220
  viewMode: viewMode,
16125
16221
  frameCtx: frameCtx,
16126
- poseBook: poseBook
16222
+ poseBook: poseBook,
16223
+ animating: animating
16127
16224
  });
16128
16225
  var _useCameraConstraints = useCameraConstraints(proxyCamera, controlsRef, {
16129
16226
  controlsMode: controlsMode,
@@ -16209,6 +16306,74 @@ function CameraController() {
16209
16306
  });
16210
16307
  }
16211
16308
 
16309
+ /** Consecutive frames the article's bounds must hold still before its placement counts as settled. */
16310
+ var STABLE_FRAMES = 3;
16311
+ /** Bounds movement (m) below which two measures are the same placement — the deck anchor's own epsilon. */
16312
+ var EPSILON_SQ = 1e-3 * 1e-3;
16313
+ function sameBounds(a, b) {
16314
+ if (a == null || b == null) return a === b;
16315
+ return a.min.distanceToSquared(b.min) < EPSILON_SQ && a.max.distanceToSquared(b.max) < EPSILON_SQ;
16316
+ }
16317
+
16318
+ /**
16319
+ * Publishes `articleSettledVersion`: the article's world bounds stopped moving after a change.
16320
+ *
16321
+ * Armed by everything that can move the article — geometry mounting or a pose commit
16322
+ * (`articleVersion`), a floor arriving (`decorVersion`, which re-runs the deck anchor) and a placement
16323
+ * pass writing its result (`elementAnchorOffsets`). While armed it measures the content box once per
16324
+ * frame and bumps once the box held still for {@link STABLE_FRAMES}, so a consumer sees the article
16325
+ * where it finally rests, whichever pass put it there. Several changes inside one settle window
16326
+ * collapse into one bump.
16327
+ */
16328
+ function ArticleSettleTracker() {
16329
+ var scene = useThree(function (s) {
16330
+ return s.scene;
16331
+ });
16332
+ var invalidate = useThree(function (s) {
16333
+ return s.invalidate;
16334
+ });
16335
+ var armedRef = useRef(false);
16336
+ var stableRef = useRef(0);
16337
+ var lastBoxRef = useRef(null);
16338
+ useEffect(function () {
16339
+ var arm = function arm() {
16340
+ armedRef.current = true;
16341
+ stableRef.current = 0;
16342
+ invalidate();
16343
+ };
16344
+ var unsubscribers = [useRTVStore$1.subscribe(function (s) {
16345
+ return s.articleVersion;
16346
+ }, arm), useRTVStore$1.subscribe(function (s) {
16347
+ return s.decorVersion;
16348
+ }, arm), useRTVStore$1.subscribe(function (s) {
16349
+ return s.elementAnchorOffsets;
16350
+ }, arm)];
16351
+ return function () {
16352
+ return unsubscribers.forEach(function (unsubscribe) {
16353
+ return unsubscribe();
16354
+ });
16355
+ };
16356
+ }, [invalidate]);
16357
+ useFrame(function () {
16358
+ if (!armedRef.current) return;
16359
+ var box = sceneContentBox(scene);
16360
+ if (sameBounds(box, lastBoxRef.current)) {
16361
+ stableRef.current += 1;
16362
+ } else {
16363
+ stableRef.current = 0;
16364
+ lastBoxRef.current = box ? box.clone() : null;
16365
+ }
16366
+ // An on-demand frameloop would otherwise stop right here and never count the settle out.
16367
+ if (stableRef.current < STABLE_FRAMES) {
16368
+ invalidate();
16369
+ return;
16370
+ }
16371
+ armedRef.current = false;
16372
+ useRTVStore$1.getState().bumpArticleSettledVersion();
16373
+ });
16374
+ return null;
16375
+ }
16376
+
16212
16377
  var wrap = "wrap-FtDo5";
16213
16378
  var dp = "dp-B372X";
16214
16379
  var dpAttach = "dp-attach-J1C1i";
@@ -18291,9 +18456,10 @@ function DimensionLines3D() {
18291
18456
  var hideUnit = useRTVStore$1(function (s) {
18292
18457
  return s.resolvedEnvironment.dimensionLineHideUnit;
18293
18458
  });
18294
- // Lines are measured from the mounted element meshes; re-measure when those land or move.
18295
- var articleVersion = useRTVStore$1(function (s) {
18296
- return s.articleVersion;
18459
+ // Lines are measured from the element meshes' world bounds, so they wait for the SETTLED placement:
18460
+ // the deck anchor moves an article onto its resting spot after its geometry mounts.
18461
+ var articleSettledVersion = useRTVStore$1(function (s) {
18462
+ return s.articleSettledVersion;
18297
18463
  });
18298
18464
  var scene = useThree(function (s) {
18299
18465
  return s.scene;
@@ -18384,7 +18550,7 @@ function DimensionLines3D() {
18384
18550
  }
18385
18551
  }
18386
18552
  return [].concat(_toConsumableArray(sizeLines), _toConsumableArray(gapLines));
18387
- }, [viewMode, selectedName, scopeNames, articleVersion, scene2d, articleNodeById, childrenOfName, parentOfName, isAccessoryMoving, accessoryGrids, scene, camera, sidesSig, getSelectionScopeNames]);
18553
+ }, [viewMode, selectedName, scopeNames, articleSettledVersion, scene2d, articleNodeById, childrenOfName, parentOfName, isAccessoryMoving, accessoryGrids, scene, camera, sidesSig, getSelectionScopeNames]);
18388
18554
 
18389
18555
  // `lines` is the only thing that mounts/unmounts children of the group.
18390
18556
  useLayoutEffect(function () {
@@ -22863,7 +23029,7 @@ function SceneRenderer() {
22863
23029
  onCreated: handleCreated,
22864
23030
  shadows: true,
22865
23031
  children: /*#__PURE__*/jsxs(ViewModeRuntimeProvider, {
22866
- children: [/*#__PURE__*/jsx(FirstFrameMark, {}), /*#__PURE__*/jsx(FrameloopVisibilityController, {}), /*#__PURE__*/jsx(PerfLogController, {}), /*#__PURE__*/jsx(CameraController, {}), /*#__PURE__*/jsx(SceneContent, {
23032
+ children: [/*#__PURE__*/jsx(FirstFrameMark, {}), /*#__PURE__*/jsx(FrameloopVisibilityController, {}), /*#__PURE__*/jsx(PerfLogController, {}), /*#__PURE__*/jsx(ArticleSettleTracker, {}), /*#__PURE__*/jsx(CameraController, {}), /*#__PURE__*/jsx(SceneContent, {
22867
23033
  matConfig: matConfig
22868
23034
  })]
22869
23035
  })
@@ -25314,11 +25480,11 @@ var preset = {
25314
25480
  halfExtentX: 2.5705,
25315
25481
  halfExtentZ: 7.071
25316
25482
  },
25317
- // -6cm margin: the deck laps 6cm over the pool's rim, hiding the seam between the
25483
+ // -13cm margin: the deck laps 13cm over the pool's rim, hiding the seam between the
25318
25484
  // collar edge and the moulded lip.
25319
25485
  articleSync: {
25320
25486
  enabled: true,
25321
- margin: -0.06
25487
+ margin: -0.13
25322
25488
  },
25323
25489
  // The pool is centered in the authored hole (HQS grows articles from their center, so
25324
25490
  // every size needs re-placing). Offsets fine-tune its resting spot within the hole.
@@ -25353,9 +25519,12 @@ var preset = {
25353
25519
  // footprintSliceDepth below the deck top, projected onto the floor). The traced rim bbox
25354
25520
  // replaces the raw article bbox for placement and water, so no calibration is needed.
25355
25521
  // Without a matching rule there is no outline and no collar — the area stays open.
25522
+ // Only the `GEO_Pool…` geos shape the cutout: the article ships more than the basin, and the
25523
+ // hole, the resting spot and the water should follow the basin alone.
25356
25524
  articleRules: [{
25357
25525
  match: 'HUELSE_POOL',
25358
- footprintFromGeometry: true
25526
+ footprintFromGeometry: true,
25527
+ geoPrefix: 'GEO_Pool'
25359
25528
  }]
25360
25529
  // The collar continues FLOOR_Wood_1's wood by fitting its mapping. To make it a DIFFERENT
25361
25530
  // material instead (another wood, stone, tile), give it its own maps — the tiling is then
@@ -25427,9 +25596,10 @@ var preset = {
25427
25596
  // The pool is flat and sunk into the deck, so the bbox-fraction focus point lands at water
25428
25597
  // level; lift the orbit pivot a meter above it.
25429
25598
  focusTargetYOffset: 1,
25430
- // Pool resizes reshape the deck cutout every config edit — keep the camera where the user
25431
- // left it instead of re-fitting to the new bounds.
25432
- reframeOnSceneChange: false,
25599
+ // Pool resizes reshape the deck cutout every config edit, and the anchor grows the pool away from
25600
+ // one border — so the look-at point and fit distance follow the resized pool, but the user's (or
25601
+ // the sweep's) view angle and zoom are kept instead of re-fitting to the initial angle.
25602
+ reframeOnSceneChange: 'follow',
25433
25603
  // Selection never moves the camera in this scene. The framing here is authored (limits, sectors,
25434
25604
  // autoRotate), and the default behaviour — fly to the element on select, out to the overview on
25435
25605
  // deselect, recenter on a click into empty space — discards it on the first click. Elements still
@@ -1,4 +1,4 @@
1
- export { E as ENVIRONMENT_CONFIG, W as WHITE_ROOM_PRESET, j as buildScene2D, R as default, m as emitConfig, k as getDimensionConfigs, i as internals, a as useRTVStore } from './index-428fd8ca.js';
1
+ export { E as ENVIRONMENT_CONFIG, W as WHITE_ROOM_PRESET, j as buildScene2D, R as default, m as emitConfig, k as getDimensionConfigs, i as internals, a as useRTVStore } from './index-6f58b1ed.js';
2
2
  import 'react';
3
3
  import '@react-three/fiber';
4
4
  import 'three';
@@ -95,6 +95,7 @@ export declare const ENVIRONMENT_CONFIG: import("./descriptor").GroupDescriptor<
95
95
  match: import("./descriptor").ValueField<string>;
96
96
  footprintFromGeometry: import("./descriptor").BooleanField;
97
97
  footprintSliceDepth: import("./descriptor").NumberField;
98
+ geoPrefix: import("./descriptor").ValueField<string>;
98
99
  }>>;
99
100
  collar: import("./descriptor").GroupDescriptor<{
100
101
  recess: import("./descriptor").NumberField;
@@ -1 +1 @@
1
- {"version":3,"file":"environment.config.d.ts","sourceRoot":"","sources":["../../../../../src/config/environment.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAc5F;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;IAW7B;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACvE,MAAM,MAAM,yBAAyB,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,yBAA8D,CAAC"}
1
+ {"version":3,"file":"environment.config.d.ts","sourceRoot":"","sources":["../../../../../src/config/environment.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAc5F;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;IAW7B;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;IAEH;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACvE,MAAM,MAAM,yBAAyB,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,yBAA8D,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Publishes `articleSettledVersion`: the article's world bounds stopped moving after a change.
3
+ *
4
+ * Armed by everything that can move the article — geometry mounting or a pose commit
5
+ * (`articleVersion`), a floor arriving (`decorVersion`, which re-runs the deck anchor) and a placement
6
+ * pass writing its result (`elementAnchorOffsets`). While armed it measures the content box once per
7
+ * frame and bumps once the box held still for {@link STABLE_FRAMES}, so a consumer sees the article
8
+ * where it finally rests, whichever pass put it there. Several changes inside one settle window
9
+ * collapse into one bump.
10
+ */
11
+ export declare function ArticleSettleTracker(): null;
12
+ //# sourceMappingURL=ArticleSettleTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArticleSettleTracker.d.ts","sourceRoot":"","sources":["../../../../../src/core/ArticleSettleTracker.tsx"],"names":[],"mappings":"AAgBA;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,SAwCnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SceneRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/core/SceneRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA4ClG,wBAAgB,aAAa,sBAmQ5B"}
1
+ {"version":3,"file":"SceneRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/core/SceneRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA6ClG,wBAAgB,aAAa,sBAoQ5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/CameraController.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAgDvE,wBAAgB,gBAAgB,sBA8a/B"}
1
+ {"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/CameraController.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAgDvE,wBAAgB,gBAAgB,sBA8b/B"}
@@ -1,4 +1,4 @@
1
- import type { RefObject } from 'react';
1
+ import type { MutableRefObject, RefObject } from 'react';
2
2
  import type { OrbitControls as OrbitControlsImpl } from 'three-stdlib';
3
3
  import type { CameraFrameContext } from '../../utils/cameraFraming';
4
4
  import type { CameraPoseBook } from './cameraPoseBook';
@@ -7,6 +7,7 @@ interface UseCameraActionsOptions {
7
7
  viewMode: '3d' | '2d';
8
8
  frameCtx: CameraFrameContext;
9
9
  poseBook: CameraPoseBook;
10
+ animating: MutableRefObject<boolean>;
10
11
  }
11
12
  export declare function useCameraActions(controlsRef: RefObject<OrbitControlsImpl | null>, animate: AnimateFn, opts: UseCameraActionsOptions): void;
12
13
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useCameraActions.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/useCameraActions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAUtD,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,uBAAuB,QA4InI"}
1
+ {"version":3,"file":"useCameraActions.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/useCameraActions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvE,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,2BAA2B,CAAC;AAEjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAUtD,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACtC;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,uBAAuB,QAqKnI"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCameraConstraints.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/useCameraConstraints.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAmC,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAmDxF,UAAU,2BAA2B;IACnC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,uFAAuF;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC9B,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACvC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,2BAA2B;;EAySlJ"}
1
+ {"version":3,"file":"useCameraConstraints.d.ts","sourceRoot":"","sources":["../../../../../../src/core/camera/useCameraConstraints.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAmC,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAmDxF,UAAU,2BAA2B;IACnC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,uFAAuF;IACvF,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC9B,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACvC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,2BAA2B;;EA2SlJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"DimensionLines3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/dimension-lines/DimensionLines3D.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AA8E1E,wBAAgB,gBAAgB,sBA2J/B"}
1
+ {"version":3,"file":"DimensionLines3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/dimension-lines/DimensionLines3D.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AA8E1E,wBAAgB,gBAAgB,sBA4J/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeckCutoutArticleSync.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/environment/deckCutout/DeckCutoutArticleSync.tsx"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,SA6KpC"}
1
+ {"version":3,"file":"DeckCutoutArticleSync.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/environment/deckCutout/DeckCutoutArticleSync.tsx"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,SA2LpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"articleFootprint.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/environment/deckCutout/articleFootprint.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAsBtH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,yHAAyH;IACzH,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAWD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,GAAG,IAAI,CAYhG;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,6BAA6B,EAAE,EAC/C,aAAa,EAAE,SAAS,gBAAgB,EAAE,GACzC;IAAE,IAAI,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAYlF;AAkHD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,kBAAkB,EAC/B,IAAI,EAAE,6BAA6B,GAAG,IAAI,EAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAA;CAAE;AACjD,oGAAoG;AACpG,YAAY,SAAI,GACf,gBAAgB,CA8ElB"}
1
+ {"version":3,"file":"articleFootprint.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/environment/deckCutout/articleFootprint.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAsBtH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mGAAmG;IACnG,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,yHAAyH;IACzH,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAWD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,GAAG,IAAI,CAYhG;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,6BAA6B,EAAE,EAC/C,aAAa,EAAE,SAAS,gBAAgB,EAAE,GACzC;IAAE,IAAI,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAYlF;AAmHD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,kBAAkB,EAC/B,IAAI,EAAE,6BAA6B,GAAG,IAAI,EAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAA;CAAE;AACjD,oGAAoG;AACpG,YAAY,SAAI,GACf,gBAAgB,CA8ElB"}