@ericchen1990/pano-view 3.0.0 → 3.1.0

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/dist/index.cjs CHANGED
@@ -2306,7 +2306,7 @@ module.exports = __toCommonJS(index_exports);
2306
2306
  // src/pano-viewer.tsx
2307
2307
  var import_fiber10 = require("@react-three/fiber");
2308
2308
  var import_xr3 = require("@react-three/xr");
2309
- var import_react25 = require("react");
2309
+ var import_react26 = require("react");
2310
2310
 
2311
2311
  // src/background-audio-host.ts
2312
2312
  var import_react = require("react");
@@ -2501,6 +2501,7 @@ var DEFAULT_ROTATE_DAMPING = 14;
2501
2501
  var DEFAULT_ZOOM_DAMPING = 16;
2502
2502
  var DEFAULT_FRICTION_STOP = 0.01;
2503
2503
  var VIEW_SETTLE_EPSILON = 1e-3;
2504
+ var DEFAULT_NAVIGATION_DURATION = 700;
2504
2505
  var PanoramaViewContext = (0, import_react3.createContext)(null);
2505
2506
  function clamp(value, min, max) {
2506
2507
  return Math.max(min, Math.min(max, value));
@@ -2520,6 +2521,15 @@ function resolveDamping(value, fallback) {
2520
2521
  function resolveFrictionStop(value) {
2521
2522
  return Number.isFinite(value) && value >= 0 ? value : DEFAULT_FRICTION_STOP;
2522
2523
  }
2524
+ function resolveNavigationDuration(value) {
2525
+ return Number.isFinite(value) && value >= 0 ? value : DEFAULT_NAVIGATION_DURATION;
2526
+ }
2527
+ function applyNavigationEasing(progress, easing) {
2528
+ if (easing === "linear") {
2529
+ return progress;
2530
+ }
2531
+ return progress < 0.5 ? 4 * progress * progress * progress : 1 - Math.pow(-2 * progress + 2, 3) / 2;
2532
+ }
2523
2533
  function viewsEqual(a, b) {
2524
2534
  return a.yaw === b.yaw && a.pitch === b.pitch && a.fov === b.fov;
2525
2535
  }
@@ -2553,13 +2563,14 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2553
2563
  const xrEulerRef = (0, import_react3.useRef)(new import_three.Euler(0, 0, 0, "YXZ"));
2554
2564
  const minFovRef = (0, import_react3.useRef)(minFov);
2555
2565
  const maxFovRef = (0, import_react3.useRef)(maxFov);
2566
+ const activeNavigationRef = (0, import_react3.useRef)(null);
2556
2567
  optionsRef.current = options;
2557
2568
  eventBusRef.current = eventBus;
2558
2569
  xrSessionRef.current = xrSession;
2559
2570
  minFovRef.current = minFov;
2560
2571
  maxFovRef.current = maxFov;
2561
2572
  const hasInertia = () => yawVelocityRef.current !== 0 || pitchVelocityRef.current !== 0 || zoomVelocityRef.current !== 0;
2562
- const isUserInteracting = () => mouseActiveRef.current || touchActiveRef.current || keyboardActiveRef.current || gyroActiveRef.current || interactionLockCountRef.current > 0 || xrSessionRef.current != null || hasInertia();
2573
+ const isUserInteracting = () => mouseActiveRef.current || touchActiveRef.current || keyboardActiveRef.current || gyroActiveRef.current || interactionLockCountRef.current > 0 || xrSessionRef.current != null || activeNavigationRef.current != null || hasInertia();
2563
2574
  const syncInteracting = () => {
2564
2575
  interactingRef.current = mouseActiveRef.current || touchActiveRef.current;
2565
2576
  };
@@ -2601,6 +2612,14 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2601
2612
  zoomVelocityRef.current = 0;
2602
2613
  lastVelocitySampleAtRef.current = null;
2603
2614
  };
2615
+ const cancelNavigation = () => {
2616
+ const navigation = activeNavigationRef.current;
2617
+ if (!navigation) {
2618
+ return;
2619
+ }
2620
+ activeNavigationRef.current = null;
2621
+ navigation.resolve({ status: "cancelled" });
2622
+ };
2604
2623
  const markDirty = () => {
2605
2624
  dirtyRef.current = true;
2606
2625
  settledRef.current = false;
@@ -2613,6 +2632,7 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2613
2632
  }
2614
2633
  };
2615
2634
  const acquireInteractionLock = () => {
2635
+ cancelNavigation();
2616
2636
  interactionLockCountRef.current += 1;
2617
2637
  stopVelocity();
2618
2638
  if (mouseActiveRef.current) {
@@ -2637,6 +2657,7 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2637
2657
  };
2638
2658
  };
2639
2659
  const setView = (view, setOptions) => {
2660
+ cancelNavigation();
2640
2661
  const nextView = hardConstrainView(view);
2641
2662
  if (gyroActiveRef.current) {
2642
2663
  gyroOffsetRef.current = {
@@ -2651,7 +2672,66 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2651
2672
  }
2652
2673
  markDirty();
2653
2674
  };
2675
+ const startNavigation = (targetInput, options2) => {
2676
+ cancelNavigation();
2677
+ if (xrSessionRef.current != null || gyroActiveRef.current || interactionLockCountRef.current > 0) {
2678
+ return Promise.resolve({ status: "cancelled" });
2679
+ }
2680
+ const from = { ...viewRef.current };
2681
+ const safeTargetInput = {
2682
+ yaw: targetInput.yaw !== void 0 && Number.isFinite(targetInput.yaw) ? targetInput.yaw : from.yaw,
2683
+ pitch: targetInput.pitch !== void 0 && Number.isFinite(targetInput.pitch) ? targetInput.pitch : from.pitch,
2684
+ fov: targetInput.fov !== void 0 && Number.isFinite(targetInput.fov) ? targetInput.fov : from.fov
2685
+ };
2686
+ const target = hardConstrainView(safeTargetInput, from);
2687
+ const duration = resolveNavigationDuration(options2?.duration);
2688
+ const rawYawDelta = targetInput.yaw !== void 0 && Number.isFinite(targetInput.yaw) ? safeTargetInput.yaw - from.yaw : 0;
2689
+ const yawDelta = options2?.shortestPath === false ? rawYawDelta : shortestYawDelta(from.yaw, target.yaw);
2690
+ stopVelocity();
2691
+ targetViewRef.current = target;
2692
+ markDirty();
2693
+ if (duration === 0) {
2694
+ viewRef.current = target;
2695
+ return Promise.resolve({ status: "completed" });
2696
+ }
2697
+ return new Promise((resolve) => {
2698
+ activeNavigationRef.current = {
2699
+ from,
2700
+ target,
2701
+ yawDelta,
2702
+ startedAt: performance.now(),
2703
+ duration,
2704
+ easing: options2?.easing,
2705
+ resolve
2706
+ };
2707
+ });
2708
+ };
2709
+ const lookTo = (position, options2) => startNavigation(
2710
+ {
2711
+ yaw: position.yaw,
2712
+ pitch: position.pitch,
2713
+ fov: options2?.fov ?? viewRef.current.fov
2714
+ },
2715
+ options2
2716
+ );
2717
+ const moveTo = (position, options2) => startNavigation(
2718
+ {
2719
+ yaw: position.yaw,
2720
+ pitch: position.pitch,
2721
+ fov: viewRef.current.fov
2722
+ },
2723
+ options2
2724
+ );
2725
+ const zoomTo = (fov, options2) => startNavigation(
2726
+ {
2727
+ yaw: viewRef.current.yaw,
2728
+ pitch: viewRef.current.pitch,
2729
+ fov
2730
+ },
2731
+ options2
2732
+ );
2654
2733
  const applyViewDelta = (delta, applyOptions) => {
2734
+ cancelNavigation();
2655
2735
  if (interactionLockCountRef.current > 0 || xrSessionRef.current != null) {
2656
2736
  return false;
2657
2737
  }
@@ -2702,10 +2782,16 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2702
2782
  getTargetView: () => ({ ...targetViewRef.current }),
2703
2783
  setView,
2704
2784
  reset: () => setView(initialViewRef.current),
2785
+ lookTo,
2786
+ moveTo,
2787
+ zoomTo,
2705
2788
  applyViewDelta,
2706
2789
  setKeyboardActive: (active) => {
2707
2790
  const wasActive = keyboardActiveRef.current;
2708
2791
  keyboardActiveRef.current = active;
2792
+ if (active) {
2793
+ cancelNavigation();
2794
+ }
2709
2795
  if (active && !wasActive) {
2710
2796
  eventBusRef.current.emit("viewinteractionstart", {
2711
2797
  source: "keyboard"
@@ -2723,6 +2809,9 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2723
2809
  } else {
2724
2810
  touchActiveRef.current = active;
2725
2811
  }
2812
+ if (active) {
2813
+ cancelNavigation();
2814
+ }
2726
2815
  syncInteracting();
2727
2816
  if (active && !wasActive) {
2728
2817
  eventBusRef.current.emit("viewinteractionstart", { source });
@@ -2739,6 +2828,9 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2739
2828
  isInteractionLocked: () => interactionLockCountRef.current > 0,
2740
2829
  isUserInteracting,
2741
2830
  setGyroActive: (active) => {
2831
+ if (active) {
2832
+ cancelNavigation();
2833
+ }
2742
2834
  gyroActiveRef.current = active;
2743
2835
  gyroOffsetRef.current = { yaw: 0, pitch: 0 };
2744
2836
  stopVelocity();
@@ -2775,7 +2867,7 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2775
2867
  acquireInteractionLock,
2776
2868
  applyAutoRotation: (yawDelta) => {
2777
2869
  const inertiaFinished = yawVelocityRef.current === 0 && pitchVelocityRef.current === 0 && zoomVelocityRef.current === 0;
2778
- if (!Number.isFinite(yawDelta) || xrSessionRef.current != null || gyroActiveRef.current || interactionLockCountRef.current > 0 || interactingRef.current || keyboardActiveRef.current || !inertiaFinished) {
2870
+ if (!Number.isFinite(yawDelta) || xrSessionRef.current != null || activeNavigationRef.current != null || gyroActiveRef.current || interactionLockCountRef.current > 0 || interactingRef.current || keyboardActiveRef.current || !inertiaFinished) {
2779
2871
  return false;
2780
2872
  }
2781
2873
  targetViewRef.current.yaw += yawDelta;
@@ -2785,6 +2877,12 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2785
2877
  }),
2786
2878
  []
2787
2879
  );
2880
+ (0, import_react3.useEffect)(
2881
+ () => () => {
2882
+ cancelNavigation();
2883
+ },
2884
+ []
2885
+ );
2788
2886
  (0, import_react3.useEffect)(() => {
2789
2887
  initialViewRef.current = { ...initialView };
2790
2888
  setView(initialView);
@@ -2794,6 +2892,7 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2794
2892
  return;
2795
2893
  }
2796
2894
  if (xrSessionRef.current && gl.xr.isPresenting) {
2895
+ cancelNavigation();
2797
2896
  const xrCamera = gl.xr.getCamera();
2798
2897
  xrEulerRef.current.setFromQuaternion(xrCamera.quaternion, "YXZ");
2799
2898
  const nextView2 = {
@@ -2814,6 +2913,48 @@ var PanoramaViewRuntime = (0, import_react3.forwardRef)(function PanoramaViewRun
2814
2913
  }
2815
2914
  return;
2816
2915
  }
2916
+ const navigation = activeNavigationRef.current;
2917
+ if (navigation) {
2918
+ const progress = Math.min(
2919
+ 1,
2920
+ Math.max(0, (performance.now() - navigation.startedAt) / navigation.duration)
2921
+ );
2922
+ const easedProgress = applyNavigationEasing(progress, navigation.easing);
2923
+ const nextView2 = {
2924
+ yaw: normalizeYaw(navigation.from.yaw + navigation.yawDelta * easedProgress),
2925
+ pitch: navigation.from.pitch + (navigation.target.pitch - navigation.from.pitch) * easedProgress,
2926
+ fov: navigation.from.fov + (navigation.target.fov - navigation.from.fov) * easedProgress
2927
+ };
2928
+ const completed = progress === 1;
2929
+ viewRef.current = completed ? { ...navigation.target } : nextView2;
2930
+ eulerRef.current.set(
2931
+ import_three.MathUtils.degToRad(viewRef.current.pitch),
2932
+ import_three.MathUtils.degToRad(-viewRef.current.yaw),
2933
+ import_three.MathUtils.degToRad(cameraRollRef.current),
2934
+ "YXZ"
2935
+ );
2936
+ camera.quaternion.setFromEuler(eulerRef.current);
2937
+ camera.fov = viewRef.current.fov;
2938
+ camera.updateProjectionMatrix();
2939
+ camera.updateMatrixWorld();
2940
+ const emittedView = { ...viewRef.current };
2941
+ const lastEmitted2 = lastEmittedViewRef.current;
2942
+ if (!lastEmitted2 || !viewsEqual(lastEmitted2, emittedView)) {
2943
+ lastEmittedViewRef.current = emittedView;
2944
+ eventBusRef.current.emit("viewchange", emittedView);
2945
+ }
2946
+ if (completed) {
2947
+ activeNavigationRef.current = null;
2948
+ settledRef.current = true;
2949
+ eventBusRef.current.emit("viewsettled", emittedView);
2950
+ navigation.resolve({ status: "completed" });
2951
+ dirtyRef.current = false;
2952
+ } else {
2953
+ settledRef.current = false;
2954
+ dirtyRef.current = true;
2955
+ }
2956
+ return;
2957
+ }
2817
2958
  const frictionStop = resolveFrictionStop(optionsRef.current.frictionStop);
2818
2959
  const inertiaEnabled = optionsRef.current.inertia !== false;
2819
2960
  if (!interactingRef.current && !gyroActiveRef.current && inertiaEnabled) {
@@ -3156,9 +3297,33 @@ function useHotspotAccessibilityLayer() {
3156
3297
  return { controls, registry };
3157
3298
  }
3158
3299
 
3300
+ // src/hotspot/target-registry.ts
3301
+ var import_react7 = require("react");
3302
+ var HotspotTargetRegistryContext = (0, import_react7.createContext)(
3303
+ null
3304
+ );
3305
+ function createHotspotTargetRegistry() {
3306
+ const targets = /* @__PURE__ */ new Map();
3307
+ return {
3308
+ getPosition: (id) => {
3309
+ const target = targets.get(id);
3310
+ return target ? { ...target.position } : null;
3311
+ },
3312
+ register: (id, position) => {
3313
+ const token = Symbol(id);
3314
+ targets.set(id, { token, position: { ...position } });
3315
+ return () => {
3316
+ if (targets.get(id)?.token === token) {
3317
+ targets.delete(id);
3318
+ }
3319
+ };
3320
+ }
3321
+ };
3322
+ }
3323
+
3159
3324
  // src/keyboard-controls.tsx
3160
3325
  var import_fiber3 = require("@react-three/fiber");
3161
- var import_react7 = require("react");
3326
+ var import_react8 = require("react");
3162
3327
  var DEFAULT_ROTATE_SPEED = 60;
3163
3328
  var DEFAULT_ZOOM_SPEED = 30;
3164
3329
  var DEFAULT_SHIFT_MULTIPLIER = 3;
@@ -3228,15 +3393,15 @@ function KeyboardControls({
3228
3393
  onNextScene
3229
3394
  }) {
3230
3395
  useClaimControlChannel("keyboard");
3231
- const controlsRef = (0, import_react7.useContext)(PanoramaViewContext);
3396
+ const controlsRef = (0, import_react8.useContext)(PanoramaViewContext);
3232
3397
  const { gl } = (0, import_fiber3.useThree)();
3233
- const pressedRef = (0, import_react7.useRef)(/* @__PURE__ */ new Set());
3234
- const shiftHeldRef = (0, import_react7.useRef)(false);
3235
- const invertRef = (0, import_react7.useRef)(invert);
3236
- const fovSpeedRef = (0, import_react7.useRef)(fovSpeed);
3237
- const onPreviousSceneRef = (0, import_react7.useRef)(onPreviousScene);
3238
- const onNextSceneRef = (0, import_react7.useRef)(onNextScene);
3239
- const keyMap = (0, import_react7.useMemo)(() => resolveKeyMap(keys), [keys]);
3398
+ const pressedRef = (0, import_react8.useRef)(/* @__PURE__ */ new Set());
3399
+ const shiftHeldRef = (0, import_react8.useRef)(false);
3400
+ const invertRef = (0, import_react8.useRef)(invert);
3401
+ const fovSpeedRef = (0, import_react8.useRef)(fovSpeed);
3402
+ const onPreviousSceneRef = (0, import_react8.useRef)(onPreviousScene);
3403
+ const onNextSceneRef = (0, import_react8.useRef)(onNextScene);
3404
+ const keyMap = (0, import_react8.useMemo)(() => resolveKeyMap(keys), [keys]);
3240
3405
  if (!controlsRef) {
3241
3406
  throw new Error("<KeyboardControls> must be rendered inside <PanoViewer>.");
3242
3407
  }
@@ -3244,7 +3409,7 @@ function KeyboardControls({
3244
3409
  fovSpeedRef.current = fovSpeed;
3245
3410
  onPreviousSceneRef.current = onPreviousScene;
3246
3411
  onNextSceneRef.current = onNextScene;
3247
- (0, import_react7.useEffect)(() => {
3412
+ (0, import_react8.useEffect)(() => {
3248
3413
  const element = gl.domElement;
3249
3414
  if (!enabled) {
3250
3415
  pressedRef.current.clear();
@@ -3402,7 +3567,7 @@ function KeyboardControls({
3402
3567
 
3403
3568
  // src/mouse-controls.tsx
3404
3569
  var import_fiber4 = require("@react-three/fiber");
3405
- var import_react8 = require("react");
3570
+ var import_react9 = require("react");
3406
3571
  var DEFAULT_ROTATE_SPEED2 = 0.35;
3407
3572
  var DEFAULT_ZOOM_SPEED2 = 0.08;
3408
3573
  var BUTTON_FLAG = {
@@ -3427,12 +3592,12 @@ function MouseControls({
3427
3592
  fovSpeed
3428
3593
  }) {
3429
3594
  useClaimControlChannel("mouse");
3430
- const controlsRef = (0, import_react8.useContext)(PanoramaViewContext);
3595
+ const controlsRef = (0, import_react9.useContext)(PanoramaViewContext);
3431
3596
  const { gl } = (0, import_fiber4.useThree)();
3432
- const pointersRef = (0, import_react8.useRef)(
3597
+ const pointersRef = (0, import_react9.useRef)(
3433
3598
  /* @__PURE__ */ new Map()
3434
3599
  );
3435
- const optionsRef = (0, import_react8.useRef)({
3600
+ const optionsRef = (0, import_react9.useRef)({
3436
3601
  rotateSpeed,
3437
3602
  zoomSpeed,
3438
3603
  wheel,
@@ -3449,7 +3614,7 @@ function MouseControls({
3449
3614
  invert,
3450
3615
  fovSpeed
3451
3616
  };
3452
- (0, import_react8.useEffect)(() => {
3617
+ (0, import_react9.useEffect)(() => {
3453
3618
  const element = gl.domElement;
3454
3619
  const allowedButtons = resolveButtons(buttons);
3455
3620
  const clearPointers = () => {
@@ -3573,7 +3738,7 @@ function MouseControls({
3573
3738
  }
3574
3739
 
3575
3740
  // src/pano-filter/host.ts
3576
- var import_react9 = require("react");
3741
+ var import_react10 = require("react");
3577
3742
 
3578
3743
  // src/pano-filter/presets.ts
3579
3744
  var PANO_FILTER_PRESETS = [
@@ -3614,7 +3779,7 @@ function isPanoFilterActive(snapshot) {
3614
3779
  }
3615
3780
 
3616
3781
  // src/pano-filter/host.ts
3617
- var PanoFilterHostContext = (0, import_react9.createContext)(null);
3782
+ var PanoFilterHostContext = (0, import_react10.createContext)(null);
3618
3783
  function createPanoFilterHost() {
3619
3784
  return {
3620
3785
  snapshot: { ...DEFAULT_PANO_FILTER_SNAPSHOT },
@@ -3668,8 +3833,8 @@ function subscribeNoop() {
3668
3833
  };
3669
3834
  }
3670
3835
  function usePanoFilterSnapshot() {
3671
- const host = (0, import_react9.useContext)(PanoFilterHostContext);
3672
- const revision = (0, import_react9.useSyncExternalStore)(
3836
+ const host = (0, import_react10.useContext)(PanoFilterHostContext);
3837
+ const revision = (0, import_react10.useSyncExternalStore)(
3673
3838
  host ? (onStoreChange) => subscribePanoFilterHost(host, onStoreChange) : subscribeNoop,
3674
3839
  () => host ? getPanoFilterHostRevision(host) : 0,
3675
3840
  () => host ? getPanoFilterHostRevision(host) : 0
@@ -3683,9 +3848,9 @@ function isProduction2() {
3683
3848
  }
3684
3849
 
3685
3850
  // src/media-activation.tsx
3686
- var import_react10 = require("react");
3851
+ var import_react11 = require("react");
3687
3852
  var import_jsx_runtime2 = require("react/jsx-runtime");
3688
- var PanoMediaActivationHostContext = (0, import_react10.createContext)(null);
3853
+ var PanoMediaActivationHostContext = (0, import_react11.createContext)(null);
3689
3854
  function createPanoMediaActivationHost() {
3690
3855
  return { intents: /* @__PURE__ */ new Set(), listeners: /* @__PURE__ */ new Set(), revision: 0 };
3691
3856
  }
@@ -3708,12 +3873,12 @@ function hasPanoMediaActivationIntent(host) {
3708
3873
  return host.intents.size > 0;
3709
3874
  }
3710
3875
  function usePanoMediaActivationIntent(required) {
3711
- const host = (0, import_react10.useContext)(PanoMediaActivationHostContext);
3712
- const keyRef = (0, import_react10.useRef)(null);
3876
+ const host = (0, import_react11.useContext)(PanoMediaActivationHostContext);
3877
+ const keyRef = (0, import_react11.useRef)(null);
3713
3878
  if (keyRef.current === null) {
3714
3879
  keyRef.current = /* @__PURE__ */ Symbol("pano-media-intent");
3715
3880
  }
3716
- (0, import_react10.useEffect)(() => {
3881
+ (0, import_react11.useEffect)(() => {
3717
3882
  if (!host || !required) {
3718
3883
  return;
3719
3884
  }
@@ -3745,12 +3910,12 @@ function PanoMediaActivationOverlay({
3745
3910
  }
3746
3911
 
3747
3912
  // src/pano-context-menu.tsx
3748
- var import_react11 = require("react");
3913
+ var import_react12 = require("react");
3749
3914
  var import_jsx_runtime3 = require("react/jsx-runtime");
3750
3915
  var DEFAULT_ICON_SIZE = 16;
3751
3916
  var MENU_EDGE_PADDING = 8;
3752
3917
  var MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY = 0.4;
3753
- var PanoContextMenuOverlayContext = (0, import_react11.createContext)(null);
3918
+ var PanoContextMenuOverlayContext = (0, import_react12.createContext)(null);
3754
3919
  var DEFAULT_APPEARANCE = {
3755
3920
  background: "#161616",
3756
3921
  color: "#f4f4f4",
@@ -3790,11 +3955,11 @@ function DefaultContextMenuPanel({
3790
3955
  selectContext,
3791
3956
  onRequestClose
3792
3957
  }) {
3793
- const menuRef = (0, import_react11.useRef)(null);
3794
- const [activeIndex, setActiveIndex] = (0, import_react11.useState)(0);
3958
+ const menuRef = (0, import_react12.useRef)(null);
3959
+ const [activeIndex, setActiveIndex] = (0, import_react12.useState)(0);
3795
3960
  const resolved = { ...DEFAULT_APPEARANCE, ...appearance };
3796
3961
  const iconSize = Number.isFinite(resolved.iconSize) ? Math.max(0, resolved.iconSize) : DEFAULT_ICON_SIZE;
3797
- const visibleItems = (0, import_react11.useMemo)(
3962
+ const visibleItems = (0, import_react12.useMemo)(
3798
3963
  () => items.filter((item) => {
3799
3964
  if (!isActionItem(item)) {
3800
3965
  return true;
@@ -3803,7 +3968,7 @@ function DefaultContextMenuPanel({
3803
3968
  }),
3804
3969
  [items]
3805
3970
  );
3806
- const focusableIndices = (0, import_react11.useMemo)(() => {
3971
+ const focusableIndices = (0, import_react12.useMemo)(() => {
3807
3972
  const indices = [];
3808
3973
  visibleItems.forEach((item, index) => {
3809
3974
  if (isActionItem(item) && !item.disabled) {
@@ -3812,7 +3977,7 @@ function DefaultContextMenuPanel({
3812
3977
  });
3813
3978
  return indices;
3814
3979
  }, [visibleItems]);
3815
- (0, import_react11.useEffect)(() => {
3980
+ (0, import_react12.useEffect)(() => {
3816
3981
  const first = focusableIndices[0];
3817
3982
  setActiveIndex(first ?? 0);
3818
3983
  const frame = requestAnimationFrame(() => {
@@ -3823,7 +3988,7 @@ function DefaultContextMenuPanel({
3823
3988
  });
3824
3989
  return () => cancelAnimationFrame(frame);
3825
3990
  }, [focusableIndices]);
3826
- const activateItem = (0, import_react11.useCallback)(
3991
+ const activateItem = (0, import_react12.useCallback)(
3827
3992
  (item) => {
3828
3993
  if (item.disabled) {
3829
3994
  return;
@@ -4029,10 +4194,10 @@ function PositionedMenuShell({
4029
4194
  overlayElement,
4030
4195
  children
4031
4196
  }) {
4032
- const shellRef = (0, import_react11.useRef)(null);
4033
- const [offset, setOffset] = (0, import_react11.useState)({ left: 0, top: 0 });
4034
- const [viewportRevision, setViewportRevision] = (0, import_react11.useState)(0);
4035
- (0, import_react11.useEffect)(() => {
4197
+ const shellRef = (0, import_react12.useRef)(null);
4198
+ const [offset, setOffset] = (0, import_react12.useState)({ left: 0, top: 0 });
4199
+ const [viewportRevision, setViewportRevision] = (0, import_react12.useState)(0);
4200
+ (0, import_react12.useEffect)(() => {
4036
4201
  const refresh = () => setViewportRevision((revision) => revision + 1);
4037
4202
  const viewport = window.visualViewport;
4038
4203
  window.addEventListener("resize", refresh);
@@ -4044,7 +4209,7 @@ function PositionedMenuShell({
4044
4209
  viewport?.removeEventListener("resize", refresh);
4045
4210
  };
4046
4211
  }, []);
4047
- (0, import_react11.useLayoutEffect)(() => {
4212
+ (0, import_react12.useLayoutEffect)(() => {
4048
4213
  const shell = shellRef.current;
4049
4214
  if (!overlayElement || !shell) {
4050
4215
  return;
@@ -4080,20 +4245,20 @@ function PositionedMenuShell({
4080
4245
  );
4081
4246
  }
4082
4247
  function usePanoContextMenuOverlay() {
4083
- const [session2, setSession] = (0, import_react11.useState)(null);
4084
- const overlayRef = (0, import_react11.useRef)(null);
4085
- const [overlayElement, setOverlayElement] = (0, import_react11.useState)(
4248
+ const [session2, setSession] = (0, import_react12.useState)(null);
4249
+ const overlayRef = (0, import_react12.useRef)(null);
4250
+ const [overlayElement, setOverlayElement] = (0, import_react12.useState)(
4086
4251
  null
4087
4252
  );
4088
- const api = (0, import_react11.useMemo)(
4253
+ const api = (0, import_react12.useMemo)(
4089
4254
  () => ({ setSession, overlayRef }),
4090
4255
  []
4091
4256
  );
4092
- const setOverlayNode = (0, import_react11.useCallback)((node) => {
4257
+ const setOverlayNode = (0, import_react12.useCallback)((node) => {
4093
4258
  overlayRef.current = node;
4094
4259
  setOverlayElement(node);
4095
4260
  }, []);
4096
- (0, import_react11.useEffect)(() => {
4261
+ (0, import_react12.useEffect)(() => {
4097
4262
  if (!session2) {
4098
4263
  return;
4099
4264
  }
@@ -4161,13 +4326,13 @@ function PanoContextMenu({
4161
4326
  separatorClassName,
4162
4327
  children
4163
4328
  }) {
4164
- const eventBus = (0, import_react11.useContext)(PanoEventBusContext);
4165
- const controlsRef = (0, import_react11.useContext)(PanoramaViewContext);
4166
- const overlayApi = (0, import_react11.useContext)(PanoContextMenuOverlayContext);
4167
- const actions = (0, import_react11.useContext)(PanoContextMenuActionsContext);
4168
- const instanceId = (0, import_react11.useId)();
4169
- const sessionKeyRef = (0, import_react11.useRef)(0);
4170
- const propsRef = (0, import_react11.useRef)({
4329
+ const eventBus = (0, import_react12.useContext)(PanoEventBusContext);
4330
+ const controlsRef = (0, import_react12.useContext)(PanoramaViewContext);
4331
+ const overlayApi = (0, import_react12.useContext)(PanoContextMenuOverlayContext);
4332
+ const actions = (0, import_react12.useContext)(PanoContextMenuActionsContext);
4333
+ const instanceId = (0, import_react12.useId)();
4334
+ const sessionKeyRef = (0, import_react12.useRef)(0);
4335
+ const propsRef = (0, import_react12.useRef)({
4171
4336
  items,
4172
4337
  prepend,
4173
4338
  append,
@@ -4197,10 +4362,10 @@ function PanoContextMenu({
4197
4362
  "<PanoContextMenu> requires the PanoViewer context-menu overlay host."
4198
4363
  );
4199
4364
  }
4200
- const close = (0, import_react11.useCallback)(() => {
4365
+ const close = (0, import_react12.useCallback)(() => {
4201
4366
  overlayApi.setSession(null);
4202
4367
  }, [overlayApi]);
4203
- const openMenu = (0, import_react11.useCallback)(
4368
+ const openMenu = (0, import_react12.useCallback)(
4204
4369
  (event) => {
4205
4370
  event.nativeEvent.preventDefault();
4206
4371
  const view = controlsRef.current?.getView() ?? {
@@ -4249,7 +4414,7 @@ function PanoContextMenu({
4249
4414
  },
4250
4415
  [actions, close, controlsRef, instanceId, overlayApi]
4251
4416
  );
4252
- (0, import_react11.useEffect)(() => {
4417
+ (0, import_react12.useEffect)(() => {
4253
4418
  const unsubscribeContextMenu = eventBus.subscribe(
4254
4419
  "contextmenu",
4255
4420
  openMenu
@@ -4428,11 +4593,11 @@ function composePanoContextMenuItems(props, presets) {
4428
4593
  ...resolvePanoContextMenuEntries(props.append ?? [], presets)
4429
4594
  ];
4430
4595
  }
4431
- var PanoContextMenuActionsContext = (0, import_react11.createContext)(null);
4596
+ var PanoContextMenuActionsContext = (0, import_react12.createContext)(null);
4432
4597
 
4433
4598
  // src/pano-cursor.tsx
4434
4599
  var import_fiber5 = require("@react-three/fiber");
4435
- var import_react12 = require("react");
4600
+ var import_react13 = require("react");
4436
4601
  var import_jsx_runtime4 = require("react/jsx-runtime");
4437
4602
  var DEFAULT_PANO_CURSORS = {
4438
4603
  default: "grab",
@@ -4447,9 +4612,9 @@ var LAYER_PRIORITY = {
4447
4612
  hotspotDragging: 3,
4448
4613
  hidden: 4
4449
4614
  };
4450
- var PanoCursorContext = (0, import_react12.createContext)(null);
4615
+ var PanoCursorContext = (0, import_react13.createContext)(null);
4451
4616
  function usePanoCursor() {
4452
- return (0, import_react12.useContext)(PanoCursorContext);
4617
+ return (0, import_react13.useContext)(PanoCursorContext);
4453
4618
  }
4454
4619
  function hotspotCursorClaimId(id) {
4455
4620
  return `pano-cursor:hotspot:${id}`;
@@ -4501,12 +4666,12 @@ function PanoCursorController({
4501
4666
  children
4502
4667
  }) {
4503
4668
  const { gl } = (0, import_fiber5.useThree)();
4504
- const eventBus = (0, import_react12.useContext)(PanoEventBusContext);
4505
- const claimsRef = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
4506
- const cursorsRef = (0, import_react12.useRef)(cursors);
4507
- const appliedCursorRef = (0, import_react12.useRef)(null);
4669
+ const eventBus = (0, import_react13.useContext)(PanoEventBusContext);
4670
+ const claimsRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
4671
+ const cursorsRef = (0, import_react13.useRef)(cursors);
4672
+ const appliedCursorRef = (0, import_react13.useRef)(null);
4508
4673
  cursorsRef.current = cursors;
4509
- const applyCursor = (0, import_react12.useCallback)(() => {
4674
+ const applyCursor = (0, import_react13.useCallback)(() => {
4510
4675
  const next = resolveHighestCursor(claimsRef.current, cursorsRef.current);
4511
4676
  const element = gl.domElement;
4512
4677
  if (appliedCursorRef.current === next && element.style.cursor === next) {
@@ -4515,14 +4680,14 @@ function PanoCursorController({
4515
4680
  element.style.cursor = next;
4516
4681
  appliedCursorRef.current = next;
4517
4682
  }, [gl]);
4518
- const claim = (0, import_react12.useCallback)(
4683
+ const claim = (0, import_react13.useCallback)(
4519
4684
  (id, layer, cursor) => {
4520
4685
  claimsRef.current.set(id, { layer, cursor });
4521
4686
  applyCursor();
4522
4687
  },
4523
4688
  [applyCursor]
4524
4689
  );
4525
- const release = (0, import_react12.useCallback)(
4690
+ const release = (0, import_react13.useCallback)(
4526
4691
  (id) => {
4527
4692
  if (claimsRef.current.delete(id)) {
4528
4693
  applyCursor();
@@ -4530,7 +4695,7 @@ function PanoCursorController({
4530
4695
  },
4531
4696
  [applyCursor]
4532
4697
  );
4533
- const api = (0, import_react12.useMemo)(
4698
+ const api = (0, import_react13.useMemo)(
4534
4699
  () => ({
4535
4700
  cursors,
4536
4701
  claim,
@@ -4538,7 +4703,7 @@ function PanoCursorController({
4538
4703
  }),
4539
4704
  [claim, cursors, release]
4540
4705
  );
4541
- (0, import_react12.useEffect)(() => {
4706
+ (0, import_react13.useEffect)(() => {
4542
4707
  const element = gl.domElement;
4543
4708
  const previous = element.style.cursor;
4544
4709
  return () => {
@@ -4547,10 +4712,10 @@ function PanoCursorController({
4547
4712
  element.style.cursor = previous;
4548
4713
  };
4549
4714
  }, [gl]);
4550
- (0, import_react12.useEffect)(() => {
4715
+ (0, import_react13.useEffect)(() => {
4551
4716
  applyCursor();
4552
4717
  }, [applyCursor, cursors]);
4553
- (0, import_react12.useEffect)(() => {
4718
+ (0, import_react13.useEffect)(() => {
4554
4719
  if (!eventBus) {
4555
4720
  return;
4556
4721
  }
@@ -4580,7 +4745,7 @@ function PanoCursorController({
4580
4745
 
4581
4746
  // src/pano-events.tsx
4582
4747
  var import_fiber6 = require("@react-three/fiber");
4583
- var import_react13 = require("react");
4748
+ var import_react14 = require("react");
4584
4749
  var DEFAULT_IDLE_TIME_MS = 2e3;
4585
4750
  function resolveIdleTime(value) {
4586
4751
  return Number.isFinite(value) && value >= 0 ? value : DEFAULT_IDLE_TIME_MS;
@@ -4618,13 +4783,13 @@ function usePanoEvents({
4618
4783
  onVRDenied,
4619
4784
  onVRUnknownDevice
4620
4785
  }) {
4621
- const eventBus = (0, import_react13.useContext)(PanoEventBusContext);
4622
- const controlsRef = (0, import_react13.useContext)(PanoramaViewContext);
4786
+ const eventBus = (0, import_react14.useContext)(PanoEventBusContext);
4787
+ const controlsRef = (0, import_react14.useContext)(PanoramaViewContext);
4623
4788
  const { gl } = (0, import_fiber6.useThree)();
4624
4789
  if (!eventBus || !controlsRef) {
4625
4790
  throw new Error("usePanoEvents must be used inside <PanoViewer>.");
4626
4791
  }
4627
- const callbacksRef = (0, import_react13.useRef)({
4792
+ const callbacksRef = (0, import_react14.useRef)({
4628
4793
  onViewChange,
4629
4794
  onViewSettled,
4630
4795
  onViewInteractionStart,
@@ -4688,15 +4853,15 @@ function usePanoEvents({
4688
4853
  onVRDenied,
4689
4854
  onVRUnknownDevice
4690
4855
  };
4691
- const idleElapsedRef = (0, import_react13.useRef)(0);
4692
- const isIdleRef = (0, import_react13.useRef)(false);
4693
- const idleTimeRef = (0, import_react13.useRef)(resolveIdleTime(idleTime));
4856
+ const idleElapsedRef = (0, import_react14.useRef)(0);
4857
+ const isIdleRef = (0, import_react14.useRef)(false);
4858
+ const idleTimeRef = (0, import_react14.useRef)(resolveIdleTime(idleTime));
4694
4859
  idleTimeRef.current = resolveIdleTime(idleTime);
4695
- (0, import_react13.useEffect)(() => {
4860
+ (0, import_react14.useEffect)(() => {
4696
4861
  idleElapsedRef.current = 0;
4697
4862
  isIdleRef.current = false;
4698
4863
  }, [idleTime]);
4699
- (0, import_react13.useEffect)(() => {
4864
+ (0, import_react14.useEffect)(() => {
4700
4865
  const unsubscribers = [
4701
4866
  eventBus.subscribe("viewchange", (view) => {
4702
4867
  callbacksRef.current.onViewChange?.(view);
@@ -4777,7 +4942,7 @@ function usePanoEvents({
4777
4942
  }
4778
4943
  };
4779
4944
  }, [eventBus]);
4780
- (0, import_react13.useEffect)(() => {
4945
+ (0, import_react14.useEffect)(() => {
4781
4946
  const element = gl.domElement;
4782
4947
  const handleWheel = (nativeEvent) => {
4783
4948
  callbacksRef.current.onWheel?.({
@@ -4790,7 +4955,7 @@ function usePanoEvents({
4790
4955
  element.removeEventListener("wheel", handleWheel);
4791
4956
  };
4792
4957
  }, [gl]);
4793
- (0, import_react13.useEffect)(() => {
4958
+ (0, import_react14.useEffect)(() => {
4794
4959
  if (typeof document === "undefined") {
4795
4960
  return;
4796
4961
  }
@@ -4816,7 +4981,7 @@ function usePanoEvents({
4816
4981
  wasFullscreenRef.current = isViewerFullscreen();
4817
4982
  return subscribeFullscreenChange(handleFullscreenChange);
4818
4983
  }, [gl]);
4819
- (0, import_react13.useEffect)(() => {
4984
+ (0, import_react14.useEffect)(() => {
4820
4985
  const element = gl.domElement;
4821
4986
  if (typeof ResizeObserver === "undefined") {
4822
4987
  return;
@@ -4858,7 +5023,7 @@ function PanoEvents(props) {
4858
5023
 
4859
5024
  // src/panorama-event-surface.tsx
4860
5025
  var import_fiber7 = require("@react-three/fiber");
4861
- var import_react14 = require("react");
5026
+ var import_react15 = require("react");
4862
5027
  var import_three3 = require("three");
4863
5028
 
4864
5029
  // src/hotspot/coordinates.ts
@@ -4951,9 +5116,9 @@ function makePanoramaPointerEvent(event) {
4951
5116
  };
4952
5117
  }
4953
5118
  function PanoramaEventSurface() {
4954
- const eventBus = (0, import_react14.useContext)(PanoEventBusContext);
5119
+ const eventBus = (0, import_react15.useContext)(PanoEventBusContext);
4955
5120
  const { camera, gl } = (0, import_fiber7.useThree)();
4956
- (0, import_react14.useEffect)(() => {
5121
+ (0, import_react15.useEffect)(() => {
4957
5122
  if (!eventBus) {
4958
5123
  return;
4959
5124
  }
@@ -5022,8 +5187,8 @@ function PanoramaEventSurface() {
5022
5187
  }
5023
5188
 
5024
5189
  // src/scenes-host.ts
5025
- var import_react15 = require("react");
5026
- var ScenesHostContext = (0, import_react15.createContext)(null);
5190
+ var import_react16 = require("react");
5191
+ var ScenesHostContext = (0, import_react16.createContext)(null);
5027
5192
  function createScenesHost() {
5028
5193
  return {
5029
5194
  controller: null,
@@ -5040,7 +5205,7 @@ function notifyScenesHost(host) {
5040
5205
 
5041
5206
  // src/touch-controls.tsx
5042
5207
  var import_fiber8 = require("@react-three/fiber");
5043
- var import_react16 = require("react");
5208
+ var import_react17 = require("react");
5044
5209
  var DEFAULT_ROTATE_SPEED3 = 0.35;
5045
5210
  function resolveSpeed3(value, fallback) {
5046
5211
  return Number.isFinite(value) && value >= 0 ? value : fallback;
@@ -5055,16 +5220,16 @@ function TouchControls({
5055
5220
  pinchZoom = true
5056
5221
  }) {
5057
5222
  useClaimControlChannel("touch");
5058
- const controlsRef = (0, import_react16.useContext)(PanoramaViewContext);
5223
+ const controlsRef = (0, import_react17.useContext)(PanoramaViewContext);
5059
5224
  const { gl } = (0, import_fiber8.useThree)();
5060
- const pointersRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
5061
- const pinchDistanceRef = (0, import_react16.useRef)(null);
5062
- const optionsRef = (0, import_react16.useRef)({ rotateSpeed, invert, pinchZoom });
5225
+ const pointersRef = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
5226
+ const pinchDistanceRef = (0, import_react17.useRef)(null);
5227
+ const optionsRef = (0, import_react17.useRef)({ rotateSpeed, invert, pinchZoom });
5063
5228
  if (!controlsRef) {
5064
5229
  throw new Error("<TouchControls> must be rendered inside <PanoViewer>.");
5065
5230
  }
5066
5231
  optionsRef.current = { rotateSpeed, invert, pinchZoom };
5067
- (0, import_react16.useEffect)(() => {
5232
+ (0, import_react17.useEffect)(() => {
5068
5233
  const element = gl.domElement;
5069
5234
  const clearPointers = () => {
5070
5235
  for (const pointerId of pointersRef.current.keys()) {
@@ -5186,17 +5351,17 @@ function TouchControls({
5186
5351
  }
5187
5352
 
5188
5353
  // src/video/chrome-overlay.tsx
5189
- var import_react17 = require("react");
5354
+ var import_react18 = require("react");
5190
5355
  var import_jsx_runtime6 = require("react/jsx-runtime");
5191
- var PanoChromeOverlayContext = (0, import_react17.createContext)(null);
5356
+ var PanoChromeOverlayContext = (0, import_react18.createContext)(null);
5192
5357
  function usePanoChromeOverlay() {
5193
- const [overlayElement, setOverlayElement] = (0, import_react17.useState)(
5358
+ const [overlayElement, setOverlayElement] = (0, import_react18.useState)(
5194
5359
  null
5195
5360
  );
5196
- const setOverlayNode = (0, import_react17.useCallback)((node) => {
5361
+ const setOverlayNode = (0, import_react18.useCallback)((node) => {
5197
5362
  setOverlayElement(node);
5198
5363
  }, []);
5199
- const api = (0, import_react17.useMemo)(
5364
+ const api = (0, import_react18.useMemo)(
5200
5365
  () => ({ overlayElement }),
5201
5366
  [overlayElement]
5202
5367
  );
@@ -5212,9 +5377,9 @@ function usePanoChromeOverlay() {
5212
5377
  }
5213
5378
 
5214
5379
  // src/video/host.ts
5215
- var import_react18 = require("react");
5216
- var PanoVideoHostContext = (0, import_react18.createContext)(null);
5217
- var DefaultPanoVideoControlsContext = (0, import_react18.createContext)(false);
5380
+ var import_react19 = require("react");
5381
+ var PanoVideoHostContext = (0, import_react19.createContext)(null);
5382
+ var DefaultPanoVideoControlsContext = (0, import_react19.createContext)(false);
5218
5383
  function createPanoVideoHost() {
5219
5384
  return {
5220
5385
  controller: null,
@@ -5259,8 +5424,8 @@ function isProduction3() {
5259
5424
  return nodeEnv === "production";
5260
5425
  }
5261
5426
  function useClaimPanoVideoControls() {
5262
- const host = (0, import_react18.useContext)(PanoVideoHostContext);
5263
- const isDefault = (0, import_react18.useContext)(DefaultPanoVideoControlsContext);
5427
+ const host = (0, import_react19.useContext)(PanoVideoHostContext);
5428
+ const isDefault = (0, import_react19.useContext)(DefaultPanoVideoControlsContext);
5264
5429
  if (!host || isDefault) {
5265
5430
  return;
5266
5431
  }
@@ -5273,10 +5438,10 @@ function useClaimPanoVideoControls() {
5273
5438
  }
5274
5439
 
5275
5440
  // src/video/pano-video-chrome-bridge.tsx
5276
- var import_react21 = require("react");
5441
+ var import_react22 = require("react");
5277
5442
 
5278
5443
  // src/video/pano-video-captions.tsx
5279
- var import_react19 = require("react");
5444
+ var import_react20 = require("react");
5280
5445
  var import_jsx_runtime7 = require("react/jsx-runtime");
5281
5446
  var DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE = {
5282
5447
  color: "#ffffff",
@@ -5300,7 +5465,7 @@ function resolvePanoVideoCaptionAppearance(appearance) {
5300
5465
  function PanoVideoCaptionsOverlay({
5301
5466
  controller
5302
5467
  }) {
5303
- const snapshot = (0, import_react19.useSyncExternalStore)(
5468
+ const snapshot = (0, import_react20.useSyncExternalStore)(
5304
5469
  controller.subscribe,
5305
5470
  controller.getSnapshot,
5306
5471
  controller.getSnapshot
@@ -5342,7 +5507,7 @@ function PanoVideoCaptions({
5342
5507
  }
5343
5508
 
5344
5509
  // src/video/pano-video-controls.tsx
5345
- var import_react20 = require("react");
5510
+ var import_react21 = require("react");
5346
5511
 
5347
5512
  // src/video/format.ts
5348
5513
  var DEFAULT_PANO_VIDEO_PLAYBACK_RATES = [0.5, 1, 1.25, 1.5, 2];
@@ -5794,7 +5959,7 @@ function VerticalVolumeSlider({
5794
5959
  onVolume,
5795
5960
  volume
5796
5961
  }) {
5797
- const trackRef = (0, import_react20.useRef)(null);
5962
+ const trackRef = (0, import_react21.useRef)(null);
5798
5963
  const applyPointer = (event) => {
5799
5964
  const track = trackRef.current;
5800
5965
  if (!track) {
@@ -5930,14 +6095,14 @@ function VolumeControl({
5930
6095
  volume,
5931
6096
  volumeAdjustable
5932
6097
  }) {
5933
- const rootRef = (0, import_react20.useRef)(null);
5934
- const [open, setOpen] = (0, import_react20.useState)(false);
6098
+ const rootRef = (0, import_react21.useRef)(null);
6099
+ const [open, setOpen] = (0, import_react21.useState)(false);
5935
6100
  const displayVolume = muted ? 0 : volume;
5936
6101
  const mutedOrSilent = muted || volume === 0;
5937
- (0, import_react20.useEffect)(() => {
6102
+ (0, import_react21.useEffect)(() => {
5938
6103
  onOpenChange(open);
5939
6104
  }, [onOpenChange, open]);
5940
- (0, import_react20.useEffect)(() => {
6105
+ (0, import_react21.useEffect)(() => {
5941
6106
  if (!open || !volumeAdjustable || hasFinePointerHover()) {
5942
6107
  return;
5943
6108
  }
@@ -6024,24 +6189,24 @@ function PanoVideoControlsHud({
6024
6189
  fullscreen,
6025
6190
  overlayElement
6026
6191
  }) {
6027
- const resolved = (0, import_react20.useMemo)(
6192
+ const resolved = (0, import_react21.useMemo)(
6028
6193
  () => resolveControlsAppearance(appearance),
6029
6194
  [appearance]
6030
6195
  );
6031
- const snapshot = (0, import_react20.useSyncExternalStore)(
6196
+ const snapshot = (0, import_react21.useSyncExternalStore)(
6032
6197
  controller.subscribe,
6033
6198
  controller.getSnapshot,
6034
6199
  controller.getSnapshot
6035
6200
  );
6036
- const [menu, setMenu] = (0, import_react20.useState)(null);
6037
- const [captionsPanel, setCaptionsPanel] = (0, import_react20.useState)("tracks");
6038
- const [visible, setVisible] = (0, import_react20.useState)(true);
6039
- const [volumeOpen, setVolumeOpen] = (0, import_react20.useState)(false);
6040
- const [overlayWidth, setOverlayWidth] = (0, import_react20.useState)(
6201
+ const [menu, setMenu] = (0, import_react21.useState)(null);
6202
+ const [captionsPanel, setCaptionsPanel] = (0, import_react21.useState)("tracks");
6203
+ const [visible, setVisible] = (0, import_react21.useState)(true);
6204
+ const [volumeOpen, setVolumeOpen] = (0, import_react21.useState)(false);
6205
+ const [overlayWidth, setOverlayWidth] = (0, import_react21.useState)(
6041
6206
  () => overlayElement.clientWidth
6042
6207
  );
6043
- const idleTimerRef = (0, import_react20.useRef)(0);
6044
- const barId = (0, import_react20.useId)();
6208
+ const idleTimerRef = (0, import_react21.useRef)(0);
6209
+ const barId = (0, import_react21.useId)();
6045
6210
  const rateMenuId = `${barId}-rate`;
6046
6211
  const variantMenuId = `${barId}-variant`;
6047
6212
  const captionsMenuId = `${barId}-captions`;
@@ -6049,7 +6214,7 @@ function PanoVideoControlsHud({
6049
6214
  const compact = overlayWidth < COMPACT_CONTROLS_WIDTH;
6050
6215
  const hideTime = overlayWidth < NARROW_CONTROLS_WIDTH;
6051
6216
  const showFullscreen = isFullscreenEnabled();
6052
- const bumpVisibility = (0, import_react20.useCallback)(
6217
+ const bumpVisibility = (0, import_react21.useCallback)(
6053
6218
  (playing) => {
6054
6219
  setVisible(true);
6055
6220
  window.clearTimeout(idleTimerRef.current);
@@ -6062,7 +6227,7 @@ function PanoVideoControlsHud({
6062
6227
  },
6063
6228
  [menu, volumeOpen]
6064
6229
  );
6065
- (0, import_react20.useEffect)(() => {
6230
+ (0, import_react21.useEffect)(() => {
6066
6231
  if (typeof ResizeObserver === "undefined") {
6067
6232
  return;
6068
6233
  }
@@ -6077,15 +6242,15 @@ function PanoVideoControlsHud({
6077
6242
  observer.disconnect();
6078
6243
  };
6079
6244
  }, [overlayElement]);
6080
- (0, import_react20.useEffect)(() => {
6245
+ (0, import_react21.useEffect)(() => {
6081
6246
  if (!compact && menu === "more") {
6082
6247
  setMenu(null);
6083
6248
  }
6084
6249
  }, [compact, menu]);
6085
- (0, import_react20.useEffect)(() => {
6250
+ (0, import_react21.useEffect)(() => {
6086
6251
  bumpVisibility(snapshot.playing);
6087
6252
  }, [bumpVisibility, snapshot.playing]);
6088
- (0, import_react20.useEffect)(() => {
6253
+ (0, import_react21.useEffect)(() => {
6089
6254
  const root = overlayElement.parentElement;
6090
6255
  if (!root) {
6091
6256
  return;
@@ -6144,7 +6309,7 @@ function PanoVideoControlsHud({
6144
6309
  document.removeEventListener("pointerdown", handlePointerDown, true);
6145
6310
  };
6146
6311
  }, [bumpVisibility, controller, menu, overlayElement, snapshot.playing, volumeOpen]);
6147
- (0, import_react20.useEffect)(
6312
+ (0, import_react21.useEffect)(
6148
6313
  () => () => {
6149
6314
  window.clearTimeout(idleTimerRef.current);
6150
6315
  },
@@ -6435,7 +6600,7 @@ function PanoVideoControlsHud({
6435
6600
  }
6436
6601
  function PanoVideoControls({ appearance }) {
6437
6602
  useClaimPanoVideoControls();
6438
- const host = (0, import_react20.useContext)(PanoVideoHostContext);
6603
+ const host = (0, import_react21.useContext)(PanoVideoHostContext);
6439
6604
  if (host && appearance) {
6440
6605
  host.controls = appearance;
6441
6606
  }
@@ -6449,7 +6614,7 @@ function PanoVideoChromeBridge({
6449
6614
  host,
6450
6615
  overlayElement
6451
6616
  }) {
6452
- (0, import_react21.useSyncExternalStore)(
6617
+ (0, import_react22.useSyncExternalStore)(
6453
6618
  (onStoreChange) => subscribePanoVideoHost(host, onStoreChange),
6454
6619
  () => getPanoVideoHostRevision(host),
6455
6620
  () => getPanoVideoHostRevision(host)
@@ -6473,11 +6638,11 @@ function PanoVideoChromeBridge({
6473
6638
  }
6474
6639
 
6475
6640
  // src/webvr/chrome.tsx
6476
- var import_react23 = require("react");
6641
+ var import_react24 = require("react");
6477
6642
 
6478
6643
  // src/webvr/host.ts
6479
- var import_react22 = require("react");
6480
- var WebVRRuntimeContext = (0, import_react22.createContext)(null);
6644
+ var import_react23 = require("react");
6645
+ var WebVRRuntimeContext = (0, import_react23.createContext)(null);
6481
6646
  function createWebVRHost() {
6482
6647
  return {
6483
6648
  controller: null,
@@ -6748,7 +6913,7 @@ function SetupPanel({
6748
6913
  );
6749
6914
  }
6750
6915
  function WebVRChromeBridge({ host }) {
6751
- (0, import_react23.useSyncExternalStore)(
6916
+ (0, import_react24.useSyncExternalStore)(
6752
6917
  (listener) => subscribeWebVRHost(host, listener),
6753
6918
  () => host.revision,
6754
6919
  () => host.revision
@@ -6832,12 +6997,12 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
6832
6997
  // src/webvr/xr-origin.tsx
6833
6998
  var import_fiber9 = require("@react-three/fiber");
6834
6999
  var import_xr2 = require("@react-three/xr");
6835
- var import_react24 = require("react");
7000
+ var import_react25 = require("react");
6836
7001
  var import_three5 = require("three");
6837
7002
  var import_jsx_runtime11 = require("react/jsx-runtime");
6838
7003
  function PanoramaXROrigin() {
6839
- const originRef = (0, import_react24.useRef)(null);
6840
- const localHeadPositionRef = (0, import_react24.useRef)(new import_three5.Vector3());
7004
+ const originRef = (0, import_react25.useRef)(null);
7005
+ const localHeadPositionRef = (0, import_react25.useRef)(new import_three5.Vector3());
6841
7006
  const session2 = (0, import_xr2.useXR)((state) => state.session);
6842
7007
  const gl = (0, import_fiber9.useThree)((state) => state.gl);
6843
7008
  (0, import_fiber9.useFrame)(() => {
@@ -6902,7 +7067,7 @@ function PanoCursorTree({
6902
7067
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoCursorController, { cursors, children });
6903
7068
  }
6904
7069
  function PanoVideoHostReset() {
6905
- const host = (0, import_react25.useContext)(PanoVideoHostContext);
7070
+ const host = (0, import_react26.useContext)(PanoVideoHostContext);
6906
7071
  if (host) {
6907
7072
  host.controlClaims = 0;
6908
7073
  }
@@ -6915,7 +7080,7 @@ function DefaultControlChannels({
6915
7080
  keyboardChannel,
6916
7081
  fovSpeed
6917
7082
  }) {
6918
- const claims = (0, import_react25.useContext)(ControlClaimsContext);
7083
+ const claims = (0, import_react26.useContext)(ControlClaimsContext);
6919
7084
  if (!claims) {
6920
7085
  return null;
6921
7086
  }
@@ -6931,7 +7096,7 @@ function DefaultControlChannels({
6931
7096
  ) : null
6932
7097
  ] });
6933
7098
  }
6934
- var PanoViewer = (0, import_react25.forwardRef)(
7099
+ var PanoViewer = (0, import_react26.forwardRef)(
6935
7100
  function PanoViewer2({
6936
7101
  children,
6937
7102
  initialView,
@@ -6950,30 +7115,31 @@ var PanoViewer = (0, import_react25.forwardRef)(
6950
7115
  "aria-label": ariaLabel = "Panorama viewer",
6951
7116
  ...divProps
6952
7117
  }, ref) {
6953
- const rootRef = (0, import_react25.useRef)(null);
6954
- const controlsRef = (0, import_react25.useRef)(null);
6955
- const eventBus = (0, import_react25.useMemo)(() => createPanoEventBus(), []);
7118
+ const rootRef = (0, import_react26.useRef)(null);
7119
+ const controlsRef = (0, import_react26.useRef)(null);
7120
+ const eventBus = (0, import_react26.useMemo)(() => createPanoEventBus(), []);
6956
7121
  const { controls: hotspotAccessibilityControls, registry } = useHotspotAccessibilityLayer();
7122
+ const hotspotTargetRegistry = (0, import_react26.useMemo)(() => createHotspotTargetRegistry(), []);
6957
7123
  const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } = usePanoContextMenuOverlay();
6958
7124
  const { api: chromeOverlayApi, setOverlayNode, overlayElement } = usePanoChromeOverlay();
6959
- const videoHost = (0, import_react25.useMemo)(() => createPanoVideoHost(), []);
6960
- const filterHost = (0, import_react25.useMemo)(() => createPanoFilterHost(), []);
6961
- const webVRHost = (0, import_react25.useMemo)(() => createWebVRHost(), []);
6962
- const scenesHost = (0, import_react25.useMemo)(() => createScenesHost(), []);
6963
- const bgmHost = (0, import_react25.useMemo)(() => createBackgroundAudioHost(), []);
6964
- const mediaActivationHost = (0, import_react25.useMemo)(() => createPanoMediaActivationHost(), []);
6965
- const mediaActivationOptions = (0, import_react25.useMemo)(
7125
+ const videoHost = (0, import_react26.useMemo)(() => createPanoVideoHost(), []);
7126
+ const filterHost = (0, import_react26.useMemo)(() => createPanoFilterHost(), []);
7127
+ const webVRHost = (0, import_react26.useMemo)(() => createWebVRHost(), []);
7128
+ const scenesHost = (0, import_react26.useMemo)(() => createScenesHost(), []);
7129
+ const bgmHost = (0, import_react26.useMemo)(() => createBackgroundAudioHost(), []);
7130
+ const mediaActivationHost = (0, import_react26.useMemo)(() => createPanoMediaActivationHost(), []);
7131
+ const mediaActivationOptions = (0, import_react26.useMemo)(
6966
7132
  () => mediaActivation === false ? null : mediaActivation ?? {},
6967
7133
  [mediaActivation]
6968
7134
  );
6969
- const mediaActivationRevision = (0, import_react25.useSyncExternalStore)(
7135
+ const mediaActivationRevision = (0, import_react26.useSyncExternalStore)(
6970
7136
  (onStoreChange) => subscribePanoMediaActivation(mediaActivationHost, onStoreChange),
6971
7137
  () => getPanoMediaActivationRevision(mediaActivationHost),
6972
7138
  () => getPanoMediaActivationRevision(mediaActivationHost)
6973
7139
  );
6974
- const [mediaActivated, setMediaActivated] = (0, import_react25.useState)(false);
6975
- const stereoView = (0, import_react25.useMemo)(() => createWebVRStereoView(), []);
6976
- const xrStore = (0, import_react25.useMemo)(
7140
+ const [mediaActivated, setMediaActivated] = (0, import_react26.useState)(false);
7141
+ const stereoView = (0, import_react26.useMemo)(() => createWebVRStereoView(), []);
7142
+ const xrStore = (0, import_react26.useMemo)(
6977
7143
  () => (0, import_xr3.createXRStore)({
6978
7144
  anchors: false,
6979
7145
  bodyTracking: false,
@@ -6989,7 +7155,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
6989
7155
  }),
6990
7156
  []
6991
7157
  );
6992
- const mediaActivationControls = (0, import_react25.useMemo)(
7158
+ const mediaActivationControls = (0, import_react26.useMemo)(
6993
7159
  () => ({
6994
7160
  resumeAudio: () => resumePanoAudio(),
6995
7161
  playVideo: async ({ unmute = false } = {}) => {
@@ -7007,7 +7173,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7007
7173
  }),
7008
7174
  [bgmHost, videoHost]
7009
7175
  );
7010
- const activateMedia = (0, import_react25.useCallback)(() => {
7176
+ const activateMedia = (0, import_react26.useCallback)(() => {
7011
7177
  setMediaActivated(true);
7012
7178
  const resume = mediaActivationControls.resumeAudio();
7013
7179
  mediaActivationOptions?.onActivate?.(mediaActivationControls);
@@ -7015,13 +7181,13 @@ var PanoViewer = (0, import_react25.forwardRef)(
7015
7181
  }, [mediaActivationControls, mediaActivationOptions]);
7016
7182
  const hasMediaActivationIntent = mediaActivationRevision >= 0 && hasPanoMediaActivationIntent(mediaActivationHost);
7017
7183
  const shouldShowMediaActivation = mediaActivationOptions !== null && hasMediaActivationIntent && !mediaActivated;
7018
- const fallbackViewRef = (0, import_react25.useRef)(DEFAULT_VIEW);
7184
+ const fallbackViewRef = (0, import_react26.useRef)(DEFAULT_VIEW);
7019
7185
  const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
7020
7186
  const normalizedMaxFov = Math.min(
7021
7187
  179,
7022
7188
  Math.max(maxFov, normalizedMinFov + 1)
7023
7189
  );
7024
- const normalizedInitialView = (0, import_react25.useMemo)(
7190
+ const normalizedInitialView = (0, import_react26.useMemo)(
7025
7191
  () => ({
7026
7192
  yaw: initialView?.yaw ?? DEFAULT_VIEW.yaw,
7027
7193
  pitch: clampPanoPitch(initialView?.pitch ?? DEFAULT_VIEW.pitch),
@@ -7039,10 +7205,10 @@ var PanoViewer = (0, import_react25.forwardRef)(
7039
7205
  ]
7040
7206
  );
7041
7207
  fallbackViewRef.current = normalizedInitialView;
7042
- const controlClaims = (0, import_react25.useMemo)(() => createControlClaims(), []);
7208
+ const controlClaims = (0, import_react26.useMemo)(() => createControlClaims(), []);
7043
7209
  resetControlClaims(controlClaims);
7044
7210
  const controlsEnabled = controls !== false;
7045
- const controlOptions = (0, import_react25.useMemo)(
7211
+ const controlOptions = (0, import_react26.useMemo)(
7046
7212
  () => typeof controls === "object" ? controls : {},
7047
7213
  [controls]
7048
7214
  );
@@ -7050,7 +7216,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7050
7216
  const allModeInvert = controlOptions.invert === true;
7051
7217
  const topRotateSpeed = controlOptions.rotateSpeed ?? DEFAULT_POINTER_ROTATE_SPEED;
7052
7218
  const topZoomSpeed = controlOptions.zoomSpeed ?? DEFAULT_MOUSE_ZOOM_SPEED;
7053
- const mouseChannel = (0, import_react25.useMemo)(
7219
+ const mouseChannel = (0, import_react26.useMemo)(
7054
7220
  () => resolveChannel(controlOptions.mouse, {
7055
7221
  enabled: true,
7056
7222
  rotateSpeed: topRotateSpeed,
@@ -7066,7 +7232,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7066
7232
  topZoomSpeed
7067
7233
  ]
7068
7234
  );
7069
- const touchChannel = (0, import_react25.useMemo)(
7235
+ const touchChannel = (0, import_react26.useMemo)(
7070
7236
  () => resolveChannel(controlOptions.touch, {
7071
7237
  enabled: true,
7072
7238
  rotateSpeed: topRotateSpeed,
@@ -7075,13 +7241,13 @@ var PanoViewer = (0, import_react25.forwardRef)(
7075
7241
  }),
7076
7242
  [allModeInvert, controlOptions.touch, topRotateSpeed]
7077
7243
  );
7078
- const keyboardChannel = (0, import_react25.useMemo)(
7244
+ const keyboardChannel = (0, import_react26.useMemo)(
7079
7245
  () => resolveChannel(controlOptions.keyboard, {
7080
7246
  enabled: true
7081
7247
  }),
7082
7248
  [controlOptions.keyboard]
7083
7249
  );
7084
- const enterFullscreen = (0, import_react25.useCallback)(async () => {
7250
+ const enterFullscreen = (0, import_react26.useCallback)(async () => {
7085
7251
  if (typeof document === "undefined") {
7086
7252
  return;
7087
7253
  }
@@ -7094,7 +7260,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7094
7260
  }
7095
7261
  await requestElementFullscreen(root);
7096
7262
  }, []);
7097
- const exitFullscreen = (0, import_react25.useCallback)(async () => {
7263
+ const exitFullscreen = (0, import_react26.useCallback)(async () => {
7098
7264
  if (typeof document === "undefined") {
7099
7265
  return;
7100
7266
  }
@@ -7103,7 +7269,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7103
7269
  }
7104
7270
  await exitElementFullscreen();
7105
7271
  }, []);
7106
- const toggleFullscreen = (0, import_react25.useCallback)(async () => {
7272
+ const toggleFullscreen = (0, import_react26.useCallback)(async () => {
7107
7273
  if (typeof document === "undefined") {
7108
7274
  return;
7109
7275
  }
@@ -7117,8 +7283,8 @@ var PanoViewer = (0, import_react25.forwardRef)(
7117
7283
  }
7118
7284
  await requestElementFullscreen(root);
7119
7285
  }, []);
7120
- const [isViewerFullscreen, setIsViewerFullscreen] = (0, import_react25.useState)(false);
7121
- (0, import_react25.useEffect)(() => {
7286
+ const [isViewerFullscreen, setIsViewerFullscreen] = (0, import_react26.useState)(false);
7287
+ (0, import_react26.useEffect)(() => {
7122
7288
  if (typeof document === "undefined") {
7123
7289
  return;
7124
7290
  }
@@ -7136,7 +7302,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7136
7302
  syncFullscreen();
7137
7303
  return subscribeFullscreenChange(syncFullscreen);
7138
7304
  }, []);
7139
- (0, import_react25.useEffect)(() => {
7305
+ (0, import_react26.useEffect)(() => {
7140
7306
  const root = rootRef.current;
7141
7307
  if (!root) {
7142
7308
  return;
@@ -7149,7 +7315,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7149
7315
  root.removeEventListener("contextmenu", suppressNativeContextMenu, true);
7150
7316
  };
7151
7317
  }, []);
7152
- const contextMenuActions = (0, import_react25.useMemo)(
7318
+ const contextMenuActions = (0, import_react26.useMemo)(
7153
7319
  () => ({
7154
7320
  reset: () => {
7155
7321
  controlsRef.current?.reset();
@@ -7161,24 +7327,24 @@ var PanoViewer = (0, import_react25.forwardRef)(
7161
7327
  }),
7162
7328
  [isViewerFullscreen, toggleFullscreen]
7163
7329
  );
7164
- const contextMenuChannel = (0, import_react25.useMemo)(
7330
+ const contextMenuChannel = (0, import_react26.useMemo)(
7165
7331
  () => resolveContextMenuChannel(contextMenu),
7166
7332
  [contextMenu]
7167
7333
  );
7168
- const resolvedCursors = (0, import_react25.useMemo)(
7334
+ const resolvedCursors = (0, import_react26.useMemo)(
7169
7335
  () => resolvePanoCursors(cursors),
7170
7336
  [cursors]
7171
7337
  );
7172
7338
  const legacyAutoRotateOptions = controlOptions;
7173
- const [legacyAutoRotate, setLegacyAutoRotate] = (0, import_react25.useState)(
7339
+ const [legacyAutoRotate, setLegacyAutoRotate] = (0, import_react26.useState)(
7174
7340
  legacyAutoRotateOptions.autoRotate ?? false
7175
7341
  );
7176
- (0, import_react25.useEffect)(() => {
7342
+ (0, import_react26.useEffect)(() => {
7177
7343
  setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);
7178
7344
  }, [legacyAutoRotateOptions.autoRotate]);
7179
- const isFullscreenRef = (0, import_react25.useRef)(false);
7345
+ const isFullscreenRef = (0, import_react26.useRef)(false);
7180
7346
  isFullscreenRef.current = isViewerFullscreen;
7181
- (0, import_react25.useImperativeHandle)(
7347
+ (0, import_react26.useImperativeHandle)(
7182
7348
  ref,
7183
7349
  () => ({
7184
7350
  // -- View --
@@ -7189,6 +7355,13 @@ var PanoViewer = (0, import_react25.forwardRef)(
7189
7355
  reset: () => {
7190
7356
  controlsRef.current?.reset();
7191
7357
  },
7358
+ lookTo: (position, options) => controlsRef.current?.lookTo(position, options) ?? Promise.resolve({ status: "cancelled" }),
7359
+ moveTo: (position, options) => controlsRef.current?.moveTo(position, options) ?? Promise.resolve({ status: "cancelled" }),
7360
+ zoomTo: (fov, options) => controlsRef.current?.zoomTo(fov, options) ?? Promise.resolve({ status: "cancelled" }),
7361
+ lookToHotspot: (id, options) => {
7362
+ const position = hotspotTargetRegistry.getPosition(id);
7363
+ return position ? controlsRef.current?.lookTo(position, options) ?? Promise.resolve({ status: "cancelled" }) : Promise.resolve({ status: "not-found" });
7364
+ },
7192
7365
  activateMedia,
7193
7366
  // -- Fullscreen --
7194
7367
  enterFullscreen,
@@ -7246,12 +7419,13 @@ var PanoViewer = (0, import_react25.forwardRef)(
7246
7419
  enterFullscreen,
7247
7420
  exitFullscreen,
7248
7421
  scenesHost,
7422
+ hotspotTargetRegistry,
7249
7423
  toggleFullscreen,
7250
7424
  videoHost,
7251
7425
  webVRHost
7252
7426
  ]
7253
7427
  );
7254
- const rootStyle = (0, import_react25.useMemo)(
7428
+ const rootStyle = (0, import_react26.useMemo)(
7255
7429
  () => ({
7256
7430
  overflow: "hidden",
7257
7431
  position: "relative",
@@ -7297,7 +7471,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7297
7471
  value: { host: webVRHost, xrStore, stereoView },
7298
7472
  children: [
7299
7473
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoramaXROrigin, {}),
7300
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HotspotAccessibilityContext.Provider, { value: registry, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoCursorTree, { cursors: resolvedCursors, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoramaViewContext.Provider, { value: controlsRef, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
7474
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HotspotAccessibilityContext.Provider, { value: registry, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HotspotTargetRegistryContext.Provider, { value: hotspotTargetRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoCursorTree, { cursors: resolvedCursors, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PanoramaViewContext.Provider, { value: controlsRef, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
7301
7475
  PanoContextMenuOverlayContext.Provider,
7302
7476
  {
7303
7477
  value: contextMenuOverlayApi,
@@ -7353,7 +7527,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7353
7527
  }
7354
7528
  ) }) }) })
7355
7529
  }
7356
- ) }) }) }) })
7530
+ ) }) }) }) }) })
7357
7531
  ]
7358
7532
  }
7359
7533
  ) })
@@ -7396,7 +7570,7 @@ var PanoViewer = (0, import_react25.forwardRef)(
7396
7570
  );
7397
7571
 
7398
7572
  // src/background-audio.tsx
7399
- var import_react26 = require("react");
7573
+ var import_react27 = require("react");
7400
7574
 
7401
7575
  // src/hotspot/audio-spatial.ts
7402
7576
  var import_three6 = require("three");
@@ -7484,31 +7658,31 @@ function BackgroundAudio({
7484
7658
  onEnded,
7485
7659
  onError
7486
7660
  }) {
7487
- const controlsRef = (0, import_react26.useContext)(PanoramaViewContext);
7661
+ const controlsRef = (0, import_react27.useContext)(PanoramaViewContext);
7488
7662
  if (!controlsRef) {
7489
7663
  throw new Error("<BackgroundAudio> must be rendered inside <PanoViewer>.");
7490
7664
  }
7491
7665
  const isControlled = controlledPlaying !== void 0;
7492
- const [internalPlaying, setInternalPlaying] = (0, import_react26.useState)(defaultPlaying);
7666
+ const [internalPlaying, setInternalPlaying] = (0, import_react27.useState)(defaultPlaying);
7493
7667
  const playing = isControlled ? controlledPlaying : internalPlaying;
7494
7668
  const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
7495
7669
  usePanoMediaActivationIntent(playing && urls.length > 0);
7496
7670
  const trackKey = urls.join("\0");
7497
- const currentRef = (0, import_react26.useRef)(null);
7498
- const outgoingRef = (0, import_react26.useRef)([]);
7499
- const fadingInRef = (0, import_react26.useRef)(false);
7500
- const isFirstTrackRef = (0, import_react26.useRef)(true);
7501
- const playingRef = (0, import_react26.useRef)(playing);
7502
- const loopRef = (0, import_react26.useRef)(loop);
7503
- const mutedRef = (0, import_react26.useRef)(muted);
7504
- const volumeRef = (0, import_react26.useRef)(volume);
7505
- const mutedPropRef = (0, import_react26.useRef)(muted);
7506
- const volumePropRef = (0, import_react26.useRef)(volume);
7507
- const fadeMsRef = (0, import_react26.useRef)(resolveFadeMs(fadeMs));
7508
- const onPlaybackStateChangeRef = (0, import_react26.useRef)(onPlaybackStateChange);
7509
- const onPlaybackErrorRef = (0, import_react26.useRef)(onPlaybackError);
7510
- const onEndedRef = (0, import_react26.useRef)(onEnded);
7511
- const onErrorRef = (0, import_react26.useRef)(onError);
7671
+ const currentRef = (0, import_react27.useRef)(null);
7672
+ const outgoingRef = (0, import_react27.useRef)([]);
7673
+ const fadingInRef = (0, import_react27.useRef)(false);
7674
+ const isFirstTrackRef = (0, import_react27.useRef)(true);
7675
+ const playingRef = (0, import_react27.useRef)(playing);
7676
+ const loopRef = (0, import_react27.useRef)(loop);
7677
+ const mutedRef = (0, import_react27.useRef)(muted);
7678
+ const volumeRef = (0, import_react27.useRef)(volume);
7679
+ const mutedPropRef = (0, import_react27.useRef)(muted);
7680
+ const volumePropRef = (0, import_react27.useRef)(volume);
7681
+ const fadeMsRef = (0, import_react27.useRef)(resolveFadeMs(fadeMs));
7682
+ const onPlaybackStateChangeRef = (0, import_react27.useRef)(onPlaybackStateChange);
7683
+ const onPlaybackErrorRef = (0, import_react27.useRef)(onPlaybackError);
7684
+ const onEndedRef = (0, import_react27.useRef)(onEnded);
7685
+ const onErrorRef = (0, import_react27.useRef)(onError);
7512
7686
  playingRef.current = playing;
7513
7687
  loopRef.current = loop;
7514
7688
  fadeMsRef.current = resolveFadeMs(fadeMs);
@@ -7524,7 +7698,7 @@ function BackgroundAudio({
7524
7698
  onPlaybackErrorRef.current = onPlaybackError;
7525
7699
  onEndedRef.current = onEnded;
7526
7700
  onErrorRef.current = onError;
7527
- const snapshotRef = (0, import_react26.useRef)({
7701
+ const snapshotRef = (0, import_react27.useRef)({
7528
7702
  ready: false,
7529
7703
  playing: false,
7530
7704
  blocked: false,
@@ -7532,7 +7706,7 @@ function BackgroundAudio({
7532
7706
  muted,
7533
7707
  volume
7534
7708
  });
7535
- const snapshotListenersRef = (0, import_react26.useRef)(/* @__PURE__ */ new Set());
7709
+ const snapshotListenersRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
7536
7710
  const notifySnapshot = (patch) => {
7537
7711
  const prev = snapshotRef.current;
7538
7712
  snapshotRef.current = { ...prev, ...patch };
@@ -7540,9 +7714,9 @@ function BackgroundAudio({
7540
7714
  listener();
7541
7715
  }
7542
7716
  };
7543
- const isControlledRef = (0, import_react26.useRef)(isControlled);
7717
+ const isControlledRef = (0, import_react27.useRef)(isControlled);
7544
7718
  isControlledRef.current = isControlled;
7545
- const controller = (0, import_react26.useMemo)(
7719
+ const controller = (0, import_react27.useMemo)(
7546
7720
  () => ({
7547
7721
  subscribe: (onStoreChange) => {
7548
7722
  snapshotListenersRef.current.add(onStoreChange);
@@ -7600,8 +7774,8 @@ function BackgroundAudio({
7600
7774
  }),
7601
7775
  []
7602
7776
  );
7603
- const bgmHost = (0, import_react26.useContext)(BackgroundAudioHostContext);
7604
- (0, import_react26.useEffect)(() => {
7777
+ const bgmHost = (0, import_react27.useContext)(BackgroundAudioHostContext);
7778
+ (0, import_react27.useEffect)(() => {
7605
7779
  if (!bgmHost) {
7606
7780
  return;
7607
7781
  }
@@ -7614,7 +7788,7 @@ function BackgroundAudio({
7614
7788
  }
7615
7789
  };
7616
7790
  }, [bgmHost, controller]);
7617
- (0, import_react26.useEffect)(() => {
7791
+ (0, import_react27.useEffect)(() => {
7618
7792
  return () => {
7619
7793
  fadingInRef.current = false;
7620
7794
  isFirstTrackRef.current = true;
@@ -7626,7 +7800,7 @@ function BackgroundAudio({
7626
7800
  outgoingRef.current = [];
7627
7801
  };
7628
7802
  }, []);
7629
- (0, import_react26.useEffect)(() => {
7803
+ (0, import_react27.useEffect)(() => {
7630
7804
  const previous = currentRef.current;
7631
7805
  if (previous?.key === trackKey && previous.crossOrigin === crossOrigin) {
7632
7806
  return;
@@ -7729,7 +7903,7 @@ function BackgroundAudio({
7729
7903
  retire(previous);
7730
7904
  }
7731
7905
  }, [crossOrigin, trackKey]);
7732
- (0, import_react26.useEffect)(() => {
7906
+ (0, import_react27.useEffect)(() => {
7733
7907
  const howl = currentRef.current?.handle.howl;
7734
7908
  if (!howl) {
7735
7909
  return;
@@ -7749,7 +7923,7 @@ function BackgroundAudio({
7749
7923
  howl.play();
7750
7924
  }
7751
7925
  }, [playing, trackKey]);
7752
- (0, import_react26.useEffect)(() => {
7926
+ (0, import_react27.useEffect)(() => {
7753
7927
  const slot = currentRef.current;
7754
7928
  if (!slot) {
7755
7929
  return;
@@ -7764,7 +7938,7 @@ function BackgroundAudio({
7764
7938
  volume: clampAudioVolume(volumeRef.current)
7765
7939
  });
7766
7940
  }, [loop, muted, trackKey, volume]);
7767
- (0, import_react26.useEffect)(() => {
7941
+ (0, import_react27.useEffect)(() => {
7768
7942
  if (!pauseWhenHidden) {
7769
7943
  return;
7770
7944
  }
@@ -7790,27 +7964,27 @@ function BackgroundAudio({
7790
7964
  }
7791
7965
 
7792
7966
  // src/pano-filter/pano-filter.tsx
7793
- var import_react27 = require("react");
7967
+ var import_react28 = require("react");
7794
7968
  function PanoFilter({
7795
7969
  preset = "none",
7796
7970
  intensity,
7797
7971
  enabled = true
7798
7972
  }) {
7799
- const host = (0, import_react27.useContext)(PanoFilterHostContext);
7973
+ const host = (0, import_react28.useContext)(PanoFilterHostContext);
7800
7974
  if (!host) {
7801
7975
  throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
7802
7976
  }
7803
- const snapshot = (0, import_react27.useMemo)(
7977
+ const snapshot = (0, import_react28.useMemo)(
7804
7978
  () => resolvePanoFilterSnapshot({ preset, intensity, enabled }),
7805
7979
  [enabled, intensity, preset]
7806
7980
  );
7807
- (0, import_react27.useEffect)(() => {
7981
+ (0, import_react28.useEffect)(() => {
7808
7982
  claimPanoFilter(host);
7809
7983
  return () => {
7810
7984
  releasePanoFilter(host);
7811
7985
  };
7812
7986
  }, [host]);
7813
- (0, import_react27.useEffect)(() => {
7987
+ (0, import_react28.useEffect)(() => {
7814
7988
  setPanoFilterSnapshot(host, snapshot);
7815
7989
  }, [host, snapshot]);
7816
7990
  return null;
@@ -7818,7 +7992,7 @@ function PanoFilter({
7818
7992
 
7819
7993
  // src/gyro.tsx
7820
7994
  var import_fiber11 = require("@react-three/fiber");
7821
- var import_react28 = require("react");
7995
+ var import_react29 = require("react");
7822
7996
 
7823
7997
  // src/gyro-orientation.ts
7824
7998
  var import_three7 = require("three");
@@ -7903,7 +8077,7 @@ function resolveSoftstart(value) {
7903
8077
  function posesNearlyEqual(a, b) {
7904
8078
  return Math.abs(shortestYawDelta2(a.yaw, b.yaw)) < 1e-4 && Math.abs(a.pitch - b.pitch) < 1e-4 && Math.abs(a.roll - b.roll) < 1e-4;
7905
8079
  }
7906
- var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8080
+ var Gyro = (0, import_react29.forwardRef)(function Gyro2({
7907
8081
  enabled = false,
7908
8082
  camroll = true,
7909
8083
  absolute = false,
@@ -7918,24 +8092,24 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
7918
8092
  onDisable,
7919
8093
  onDenied
7920
8094
  }, ref) {
7921
- const controlsRef = (0, import_react28.useContext)(PanoramaViewContext);
7922
- const eventBus = (0, import_react28.useContext)(PanoEventBusContext);
8095
+ const controlsRef = (0, import_react29.useContext)(PanoramaViewContext);
8096
+ const eventBus = (0, import_react29.useContext)(PanoEventBusContext);
7923
8097
  const { gl } = (0, import_fiber11.useThree)();
7924
- const [internallyDisabled, setInternallyDisabled] = (0, import_react28.useState)(false);
7925
- const availableRef = (0, import_react28.useRef)(false);
7926
- const availabilityReportedRef = (0, import_react28.useRef)(null);
7927
- const activeRef = (0, import_react28.useRef)(false);
7928
- const permissionRef = (0, import_react28.useRef)(deviceOrientationPermissionState);
7929
- const absoluteEventSourceRef = (0, import_react28.useRef)(null);
7930
- const rawQuaternionRef = (0, import_react28.useRef)(null);
7931
- const calibrationRef = (0, import_react28.useRef)(null);
7932
- const absoluteOffsetRef = (0, import_react28.useRef)({ yaw: 0, pitch: 0 });
7933
- const screenAngleRef = (0, import_react28.useRef)(getScreenOrientationAngle());
7934
- const startPoseRef = (0, import_react28.useRef)(null);
7935
- const enabledAtRef = (0, import_react28.useRef)(0);
7936
- const filteredPoseRef = (0, import_react28.useRef)(null);
7937
- const lastAppliedPoseRef = (0, import_react28.useRef)(null);
7938
- const callbacksRef = (0, import_react28.useRef)({
8098
+ const [internallyDisabled, setInternallyDisabled] = (0, import_react29.useState)(false);
8099
+ const availableRef = (0, import_react29.useRef)(false);
8100
+ const availabilityReportedRef = (0, import_react29.useRef)(null);
8101
+ const activeRef = (0, import_react29.useRef)(false);
8102
+ const permissionRef = (0, import_react29.useRef)(deviceOrientationPermissionState);
8103
+ const absoluteEventSourceRef = (0, import_react29.useRef)(null);
8104
+ const rawQuaternionRef = (0, import_react29.useRef)(null);
8105
+ const calibrationRef = (0, import_react29.useRef)(null);
8106
+ const absoluteOffsetRef = (0, import_react29.useRef)({ yaw: 0, pitch: 0 });
8107
+ const screenAngleRef = (0, import_react29.useRef)(getScreenOrientationAngle());
8108
+ const startPoseRef = (0, import_react29.useRef)(null);
8109
+ const enabledAtRef = (0, import_react29.useRef)(0);
8110
+ const filteredPoseRef = (0, import_react29.useRef)(null);
8111
+ const lastAppliedPoseRef = (0, import_react29.useRef)(null);
8112
+ const callbacksRef = (0, import_react29.useRef)({
7939
8113
  onAvailable,
7940
8114
  onUnavailable,
7941
8115
  onEnable,
@@ -7952,7 +8126,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
7952
8126
  if (!controlsRef) {
7953
8127
  throw new Error("<Gyro> must be rendered inside <PanoViewer>.");
7954
8128
  }
7955
- const emit = (0, import_react28.useCallback)(
8129
+ const emit = (0, import_react29.useCallback)(
7956
8130
  (type) => {
7957
8131
  eventBus?.emit(type, void 0);
7958
8132
  switch (type) {
@@ -7979,7 +8153,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
7979
8153
  },
7980
8154
  [eventBus]
7981
8155
  );
7982
- const setAvailable = (0, import_react28.useCallback)(
8156
+ const setAvailable = (0, import_react29.useCallback)(
7983
8157
  (available) => {
7984
8158
  availableRef.current = available;
7985
8159
  if (availabilityReportedRef.current === available) {
@@ -7990,7 +8164,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
7990
8164
  },
7991
8165
  [emit]
7992
8166
  );
7993
- const requestPermission = (0, import_react28.useCallback)(async () => {
8167
+ const requestPermission = (0, import_react29.useCallback)(async () => {
7994
8168
  if (!availableRef.current) {
7995
8169
  return false;
7996
8170
  }
@@ -8023,7 +8197,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8023
8197
  emit("gyrodenied");
8024
8198
  return false;
8025
8199
  }, [emit, setAvailable]);
8026
- const deactivate = (0, import_react28.useCallback)(() => {
8200
+ const deactivate = (0, import_react29.useCallback)(() => {
8027
8201
  if (activeRef.current) {
8028
8202
  activeRef.current = false;
8029
8203
  controlsRef.current?.setGyroActive(false);
@@ -8035,7 +8209,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8035
8209
  filteredPoseRef.current = null;
8036
8210
  lastAppliedPoseRef.current = null;
8037
8211
  }, [controlsRef, emit]);
8038
- const resetSensor = (0, import_react28.useCallback)(
8212
+ const resetSensor = (0, import_react29.useCallback)(
8039
8213
  (yaw, pitch) => {
8040
8214
  const rawQuaternion = rawQuaternionRef.current;
8041
8215
  if (!rawQuaternion) {
@@ -8070,7 +8244,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8070
8244
  },
8071
8245
  [absolute, controlsRef, north]
8072
8246
  );
8073
- (0, import_react28.useImperativeHandle)(
8247
+ (0, import_react29.useImperativeHandle)(
8074
8248
  ref,
8075
8249
  () => ({
8076
8250
  resetSensor,
@@ -8080,22 +8254,22 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8080
8254
  }),
8081
8255
  [requestPermission, resetSensor]
8082
8256
  );
8083
- (0, import_react28.useEffect)(() => {
8257
+ (0, import_react29.useEffect)(() => {
8084
8258
  if (!enabled) {
8085
8259
  setInternallyDisabled(false);
8086
8260
  }
8087
8261
  }, [enabled]);
8088
- (0, import_react28.useEffect)(() => {
8262
+ (0, import_react29.useEffect)(() => {
8089
8263
  const supported = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined" && (desktopSupport || isMobileDevice());
8090
8264
  setAvailable(supported);
8091
8265
  return () => {
8092
8266
  availableRef.current = false;
8093
8267
  };
8094
8268
  }, [desktopSupport, setAvailable]);
8095
- (0, import_react28.useEffect)(() => {
8269
+ (0, import_react29.useEffect)(() => {
8096
8270
  controlsRef.current?.setGyroTouchMode(touchMode);
8097
8271
  }, [controlsRef, touchMode]);
8098
- (0, import_react28.useEffect)(() => {
8272
+ (0, import_react29.useEffect)(() => {
8099
8273
  if (!enabled || internallyDisabled || touchMode !== "disablegyro") {
8100
8274
  return;
8101
8275
  }
@@ -8109,7 +8283,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8109
8283
  gl.domElement.removeEventListener("pointerdown", onPointerDown);
8110
8284
  };
8111
8285
  }, [enabled, gl, internallyDisabled, touchMode]);
8112
- (0, import_react28.useEffect)(() => {
8286
+ (0, import_react29.useEffect)(() => {
8113
8287
  if (!enabled || internallyDisabled || !availableRef.current) {
8114
8288
  deactivate();
8115
8289
  return;
@@ -8271,7 +8445,7 @@ var Gyro = (0, import_react28.forwardRef)(function Gyro2({
8271
8445
 
8272
8446
  // src/webvr/webvr.tsx
8273
8447
  var import_fiber14 = require("@react-three/fiber");
8274
- var import_react33 = require("react");
8448
+ var import_react34 = require("react");
8275
8449
 
8276
8450
  // src/webvr/detect.ts
8277
8451
  function isMobileVRDevice() {
@@ -8294,7 +8468,7 @@ async function detectWebVRCapabilities() {
8294
8468
 
8295
8469
  // src/webvr/reticle.tsx
8296
8470
  var import_fiber12 = require("@react-three/fiber");
8297
- var import_react29 = require("react");
8471
+ var import_react30 = require("react");
8298
8472
  var import_three8 = require("three");
8299
8473
  var import_jsx_runtime13 = require("react/jsx-runtime");
8300
8474
  var CENTER_NDC = new import_three8.Vector2(0, 0);
@@ -8380,13 +8554,13 @@ function WebVRReticle({
8380
8554
  dwellMs,
8381
8555
  visible
8382
8556
  }) {
8383
- const groupRef = (0, import_react29.useRef)(null);
8384
- const ringMeshRef = (0, import_react29.useRef)(null);
8385
- const directionRef = (0, import_react29.useRef)(new import_three8.Vector3());
8386
- const raycasterRef = (0, import_react29.useRef)(new import_three8.Raycaster());
8387
- const hoveredRef = (0, import_react29.useRef)(null);
8388
- const dwellRef = (0, import_react29.useRef)(0);
8389
- const clickedRef = (0, import_react29.useRef)(false);
8557
+ const groupRef = (0, import_react30.useRef)(null);
8558
+ const ringMeshRef = (0, import_react30.useRef)(null);
8559
+ const directionRef = (0, import_react30.useRef)(new import_three8.Vector3());
8560
+ const raycasterRef = (0, import_react30.useRef)(new import_three8.Raycaster());
8561
+ const hoveredRef = (0, import_react30.useRef)(null);
8562
+ const dwellRef = (0, import_react30.useRef)(0);
8563
+ const clickedRef = (0, import_react30.useRef)(false);
8390
8564
  const { camera, gl, scene } = (0, import_fiber12.useThree)();
8391
8565
  (0, import_fiber12.useFrame)((_, deltaSeconds) => {
8392
8566
  const group = groupRef.current;
@@ -8549,7 +8723,7 @@ function WebVRReticle({
8549
8723
 
8550
8724
  // src/webvr/stereo.tsx
8551
8725
  var import_fiber13 = require("@react-three/fiber");
8552
- var import_react30 = require("react");
8726
+ var import_react31 = require("react");
8553
8727
  var import_three9 = require("three");
8554
8728
  var vertexShader = `
8555
8729
  varying vec2 vUv;
@@ -8624,25 +8798,25 @@ function WebVRStereoRenderer({
8624
8798
  screensize
8625
8799
  }) {
8626
8800
  const { camera, gl } = (0, import_fiber13.useThree)();
8627
- const runtime = (0, import_react30.useContext)(WebVRRuntimeContext);
8628
- const fallbackStereoRef = (0, import_react30.useRef)(null);
8801
+ const runtime = (0, import_react31.useContext)(WebVRRuntimeContext);
8802
+ const fallbackStereoRef = (0, import_react31.useRef)(null);
8629
8803
  if (!fallbackStereoRef.current) {
8630
8804
  fallbackStereoRef.current = new import_three9.StereoCamera();
8631
8805
  }
8632
8806
  const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
8633
- const stereoRef = (0, import_react30.useRef)(stereo);
8807
+ const stereoRef = (0, import_react31.useRef)(stereo);
8634
8808
  stereoRef.current = stereo;
8635
- const resources = (0, import_react30.useMemo)(createDistortionResources, []);
8636
- const drawingSizeRef = (0, import_react30.useRef)(new import_three9.Vector2());
8637
- const viewportRef = (0, import_react30.useRef)(new import_three9.Vector4());
8638
- const scissorRef = (0, import_react30.useRef)(new import_three9.Vector4());
8639
- const originalFovRef = (0, import_react30.useRef)(null);
8640
- const stereoActiveRef = (0, import_react30.useRef)(false);
8641
- const profileRef = (0, import_react30.useRef)(profile);
8642
- const screensizeRef = (0, import_react30.useRef)(screensize);
8809
+ const resources = (0, import_react31.useMemo)(createDistortionResources, []);
8810
+ const drawingSizeRef = (0, import_react31.useRef)(new import_three9.Vector2());
8811
+ const viewportRef = (0, import_react31.useRef)(new import_three9.Vector4());
8812
+ const scissorRef = (0, import_react31.useRef)(new import_three9.Vector4());
8813
+ const originalFovRef = (0, import_react31.useRef)(null);
8814
+ const stereoActiveRef = (0, import_react31.useRef)(false);
8815
+ const profileRef = (0, import_react31.useRef)(profile);
8816
+ const screensizeRef = (0, import_react31.useRef)(screensize);
8643
8817
  profileRef.current = profile;
8644
8818
  screensizeRef.current = screensize;
8645
- (0, import_react30.useEffect)(
8819
+ (0, import_react31.useEffect)(
8646
8820
  () => () => {
8647
8821
  resources.geometry.dispose();
8648
8822
  resources.material.dispose();
@@ -8650,7 +8824,7 @@ function WebVRStereoRenderer({
8650
8824
  },
8651
8825
  [resources]
8652
8826
  );
8653
- (0, import_react30.useEffect)(() => {
8827
+ (0, import_react31.useEffect)(() => {
8654
8828
  const originalRender = gl.render.bind(gl);
8655
8829
  gl.render = (sceneToRender, cameraToRender) => {
8656
8830
  if (!stereoActiveRef.current || !(cameraToRender instanceof import_three9.PerspectiveCamera)) {
@@ -8714,7 +8888,7 @@ function WebVRStereoRenderer({
8714
8888
  gl.render = originalRender;
8715
8889
  };
8716
8890
  }, [gl, resources]);
8717
- (0, import_react30.useEffect)(
8891
+ (0, import_react31.useEffect)(
8718
8892
  () => () => {
8719
8893
  if (runtime) {
8720
8894
  runtime.stereoView.active = false;
@@ -8749,7 +8923,7 @@ function WebVRStereoRenderer({
8749
8923
  }
8750
8924
 
8751
8925
  // src/webvr/pointerlock.ts
8752
- var import_react31 = require("react");
8926
+ var import_react32 = require("react");
8753
8927
  var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
8754
8928
  async function requestWebVRPointerLock(element) {
8755
8929
  if (typeof document === "undefined") {
@@ -8782,11 +8956,11 @@ function exitWebVRPointerLock(element) {
8782
8956
  }
8783
8957
  function useWebVRPointerLock(enabled, element) {
8784
8958
  const cursor = usePanoCursor();
8785
- const cursorRef = (0, import_react31.useRef)(cursor);
8786
- const enabledRef = (0, import_react31.useRef)(enabled);
8959
+ const cursorRef = (0, import_react32.useRef)(cursor);
8960
+ const enabledRef = (0, import_react32.useRef)(enabled);
8787
8961
  cursorRef.current = cursor;
8788
8962
  enabledRef.current = enabled;
8789
- (0, import_react31.useEffect)(() => {
8963
+ (0, import_react32.useEffect)(() => {
8790
8964
  if (!enabled || !element) {
8791
8965
  return;
8792
8966
  }
@@ -8816,7 +8990,7 @@ function useWebVRPointerLock(enabled, element) {
8816
8990
  }
8817
8991
 
8818
8992
  // src/webvr/wakelock.ts
8819
- var import_react32 = require("react");
8993
+ var import_react33 = require("react");
8820
8994
 
8821
8995
  // src/webvr/wakelock-fallback.ts
8822
8996
  var WEBVR_WAKELOCK_FALLBACK_VIDEO_BASE64 = "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAbBbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAD4AAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAxt0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAAggAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAABAAAAAQAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAIIAAAEAAABAAAAAAKTbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAyAAAAGgBVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACPm1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAf5zdGJsAAAAvnN0c2QAAAAAAAAAAQAAAK5hdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAABAAEABIAAAASAAAAAAAAAABFUxhdmM2Mi4xMS4xMDAgbGlieDI2NAAAAAAAAAAAAAAAGP//AAAANGF2Y0MBZAAK/+EAF2dkAAqs2V7ARAAAAwAEAAADAMg8SJZYAQAGaOvjyyLA/fj4AAAAABBwYXNwAAAAAQAAAAEAAAAUYnRydAAAAAAAADQ5AAAAAAAAABhzdHRzAAAAAAAAAAEAAAANAAACAAAAABRzdHNzAAAAAAAAAAEAAAABAAAAeGN0dHMAAAAAAAAADQAAAAEAAAQAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAKHN0c2MAAAAAAAAAAgAAAAEAAAADAAAAAQAAAAUAAAABAAAAAQAAAEhzdHN6AAAAAAAAAAAAAAANAAACxQAAAAwAAAAMAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAACRzdGNvAAAAAAAAAAUAAAcGAAAJ5wAAChUAAAo/AAAKbwAAAtF0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAACAAAAAAAAD4AAAAAAAAAAAAAAAAEBAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAA+AAAAEAAABAAAAAAJJbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAfQAAAgABVxAAAAAAALWhkbHIAAAAAAAAAAHNvdW4AAAAAAAAAAAAAAABTb3VuZEhhbmRsZXIAAAAB9G1pbmYAAAAQc21oZAAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAABuHN0YmwAAAB+c3RzZAAAAAAAAAABAAAAbm1wNGEAAAAAAAAAAQAAAAAAAAAAAAEAEAAAAAAfQAAAAAAANmVzZHMAAAAAA4CAgCUAAgAEgICAF0AVAAAAAAAfQAAAARsFgICABRWIVuUABoCAgAECAAAAFGJ0cnQAAAAAAAAfQAAAARsAAAAYc3R0cwAAAAAAAAABAAAAIAAABAAAAAAoc3RzYwAAAAAAAAACAAAAAQAAAAEAAAABAAAABgAAABsAAAABAAAAlHN0c3oAAAAAAAAAAAAAACAAAAAVAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAChzdGNvAAAAAAAAAAYAAAbxAAAJ4wAAChEAAAo7AAAKawAACnsAAAAac2dwZAEAAAByb2xsAAAAAgAAAAH//wAAABxzYmdwAAAAAHJvbGwAAAABAAAAIAAAAAEAAABhdWR0YQAAAFltZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAACxpbHN0AAAAJKl0b28AAAAcZGF0YQAAAAEAAAAATGF2ZjYyLjMuMTAwAAAACGZyZWUAAAP+bWRhdN4CAExhdmM2Mi4xMS4xMDAAAjBADgAAAq4GBf//qtxF6b3m2Ui3lizYINkj7u94MjY0IC0gY29yZSAxNjUgcjMyMjIgYjM1NjA1YSAtIEguMjY0L01QRUctNCBBVkMgY29kZWMgLSBDb3B5bGVmdCAyMDAzLTIwMjUgLSBodHRwOi8vd3d3LnZpZGVvbGFuLm9yZy94MjY0Lmh0bWwgLSBvcHRpb25zOiBjYWJhYz0xIHJlZj0zIGRlYmxvY2s9MTowOjAgYW5hbHlzZT0weDM6MHgxMTMgbWU9aGV4IHN1Ym1lPTcgcHN5PTEgcHN5X3JkPTEuMDA6MC4wMCBtaXhlZF9yZWY9MSBtZV9yYW5nZT0xNiBjaHJvbWFfbWU9MSB0cmVsbGlzPTEgOHg4ZGN0PTEgY3FtPTAgZGVhZHpvbmU9MjEsMTEgZmFzdF9wc2tpcD0xIGNocm9tYV9xcF9vZmZzZXQ9LTIgdGhyZWFkcz0xIGxvb2thaGVhZF90aHJlYWRzPTEgc2xpY2VkX3RocmVhZHM9MCBucj0wIGRlY2ltYXRlPTEgaW50ZXJsYWNlZD0wIGJsdXJheV9jb21wYXQ9MCBjb25zdHJhaW5lZF9pbnRyYT0wIGJmcmFtZXM9MyBiX3B5cmFtaWQ9MiBiX2FkYXB0PTEgYl9iaWFzPTAgZGlyZWN0PTEgd2VpZ2h0Yj0xIG9wZW5fZ29wPTAgd2VpZ2h0cD0yIGtleWludD0yNTAga2V5aW50X21pbj0yNSBzY2VuZWN1dD00MCBpbnRyYV9yZWZyZXNoPTAgcmNfbG9va2FoZWFkPTQwIHJjPWNyZiBtYnRyZWU9MSBjcmY9MjMuMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAAA9liIQAO//+906/AptUwmEAAAAIQZokbEN//uAAAAAIQZ5CeIX/wYEBGCAHAAAACAGeYXRCv8SAAAAACAGeY2pCv8SBAAAADkGaaEmoQWiZTAhn//7hARggBwAAAApBnoZFESwv/8GBAAAACAGepXRCv8SBAAAACAGep2pCv8SAARggBwAAAA5BmqxJqEFsmUwIV//+wAAAAApBnspFFSwv/8GBAAAACAGe6XRCv8SAARggBwAAAAgBnutqQr/EgAEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBwEYIAcBGCAHARggBw==";
@@ -8950,7 +9124,7 @@ function releaseWebVRWakeLock() {
8950
9124
  stopFallbackVideo();
8951
9125
  }
8952
9126
  function useWebVRWakeLock(enabled) {
8953
- (0, import_react32.useEffect)(() => {
9127
+ (0, import_react33.useEffect)(() => {
8954
9128
  if (!enabled) {
8955
9129
  return;
8956
9130
  }
@@ -8980,7 +9154,7 @@ function initializeSettings(screensize, profile) {
8980
9154
  function getViewerElement(canvas) {
8981
9155
  return canvas.closest("[data-pano-viewer]") ?? canvas.parentElement ?? canvas;
8982
9156
  }
8983
- var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9157
+ var WebVR = (0, import_react34.forwardRef)(function WebVR2({
8984
9158
  chrome = true,
8985
9159
  mobileVr = true,
8986
9160
  desktopSupport = false,
@@ -8998,24 +9172,24 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
8998
9172
  onDenied,
8999
9173
  onUnknownDevice
9000
9174
  }, ref) {
9001
- const runtime = (0, import_react33.useContext)(WebVRRuntimeContext);
9002
- const controlsRef = (0, import_react33.useContext)(PanoramaViewContext);
9003
- const eventBus = (0, import_react33.useContext)(PanoEventBusContext);
9175
+ const runtime = (0, import_react34.useContext)(WebVRRuntimeContext);
9176
+ const controlsRef = (0, import_react34.useContext)(PanoramaViewContext);
9177
+ const eventBus = (0, import_react34.useContext)(PanoEventBusContext);
9004
9178
  const gl = (0, import_fiber14.useThree)((state) => state.gl);
9005
- const gyroRef = (0, import_react33.useRef)(null);
9006
- const capabilitiesRef = (0, import_react33.useRef)({
9179
+ const gyroRef = (0, import_react34.useRef)(null);
9180
+ const capabilitiesRef = (0, import_react34.useRef)({
9007
9181
  mobile: false,
9008
9182
  sensor: false,
9009
9183
  webxr: false
9010
9184
  });
9011
- const availableRef = (0, import_react33.useRef)(false);
9012
- const modeRef = (0, import_react33.useRef)(null);
9013
- const webXRSessionRef = (0, import_react33.useRef)(null);
9014
- const [mode, setMode] = (0, import_react33.useState)(null);
9015
- const [settings, setSettings] = (0, import_react33.useState)(
9185
+ const availableRef = (0, import_react34.useRef)(false);
9186
+ const modeRef = (0, import_react34.useRef)(null);
9187
+ const webXRSessionRef = (0, import_react34.useRef)(null);
9188
+ const [mode, setMode] = (0, import_react34.useState)(null);
9189
+ const [settings, setSettings] = (0, import_react34.useState)(
9016
9190
  () => initializeSettings(screensize, profile)
9017
9191
  );
9018
- const callbacksRef = (0, import_react33.useRef)({
9192
+ const callbacksRef = (0, import_react34.useRef)({
9019
9193
  onAvailable,
9020
9194
  onDenied,
9021
9195
  onEnterVR,
@@ -9035,22 +9209,22 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9035
9209
  throw new Error("<WebVR> must be rendered inside <PanoViewer>.");
9036
9210
  }
9037
9211
  const { host, xrStore } = runtime;
9038
- const resolvedProfile = (0, import_react33.useMemo)(
9212
+ const resolvedProfile = (0, import_react34.useMemo)(
9039
9213
  () => resolveWebVRProfile(profile, settings.profileId),
9040
9214
  [profile, settings.profileId]
9041
9215
  );
9042
- const reportDenied = (0, import_react33.useCallback)(
9216
+ const reportDenied = (0, import_react34.useCallback)(
9043
9217
  (error) => {
9044
9218
  eventBus.emit("vrdenied", { error });
9045
9219
  callbacksRef.current.onDenied?.(error);
9046
9220
  },
9047
9221
  [eventBus]
9048
9222
  );
9049
- const reportUnknownDevice = (0, import_react33.useCallback)(() => {
9223
+ const reportUnknownDevice = (0, import_react34.useCallback)(() => {
9050
9224
  eventBus.emit("vrunknowndevice", void 0);
9051
9225
  callbacksRef.current.onUnknownDevice?.();
9052
9226
  }, [eventBus]);
9053
- const activate = (0, import_react33.useCallback)(
9227
+ const activate = (0, import_react34.useCallback)(
9054
9228
  (nextMode) => {
9055
9229
  if (modeRef.current === nextMode) {
9056
9230
  return;
@@ -9065,7 +9239,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9065
9239
  },
9066
9240
  [controlsRef, eventBus]
9067
9241
  );
9068
- const deactivate = (0, import_react33.useCallback)(
9242
+ const deactivate = (0, import_react34.useCallback)(
9069
9243
  (expectedMode) => {
9070
9244
  const previousMode = modeRef.current;
9071
9245
  if (!previousMode || expectedMode && previousMode !== expectedMode) {
@@ -9082,10 +9256,10 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9082
9256
  },
9083
9257
  [controlsRef, eventBus, gl.domElement]
9084
9258
  );
9085
- const requestPermission = (0, import_react33.useCallback)(async () => {
9259
+ const requestPermission = (0, import_react34.useCallback)(async () => {
9086
9260
  return await gyroRef.current?.requestPermission() ?? false;
9087
9261
  }, []);
9088
- const enterVR = (0, import_react33.useCallback)(async () => {
9262
+ const enterVR = (0, import_react34.useCallback)(async () => {
9089
9263
  if (modeRef.current) {
9090
9264
  return true;
9091
9265
  }
@@ -9170,7 +9344,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9170
9344
  wakelock,
9171
9345
  xrStore
9172
9346
  ]);
9173
- const exitVR = (0, import_react33.useCallback)(async () => {
9347
+ const exitVR = (0, import_react34.useCallback)(async () => {
9174
9348
  if (modeRef.current === "webxr") {
9175
9349
  const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
9176
9350
  if (session2) {
@@ -9185,14 +9359,14 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9185
9359
  await exitElementFullscreen();
9186
9360
  }
9187
9361
  }, [deactivate, xrStore]);
9188
- const toggleVR = (0, import_react33.useCallback)(async () => {
9362
+ const toggleVR = (0, import_react34.useCallback)(async () => {
9189
9363
  if (modeRef.current) {
9190
9364
  await exitVR();
9191
9365
  return false;
9192
9366
  }
9193
9367
  return enterVR();
9194
9368
  }, [enterVR, exitVR]);
9195
- const updateSettings = (0, import_react33.useCallback)((next) => {
9369
+ const updateSettings = (0, import_react34.useCallback)((next) => {
9196
9370
  const normalized = {
9197
9371
  profileId: next.profileId,
9198
9372
  screensize: next.screensize === "auto" ? "auto" : Math.round(Math.max(3, Math.min(20, next.screensize)) * 10) / 10
@@ -9200,7 +9374,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9200
9374
  setSettings(normalized);
9201
9375
  saveWebVRSettings(normalized);
9202
9376
  }, []);
9203
- const controller = (0, import_react33.useMemo)(
9377
+ const controller = (0, import_react34.useMemo)(
9204
9378
  () => ({
9205
9379
  closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
9206
9380
  enterVR,
@@ -9212,7 +9386,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9212
9386
  }),
9213
9387
  [enterVR, exitVR, host, requestPermission, toggleVR, updateSettings]
9214
9388
  );
9215
- (0, import_react33.useImperativeHandle)(
9389
+ (0, import_react34.useImperativeHandle)(
9216
9390
  ref,
9217
9391
  () => ({
9218
9392
  enterVR,
@@ -9225,7 +9399,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9225
9399
  }),
9226
9400
  [enterVR, exitVR, requestPermission, toggleVR]
9227
9401
  );
9228
- (0, import_react33.useEffect)(() => {
9402
+ (0, import_react34.useEffect)(() => {
9229
9403
  let active = true;
9230
9404
  void detectWebVRCapabilities().then((capabilities) => {
9231
9405
  if (!active) {
@@ -9247,7 +9421,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9247
9421
  active = false;
9248
9422
  };
9249
9423
  }, [desktopSupport, eventBus, fakeSupport, host, mobileVr]);
9250
- (0, import_react33.useEffect)(() => {
9424
+ (0, import_react34.useEffect)(() => {
9251
9425
  host.controller = controller;
9252
9426
  return () => {
9253
9427
  if (host.controller === controller) {
@@ -9256,10 +9430,10 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9256
9430
  }
9257
9431
  };
9258
9432
  }, [controller, host]);
9259
- (0, import_react33.useEffect)(() => {
9433
+ (0, import_react34.useEffect)(() => {
9260
9434
  updateWebVRHost(host, { chrome, mode, settings });
9261
9435
  }, [chrome, host, mode, settings]);
9262
- (0, import_react33.useEffect)(() => {
9436
+ (0, import_react34.useEffect)(() => {
9263
9437
  if (mode !== "fake") {
9264
9438
  return;
9265
9439
  }
@@ -9283,7 +9457,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9283
9457
  document.removeEventListener("mousemove", onMouseMove);
9284
9458
  };
9285
9459
  }, [controlsRef, gl.domElement, mode, mousePointerLock]);
9286
- (0, import_react33.useEffect)(
9460
+ (0, import_react34.useEffect)(
9287
9461
  () => () => {
9288
9462
  const session2 = webXRSessionRef.current;
9289
9463
  if (session2) {
@@ -9336,7 +9510,7 @@ var WebVR = (0, import_react33.forwardRef)(function WebVR2({
9336
9510
  });
9337
9511
 
9338
9512
  // src/use-pano-viewer.ts
9339
- var import_react34 = require("react");
9513
+ var import_react35 = require("react");
9340
9514
  function createPanoViewerHandle(ref) {
9341
9515
  return {
9342
9516
  getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
@@ -9346,6 +9520,10 @@ function createPanoViewerHandle(ref) {
9346
9520
  reset: () => {
9347
9521
  ref.current?.reset();
9348
9522
  },
9523
+ lookTo: (position, options) => ref.current?.lookTo(position, options) ?? Promise.resolve({ status: "cancelled" }),
9524
+ moveTo: (position, options) => ref.current?.moveTo(position, options) ?? Promise.resolve({ status: "cancelled" }),
9525
+ zoomTo: (fov, options) => ref.current?.zoomTo(fov, options) ?? Promise.resolve({ status: "cancelled" }),
9526
+ lookToHotspot: (id, options) => ref.current?.lookToHotspot(id, options) ?? Promise.resolve({ status: "not-found" }),
9349
9527
  activateMedia: () => ref.current?.activateMedia() ?? Promise.resolve(),
9350
9528
  enterFullscreen: () => ref.current?.enterFullscreen() ?? Promise.resolve(),
9351
9529
  exitFullscreen: () => ref.current?.exitFullscreen() ?? Promise.resolve(),
@@ -9414,14 +9592,14 @@ function createPanoViewerHandle(ref) {
9414
9592
  };
9415
9593
  }
9416
9594
  function usePanoViewer() {
9417
- const ref = (0, import_react34.useRef)(null);
9418
- const handle = (0, import_react34.useMemo)(() => createPanoViewerHandle(ref), []);
9419
- return (0, import_react34.useMemo)(() => ({ ref, ...handle }), [handle]);
9595
+ const ref = (0, import_react35.useRef)(null);
9596
+ const handle = (0, import_react35.useMemo)(() => createPanoViewerHandle(ref), []);
9597
+ return (0, import_react35.useMemo)(() => ({ ref, ...handle }), [handle]);
9420
9598
  }
9421
9599
 
9422
9600
  // src/sphere.tsx
9423
9601
  var import_fiber15 = require("@react-three/fiber");
9424
- var import_react36 = require("react");
9602
+ var import_react37 = require("react");
9425
9603
  var import_three10 = require("three");
9426
9604
 
9427
9605
  // src/asset-url.ts
@@ -9446,7 +9624,7 @@ function resolveUrlAgainstFile(fileUrl, path) {
9446
9624
  }
9447
9625
 
9448
9626
  // src/pano-filter/pano-basic-material.tsx
9449
- var import_react35 = require("react");
9627
+ var import_react36 = require("react");
9450
9628
 
9451
9629
  // src/pano-filter/shaders.ts
9452
9630
  var GLSL_FILTER_COMMON = `
@@ -9606,13 +9784,13 @@ function PanoBasicMaterial({
9606
9784
  toneMapped = false
9607
9785
  }) {
9608
9786
  const snapshot = usePanoFilterSnapshot();
9609
- const materialRef = (0, import_react35.useRef)(null);
9610
- const intensityRef = (0, import_react35.useRef)(snapshot.intensity);
9611
- const intensityUniformRef = (0, import_react35.useRef)(null);
9787
+ const materialRef = (0, import_react36.useRef)(null);
9788
+ const intensityRef = (0, import_react36.useRef)(snapshot.intensity);
9789
+ const intensityUniformRef = (0, import_react36.useRef)(null);
9612
9790
  intensityRef.current = snapshot.intensity;
9613
9791
  const active = isPanoFilterActive(snapshot);
9614
9792
  const preset = snapshot.preset;
9615
- const onBeforeCompile = (0, import_react35.useMemo)(() => {
9793
+ const onBeforeCompile = (0, import_react36.useMemo)(() => {
9616
9794
  if (!active || preset === "none") {
9617
9795
  return void 0;
9618
9796
  }
@@ -9629,7 +9807,7 @@ function PanoBasicMaterial({
9629
9807
  compile.toString = () => `pano-filter:${preset}`;
9630
9808
  return compile;
9631
9809
  }, [active, preset]);
9632
- (0, import_react35.useLayoutEffect)(() => {
9810
+ (0, import_react36.useLayoutEffect)(() => {
9633
9811
  if (!active) {
9634
9812
  intensityUniformRef.current = null;
9635
9813
  }
@@ -9639,7 +9817,7 @@ function PanoBasicMaterial({
9639
9817
  }
9640
9818
  material.needsUpdate = true;
9641
9819
  }, [active, preset]);
9642
- (0, import_react35.useLayoutEffect)(() => {
9820
+ (0, import_react36.useLayoutEffect)(() => {
9643
9821
  if (intensityUniformRef.current) {
9644
9822
  intensityUniformRef.current.value = snapshot.intensity;
9645
9823
  }
@@ -9662,12 +9840,12 @@ function PanoBasicMaterial({
9662
9840
  // src/sphere.tsx
9663
9841
  var import_jsx_runtime16 = require("react/jsx-runtime");
9664
9842
  function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9665
- const [texture, setTexture] = (0, import_react36.useState)(null);
9666
- const onLoadRef = (0, import_react36.useRef)(onLoad);
9667
- const onErrorRef = (0, import_react36.useRef)(onError);
9843
+ const [texture, setTexture] = (0, import_react37.useState)(null);
9844
+ const onLoadRef = (0, import_react37.useRef)(onLoad);
9845
+ const onErrorRef = (0, import_react37.useRef)(onError);
9668
9846
  onLoadRef.current = onLoad;
9669
9847
  onErrorRef.current = onError;
9670
- (0, import_react36.useEffect)(() => {
9848
+ (0, import_react37.useEffect)(() => {
9671
9849
  if (!url) {
9672
9850
  setTexture(null);
9673
9851
  return;
@@ -9706,7 +9884,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9706
9884
  active = false;
9707
9885
  };
9708
9886
  }, [anisotropy, generateMipmaps, url]);
9709
- (0, import_react36.useEffect)(
9887
+ (0, import_react37.useEffect)(
9710
9888
  () => () => {
9711
9889
  texture?.dispose();
9712
9890
  },
@@ -9726,7 +9904,7 @@ function Sphere({
9726
9904
  }) {
9727
9905
  const gl = (0, import_fiber15.useThree)((state) => state.gl);
9728
9906
  const anisotropy = gl.capabilities.getMaxAnisotropy();
9729
- const resolvedPreviewUrl = (0, import_react36.useMemo)(
9907
+ const resolvedPreviewUrl = (0, import_react37.useMemo)(
9730
9908
  () => resolveUrlAgainstFile(src, previewUrl),
9731
9909
  [previewUrl, src]
9732
9910
  );
@@ -9745,11 +9923,11 @@ function Sphere({
9745
9923
  onPreviewError
9746
9924
  );
9747
9925
  const displayTexture = texture ?? previewTexture;
9748
- const readyRef = (0, import_react36.useRef)(false);
9749
- (0, import_react36.useEffect)(() => {
9926
+ const readyRef = (0, import_react37.useRef)(false);
9927
+ (0, import_react37.useEffect)(() => {
9750
9928
  readyRef.current = false;
9751
9929
  }, [resolvedPreviewUrl, src]);
9752
- (0, import_react36.useEffect)(() => {
9930
+ (0, import_react37.useEffect)(() => {
9753
9931
  if (!displayTexture || readyRef.current) {
9754
9932
  return;
9755
9933
  }
@@ -9781,7 +9959,7 @@ function Sphere({
9781
9959
 
9782
9960
  // src/video/pano-video.tsx
9783
9961
  var import_fiber16 = require("@react-three/fiber");
9784
- var import_react37 = require("react");
9962
+ var import_react38 = require("react");
9785
9963
  var import_three11 = require("three");
9786
9964
  var import_jsx_runtime17 = require("react/jsx-runtime");
9787
9965
  var EMPTY_TRACKS = [];
@@ -9868,10 +10046,10 @@ function applyEquirectangularLayout(texture, anisotropy) {
9868
10046
  }
9869
10047
  function usePosterTexture(poster, onError) {
9870
10048
  const gl = (0, import_fiber16.useThree)((state) => state.gl);
9871
- const [texture, setTexture] = (0, import_react37.useState)(null);
9872
- const onErrorRef = (0, import_react37.useRef)(onError);
10049
+ const [texture, setTexture] = (0, import_react38.useState)(null);
10050
+ const onErrorRef = (0, import_react38.useRef)(onError);
9873
10051
  onErrorRef.current = onError;
9874
- (0, import_react37.useEffect)(() => {
10052
+ (0, import_react38.useEffect)(() => {
9875
10053
  let active = true;
9876
10054
  setTexture(null);
9877
10055
  if (!poster) {
@@ -9908,7 +10086,7 @@ function usePosterTexture(poster, onError) {
9908
10086
  active = false;
9909
10087
  };
9910
10088
  }, [gl, poster]);
9911
- (0, import_react37.useEffect)(
10089
+ (0, import_react38.useEffect)(
9912
10090
  () => () => {
9913
10091
  texture?.dispose();
9914
10092
  },
@@ -9967,38 +10145,38 @@ function PanoVideo({
9967
10145
  }) {
9968
10146
  usePanoMediaActivationIntent(autoPlay);
9969
10147
  const gl = (0, import_fiber16.useThree)((state) => state.gl);
9970
- const host = (0, import_react37.useContext)(PanoVideoHostContext);
9971
- const overlay = (0, import_react37.useContext)(PanoChromeOverlayContext);
9972
- const variants = (0, import_react37.useMemo)(
10148
+ const host = (0, import_react38.useContext)(PanoVideoHostContext);
10149
+ const overlay = (0, import_react38.useContext)(PanoChromeOverlayContext);
10150
+ const variants = (0, import_react38.useMemo)(
9973
10151
  () => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
9974
10152
  [poster, src, variantsProp]
9975
10153
  );
9976
10154
  const tracks = tracksProp ?? EMPTY_TRACKS;
9977
10155
  const captionsEnabled = captions !== false;
9978
- const captionAppearance = (0, import_react37.useMemo)(
10156
+ const captionAppearance = (0, import_react38.useMemo)(
9979
10157
  () => resolvePanoVideoCaptionAppearance(
9980
10158
  typeof captions === "object" ? captions : void 0
9981
10159
  ),
9982
10160
  [captions]
9983
10161
  );
9984
- const [variantId, setVariantId] = (0, import_react37.useState)(
10162
+ const [variantId, setVariantId] = (0, import_react38.useState)(
9985
10163
  () => resolvePanoVideoVariantId(variants, defaultVariantId)
9986
10164
  );
9987
- const [trackId, setTrackId] = (0, import_react37.useState)(
10165
+ const [trackId, setTrackId] = (0, import_react38.useState)(
9988
10166
  () => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
9989
10167
  );
9990
- const [ready, setReady] = (0, import_react37.useState)(false);
9991
- const autoPlayRef = (0, import_react37.useRef)(autoPlay);
10168
+ const [ready, setReady] = (0, import_react38.useState)(false);
10169
+ const autoPlayRef = (0, import_react38.useRef)(autoPlay);
9992
10170
  autoPlayRef.current = autoPlay;
9993
- const blockedRef = (0, import_react37.useRef)(false);
9994
- const captionAppearanceOverrideRef = (0, import_react37.useRef)(
10171
+ const blockedRef = (0, import_react38.useRef)(false);
10172
+ const captionAppearanceOverrideRef = (0, import_react38.useRef)(
9995
10173
  {}
9996
10174
  );
9997
- const mediaCapabilitiesRef = (0, import_react37.useRef)({
10175
+ const mediaCapabilitiesRef = (0, import_react38.useRef)({
9998
10176
  volumeAdjustable: true,
9999
10177
  playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
10000
10178
  });
10001
- const storeRef = (0, import_react37.useRef)(null);
10179
+ const storeRef = (0, import_react38.useRef)(null);
10002
10180
  if (!storeRef.current) {
10003
10181
  storeRef.current = {
10004
10182
  snapshot: {
@@ -10008,7 +10186,7 @@ function PanoVideo({
10008
10186
  listeners: /* @__PURE__ */ new Set()
10009
10187
  };
10010
10188
  }
10011
- const actionsRef = (0, import_react37.useRef)({
10189
+ const actionsRef = (0, import_react38.useRef)({
10012
10190
  play: async () => {
10013
10191
  },
10014
10192
  pause: () => {
@@ -10028,19 +10206,19 @@ function PanoVideo({
10028
10206
  setCaptionAppearance: (_appearance) => {
10029
10207
  }
10030
10208
  });
10031
- const onLoadRef = (0, import_react37.useRef)(onLoad);
10032
- const onErrorRef = (0, import_react37.useRef)(onError);
10033
- const onPlaybackStateChangeRef = (0, import_react37.useRef)(onPlaybackStateChange);
10034
- const onEndedRef = (0, import_react37.useRef)(onEnded);
10035
- const onVariantChangeRef = (0, import_react37.useRef)(onVariantChange);
10036
- const onTrackChangeRef = (0, import_react37.useRef)(onTrackChange);
10209
+ const onLoadRef = (0, import_react38.useRef)(onLoad);
10210
+ const onErrorRef = (0, import_react38.useRef)(onError);
10211
+ const onPlaybackStateChangeRef = (0, import_react38.useRef)(onPlaybackStateChange);
10212
+ const onEndedRef = (0, import_react38.useRef)(onEnded);
10213
+ const onVariantChangeRef = (0, import_react38.useRef)(onVariantChange);
10214
+ const onTrackChangeRef = (0, import_react38.useRef)(onTrackChange);
10037
10215
  onLoadRef.current = onLoad;
10038
10216
  onErrorRef.current = onError;
10039
10217
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
10040
10218
  onEndedRef.current = onEnded;
10041
10219
  onVariantChangeRef.current = onVariantChange;
10042
10220
  onTrackChangeRef.current = onTrackChange;
10043
- const resource = (0, import_react37.useMemo)(() => {
10221
+ const resource = (0, import_react38.useMemo)(() => {
10044
10222
  if (typeof document === "undefined") {
10045
10223
  return null;
10046
10224
  }
@@ -10057,7 +10235,7 @@ function PanoVideo({
10057
10235
  texture.generateMipmaps = false;
10058
10236
  return { video, texture };
10059
10237
  }, []);
10060
- (0, import_react37.useEffect)(
10238
+ (0, import_react38.useEffect)(
10061
10239
  () => () => {
10062
10240
  if (!resource) {
10063
10241
  return;
@@ -10072,13 +10250,13 @@ function PanoVideo({
10072
10250
  },
10073
10251
  [resource]
10074
10252
  );
10075
- (0, import_react37.useEffect)(() => {
10253
+ (0, import_react38.useEffect)(() => {
10076
10254
  if (!resource) {
10077
10255
  return;
10078
10256
  }
10079
10257
  resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
10080
10258
  }, [gl, resource]);
10081
- (0, import_react37.useEffect)(() => {
10259
+ (0, import_react38.useEffect)(() => {
10082
10260
  if (!resource || !overlay?.overlayElement) {
10083
10261
  return;
10084
10262
  }
@@ -10101,7 +10279,7 @@ function PanoVideo({
10101
10279
  activeVariant?.poster ?? poster,
10102
10280
  onError
10103
10281
  );
10104
- const emitSnapshot = (0, import_react37.useCallback)(
10282
+ const emitSnapshot = (0, import_react38.useCallback)(
10105
10283
  (patch) => {
10106
10284
  const store = storeRef.current;
10107
10285
  const video = resource?.video;
@@ -10153,7 +10331,7 @@ function PanoVideo({
10153
10331
  captionAppearance
10154
10332
  ]
10155
10333
  );
10156
- const controller = (0, import_react37.useMemo)(
10334
+ const controller = (0, import_react38.useMemo)(
10157
10335
  () => ({
10158
10336
  subscribe: (onStoreChange) => {
10159
10337
  const store = storeRef.current;
@@ -10205,7 +10383,7 @@ function PanoVideo({
10205
10383
  }),
10206
10384
  []
10207
10385
  );
10208
- (0, import_react37.useLayoutEffect)(() => {
10386
+ (0, import_react38.useLayoutEffect)(() => {
10209
10387
  if (!host || variants.length === 0) {
10210
10388
  return;
10211
10389
  }
@@ -10218,7 +10396,7 @@ function PanoVideo({
10218
10396
  notifyPanoVideoHost(host);
10219
10397
  };
10220
10398
  }, [captionsEnabled, controller, controls, host, variants.length]);
10221
- (0, import_react37.useLayoutEffect)(() => {
10399
+ (0, import_react38.useLayoutEffect)(() => {
10222
10400
  if (!resource) {
10223
10401
  return;
10224
10402
  }
@@ -10231,10 +10409,10 @@ function PanoVideo({
10231
10409
  };
10232
10410
  emitSnapshot();
10233
10411
  }, [emitSnapshot, playbackRates, resource]);
10234
- (0, import_react37.useEffect)(() => {
10412
+ (0, import_react38.useEffect)(() => {
10235
10413
  emitSnapshot();
10236
10414
  }, [emitSnapshot]);
10237
- (0, import_react37.useEffect)(() => {
10415
+ (0, import_react38.useEffect)(() => {
10238
10416
  if (!resource || !activeVariant || !mediaKey) {
10239
10417
  return;
10240
10418
  }
@@ -10291,7 +10469,7 @@ function PanoVideo({
10291
10469
  video.removeEventListener("error", handleError);
10292
10470
  };
10293
10471
  }, [mediaKey, resource]);
10294
- (0, import_react37.useEffect)(() => {
10472
+ (0, import_react38.useEffect)(() => {
10295
10473
  if (!resource) {
10296
10474
  return;
10297
10475
  }
@@ -10381,7 +10559,7 @@ function PanoVideo({
10381
10559
  }
10382
10560
  };
10383
10561
  }, [emitSnapshot, resource]);
10384
- (0, import_react37.useEffect)(() => {
10562
+ (0, import_react38.useEffect)(() => {
10385
10563
  if (!resource) {
10386
10564
  return;
10387
10565
  }
@@ -10401,7 +10579,7 @@ function PanoVideo({
10401
10579
  }
10402
10580
  video.preload = preload;
10403
10581
  }, [loop, muted, playsInline, preload, resource, volume]);
10404
- (0, import_react37.useEffect)(() => {
10582
+ (0, import_react38.useEffect)(() => {
10405
10583
  if (!resource) {
10406
10584
  return;
10407
10585
  }
@@ -10451,7 +10629,7 @@ function PanoVideo({
10451
10629
  video.removeEventListener("ratechange", handleVolume);
10452
10630
  };
10453
10631
  }, [emitSnapshot, resource]);
10454
- (0, import_react37.useEffect)(() => {
10632
+ (0, import_react38.useEffect)(() => {
10455
10633
  if (!resource) {
10456
10634
  return;
10457
10635
  }
@@ -10486,7 +10664,7 @@ function PanoVideo({
10486
10664
  video.textTracks.removeEventListener("change", applyModes);
10487
10665
  };
10488
10666
  }, [emitSnapshot, resource, trackId, tracks]);
10489
- (0, import_react37.useEffect)(() => {
10667
+ (0, import_react38.useEffect)(() => {
10490
10668
  if (!captionsEnabled) {
10491
10669
  setTrackId(null);
10492
10670
  return;
@@ -10522,7 +10700,7 @@ function PanoVideo({
10522
10700
 
10523
10701
  // src/scenes.tsx
10524
10702
  var import_fiber21 = require("@react-three/fiber");
10525
- var import_react42 = require("react");
10703
+ var import_react43 = require("react");
10526
10704
  var import_three19 = require("three");
10527
10705
 
10528
10706
  // src/scene-transitions/presets.ts
@@ -10573,7 +10751,7 @@ function isSnapshotTransition(preset) {
10573
10751
 
10574
10752
  // src/scene-transitions/particle-overlay.tsx
10575
10753
  var import_fiber17 = require("@react-three/fiber");
10576
- var import_react38 = require("react");
10754
+ var import_react39 = require("react");
10577
10755
  var import_three13 = require("three");
10578
10756
 
10579
10757
  // src/scene-transitions/glsl.ts
@@ -10705,12 +10883,12 @@ function ParticleOverlay({
10705
10883
  onFinish
10706
10884
  }) {
10707
10885
  const { camera } = (0, import_fiber17.useThree)();
10708
- const meshRef = (0, import_react38.useRef)(null);
10709
- const startRef = (0, import_react38.useRef)(null);
10710
- const finishedRef = (0, import_react38.useRef)(false);
10711
- const directionRef = (0, import_react38.useRef)(new import_three13.Vector3());
10712
- const geometry = (0, import_react38.useMemo)(() => createParticleGeometry(), []);
10713
- const material = (0, import_react38.useMemo)(
10886
+ const meshRef = (0, import_react39.useRef)(null);
10887
+ const startRef = (0, import_react39.useRef)(null);
10888
+ const finishedRef = (0, import_react39.useRef)(false);
10889
+ const directionRef = (0, import_react39.useRef)(new import_three13.Vector3());
10890
+ const geometry = (0, import_react39.useMemo)(() => createParticleGeometry(), []);
10891
+ const material = (0, import_react39.useMemo)(
10714
10892
  () => new import_three13.ShaderMaterial({
10715
10893
  transparent: true,
10716
10894
  depthTest: false,
@@ -10726,9 +10904,9 @@ function ParticleOverlay({
10726
10904
  }),
10727
10905
  [snapshot.texture]
10728
10906
  );
10729
- (0, import_react38.useEffect)(() => () => geometry.dispose(), [geometry]);
10730
- (0, import_react38.useEffect)(() => () => material.dispose(), [material]);
10731
- (0, import_react38.useEffect)(() => {
10907
+ (0, import_react39.useEffect)(() => () => geometry.dispose(), [geometry]);
10908
+ (0, import_react39.useEffect)(() => () => material.dispose(), [material]);
10909
+ (0, import_react39.useEffect)(() => {
10732
10910
  startRef.current = null;
10733
10911
  finishedRef.current = false;
10734
10912
  material.uniforms.progress.value = 0;
@@ -10764,7 +10942,7 @@ function ParticleOverlay({
10764
10942
 
10765
10943
  // src/scene-transitions/snapshot-overlay.tsx
10766
10944
  var import_fiber18 = require("@react-three/fiber");
10767
- var import_react39 = require("react");
10945
+ var import_react40 = require("react");
10768
10946
  var import_three15 = require("three");
10769
10947
 
10770
10948
  // src/scene-transitions/snapshot-shaders.ts
@@ -11053,18 +11231,18 @@ function SnapshotOverlay({
11053
11231
  onFinish
11054
11232
  }) {
11055
11233
  const { camera, gl } = (0, import_fiber18.useThree)();
11056
- const meshRef = (0, import_react39.useRef)(null);
11057
- const startRef = (0, import_react39.useRef)(null);
11058
- const finishedRef = (0, import_react39.useRef)(false);
11059
- const directionRef = (0, import_react39.useRef)(new import_three15.Vector3());
11060
- const material = (0, import_react39.useMemo)(() => {
11234
+ const meshRef = (0, import_react40.useRef)(null);
11235
+ const startRef = (0, import_react40.useRef)(null);
11236
+ const finishedRef = (0, import_react40.useRef)(false);
11237
+ const directionRef = (0, import_react40.useRef)(new import_three15.Vector3());
11238
+ const material = (0, import_react40.useMemo)(() => {
11061
11239
  if (!isSnapshotTransition(transition.preset)) {
11062
11240
  return null;
11063
11241
  }
11064
11242
  return createSnapshotMaterial(transition.preset, snapshot.texture);
11065
11243
  }, [snapshot.texture, transition.preset]);
11066
- (0, import_react39.useEffect)(() => () => material?.dispose(), [material]);
11067
- (0, import_react39.useEffect)(() => {
11244
+ (0, import_react40.useEffect)(() => () => material?.dispose(), [material]);
11245
+ (0, import_react40.useEffect)(() => {
11068
11246
  startRef.current = null;
11069
11247
  finishedRef.current = false;
11070
11248
  if (material) {
@@ -11146,7 +11324,7 @@ function TransitionOverlay(props) {
11146
11324
 
11147
11325
  // src/tile/texture-manager-context.tsx
11148
11326
  var import_fiber19 = require("@react-three/fiber");
11149
- var import_react40 = require("react");
11327
+ var import_react41 = require("react");
11150
11328
 
11151
11329
  // src/tile/texture-manager.ts
11152
11330
  var import_three16 = require("three");
@@ -11371,7 +11549,7 @@ var TileTextureManager = class {
11371
11549
 
11372
11550
  // src/tile/texture-manager-context.tsx
11373
11551
  var import_jsx_runtime21 = require("react/jsx-runtime");
11374
- var TileTextureManagerContext = (0, import_react40.createContext)(
11552
+ var TileTextureManagerContext = (0, import_react41.createContext)(
11375
11553
  null
11376
11554
  );
11377
11555
  function TileTextureManagerProvider({
@@ -11381,7 +11559,7 @@ function TileTextureManagerProvider({
11381
11559
  }) {
11382
11560
  const gl = (0, import_fiber19.useThree)((state) => state.gl);
11383
11561
  const anisotropy = gl.capabilities.getMaxAnisotropy();
11384
- const manager = (0, import_react40.useMemo)(
11562
+ const manager = (0, import_react41.useMemo)(
11385
11563
  () => new TileTextureManager({
11386
11564
  anisotropy,
11387
11565
  maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
@@ -11390,19 +11568,19 @@ function TileTextureManagerProvider({
11390
11568
  }),
11391
11569
  [anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
11392
11570
  );
11393
- (0, import_react40.useEffect)(() => {
11571
+ (0, import_react41.useEffect)(() => {
11394
11572
  manager.resume();
11395
11573
  return () => manager.dispose();
11396
11574
  }, [manager]);
11397
11575
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TileTextureManagerContext.Provider, { value: manager, children });
11398
11576
  }
11399
11577
  function useSharedTileTextureManager() {
11400
- return (0, import_react40.useContext)(TileTextureManagerContext);
11578
+ return (0, import_react41.useContext)(TileTextureManagerContext);
11401
11579
  }
11402
11580
 
11403
11581
  // src/tile/tile.tsx
11404
11582
  var import_fiber20 = require("@react-three/fiber");
11405
- var import_react41 = require("react");
11583
+ var import_react42 = require("react");
11406
11584
  var import_three18 = require("three");
11407
11585
 
11408
11586
  // src/tile/face-layout.ts
@@ -11591,10 +11769,10 @@ var VISIBILITY_FOV_PADDING_DEGREES = 8;
11591
11769
  var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
11592
11770
  var SHARED_TILE_GEOMETRY = new import_three18.PlaneGeometry(1, 1);
11593
11771
  function usePreviewTexture(url, anisotropy, onError) {
11594
- const [texture, setTexture] = (0, import_react41.useState)(null);
11595
- const onErrorRef = (0, import_react41.useRef)(onError);
11772
+ const [texture, setTexture] = (0, import_react42.useState)(null);
11773
+ const onErrorRef = (0, import_react42.useRef)(onError);
11596
11774
  onErrorRef.current = onError;
11597
- (0, import_react41.useEffect)(() => {
11775
+ (0, import_react42.useEffect)(() => {
11598
11776
  if (!url) {
11599
11777
  setTexture(null);
11600
11778
  return;
@@ -11631,7 +11809,7 @@ function usePreviewTexture(url, anisotropy, onError) {
11631
11809
  active = false;
11632
11810
  };
11633
11811
  }, [anisotropy, url]);
11634
- (0, import_react41.useEffect)(
11812
+ (0, import_react42.useEffect)(
11635
11813
  () => () => {
11636
11814
  texture?.dispose();
11637
11815
  },
@@ -11644,7 +11822,7 @@ function PreviewFace({
11644
11822
  texture,
11645
11823
  faceOrder
11646
11824
  }) {
11647
- const geometry = (0, import_react41.useMemo)(() => {
11825
+ const geometry = (0, import_react42.useMemo)(() => {
11648
11826
  const nextGeometry = new import_three18.PlaneGeometry(
11649
11827
  PREVIEW_RADIUS * 2,
11650
11828
  PREVIEW_RADIUS * 2
@@ -11662,7 +11840,7 @@ function PreviewFace({
11662
11840
  uv.needsUpdate = true;
11663
11841
  return nextGeometry;
11664
11842
  }, [face, faceOrder]);
11665
- (0, import_react41.useEffect)(
11843
+ (0, import_react42.useEffect)(
11666
11844
  () => () => {
11667
11845
  geometry.dispose();
11668
11846
  },
@@ -11703,14 +11881,14 @@ function PreviewCube({
11703
11881
  ));
11704
11882
  }
11705
11883
  function useManagedTexture(manager, key, url, address) {
11706
- const [managedState, setManagedState] = (0, import_react41.useState)(() => ({
11884
+ const [managedState, setManagedState] = (0, import_react42.useState)(() => ({
11707
11885
  manager,
11708
11886
  key,
11709
11887
  url,
11710
11888
  snapshot: manager.getSnapshot(key)
11711
11889
  }));
11712
11890
  const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
11713
- (0, import_react41.useEffect)(
11891
+ (0, import_react42.useEffect)(
11714
11892
  () => manager.acquire(key, url, address, (nextSnapshot) => {
11715
11893
  setManagedState({
11716
11894
  manager,
@@ -11723,7 +11901,7 @@ function useManagedTexture(manager, key, url, address) {
11723
11901
  );
11724
11902
  return snapshot;
11725
11903
  }
11726
- var TileMesh = (0, import_react41.memo)(function TileMesh2({
11904
+ var TileMesh = (0, import_react42.memo)(function TileMesh2({
11727
11905
  address,
11728
11906
  manager,
11729
11907
  renderOrder,
@@ -11756,7 +11934,7 @@ var TileMesh = (0, import_react41.memo)(function TileMesh2({
11756
11934
  }
11757
11935
  ) });
11758
11936
  });
11759
- var TileLayerMeshes = (0, import_react41.memo)(function TileLayerMeshes2({
11937
+ var TileLayerMeshes = (0, import_react42.memo)(function TileLayerMeshes2({
11760
11938
  layer,
11761
11939
  manager,
11762
11940
  resolveUrl
@@ -11930,10 +12108,10 @@ function Tile({
11930
12108
  onLevelChange
11931
12109
  }) {
11932
12110
  const { camera, gl, size } = (0, import_fiber20.useThree)();
11933
- const multiresConfig = (0, import_react41.useMemo)(() => parseMultires(multires), [multires]);
12111
+ const multiresConfig = (0, import_react42.useMemo)(() => parseMultires(multires), [multires]);
11934
12112
  const { levels, tileSize } = multiresConfig;
11935
12113
  const multiresToken = `${tileSize}:${levels.join(",")}`;
11936
- const candidatesByLevel = (0, import_react41.useMemo)(
12114
+ const candidatesByLevel = (0, import_react42.useMemo)(
11937
12115
  () => buildTileCandidates(levels, tileSize),
11938
12116
  [levels, tileSize]
11939
12117
  );
@@ -11945,13 +12123,13 @@ function Tile({
11945
12123
  onPreviewError
11946
12124
  );
11947
12125
  const sharedManager = useSharedTileTextureManager();
11948
- const progressRef = (0, import_react41.useRef)(onLoadProgress);
11949
- const errorRef = (0, import_react41.useRef)(onTileError);
11950
- const levelChangeRef = (0, import_react41.useRef)(onLevelChange);
12126
+ const progressRef = (0, import_react42.useRef)(onLoadProgress);
12127
+ const errorRef = (0, import_react42.useRef)(onTileError);
12128
+ const levelChangeRef = (0, import_react42.useRef)(onLevelChange);
11951
12129
  progressRef.current = onLoadProgress;
11952
12130
  errorRef.current = onTileError;
11953
12131
  levelChangeRef.current = onLevelChange;
11954
- const ownedManager = (0, import_react41.useMemo)(
12132
+ const ownedManager = (0, import_react42.useMemo)(
11955
12133
  () => new TileTextureManager({
11956
12134
  anisotropy,
11957
12135
  maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
@@ -11972,7 +12150,7 @@ function Tile({
11972
12150
  ]
11973
12151
  );
11974
12152
  const manager = sharedManager ?? ownedManager;
11975
- (0, import_react41.useEffect)(() => {
12153
+ (0, import_react42.useEffect)(() => {
11976
12154
  manager.resume();
11977
12155
  return () => {
11978
12156
  if (manager === ownedManager) {
@@ -11982,11 +12160,11 @@ function Tile({
11982
12160
  queueMicrotask(() => manager.releaseUnused());
11983
12161
  };
11984
12162
  }, [manager, ownedManager]);
11985
- const readyRef = (0, import_react41.useRef)(false);
11986
- (0, import_react41.useEffect)(() => {
12163
+ const readyRef = (0, import_react42.useRef)(false);
12164
+ (0, import_react42.useEffect)(() => {
11987
12165
  readyRef.current = false;
11988
12166
  }, [effectivePreviewUrl]);
11989
- (0, import_react41.useEffect)(() => {
12167
+ (0, import_react42.useEffect)(() => {
11990
12168
  if (!previewTexture || readyRef.current) {
11991
12169
  return;
11992
12170
  }
@@ -11994,31 +12172,31 @@ function Tile({
11994
12172
  onReady?.();
11995
12173
  }, [onReady, previewTexture]);
11996
12174
  const template = urlTemplate ?? buildDefaultTileUrlTemplate();
11997
- const resolveUrl = (0, import_react41.useMemo)(
12175
+ const resolveUrl = (0, import_react42.useMemo)(
11998
12176
  () => (address) => {
11999
12177
  const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
12000
12178
  return resolveRelativeTileUrl(baseUrl, relativePath);
12001
12179
  },
12002
12180
  [baseUrl, resolveTileUrl, template]
12003
12181
  );
12004
- const [layers, setLayers] = (0, import_react41.useState)([]);
12005
- const layerTokenRef = (0, import_react41.useRef)("");
12006
- const currentLevelRef = (0, import_react41.useRef)(1);
12007
- const lastUpdateAtRef = (0, import_react41.useRef)(-Infinity);
12008
- const visibilityDirtyRef = (0, import_react41.useRef)(true);
12009
- const lastVisibilityQuaternionRef = (0, import_react41.useRef)(camera.quaternion.clone());
12010
- const lastVisibilityFovRef = (0, import_react41.useRef)(Number.NaN);
12011
- const lastViewportRef = (0, import_react41.useRef)({ width: 0, height: 0, dpr: 0 });
12012
- const frustumRef = (0, import_react41.useRef)(new import_three18.Frustum());
12013
- const projectionMatrixRef = (0, import_react41.useRef)(new import_three18.Matrix4());
12014
- const visibilityCameraRef = (0, import_react41.useRef)(new import_three18.PerspectiveCamera());
12015
- (0, import_react41.useEffect)(() => {
12182
+ const [layers, setLayers] = (0, import_react42.useState)([]);
12183
+ const layerTokenRef = (0, import_react42.useRef)("");
12184
+ const currentLevelRef = (0, import_react42.useRef)(1);
12185
+ const lastUpdateAtRef = (0, import_react42.useRef)(-Infinity);
12186
+ const visibilityDirtyRef = (0, import_react42.useRef)(true);
12187
+ const lastVisibilityQuaternionRef = (0, import_react42.useRef)(camera.quaternion.clone());
12188
+ const lastVisibilityFovRef = (0, import_react42.useRef)(Number.NaN);
12189
+ const lastViewportRef = (0, import_react42.useRef)({ width: 0, height: 0, dpr: 0 });
12190
+ const frustumRef = (0, import_react42.useRef)(new import_three18.Frustum());
12191
+ const projectionMatrixRef = (0, import_react42.useRef)(new import_three18.Matrix4());
12192
+ const visibilityCameraRef = (0, import_react42.useRef)(new import_three18.PerspectiveCamera());
12193
+ (0, import_react42.useEffect)(() => {
12016
12194
  currentLevelRef.current = 1;
12017
12195
  layerTokenRef.current = "";
12018
12196
  visibilityDirtyRef.current = true;
12019
12197
  setLayers([]);
12020
12198
  }, [manager, multiresToken]);
12021
- (0, import_react41.useEffect)(() => {
12199
+ (0, import_react42.useEffect)(() => {
12022
12200
  if (loadMode !== "preview") {
12023
12201
  return;
12024
12202
  }
@@ -12169,9 +12347,9 @@ function SnapshotCapture({
12169
12347
  onCaptured
12170
12348
  }) {
12171
12349
  const { camera, gl, scene, size } = (0, import_fiber21.useThree)();
12172
- const capturedRequestRef = (0, import_react42.useRef)(0);
12173
- const renderTargetRef = (0, import_react42.useRef)(null);
12174
- (0, import_react42.useEffect)(
12350
+ const capturedRequestRef = (0, import_react43.useRef)(0);
12351
+ const renderTargetRef = (0, import_react43.useRef)(null);
12352
+ (0, import_react43.useEffect)(
12175
12353
  () => () => {
12176
12354
  renderTargetRef.current?.dispose();
12177
12355
  renderTargetRef.current = null;
@@ -12227,50 +12405,50 @@ function ScenesController({
12227
12405
  snapshotMaxPixels = 3686400,
12228
12406
  phaseRef: externalPhaseRef
12229
12407
  }) {
12230
- const controlsRef = (0, import_react42.useContext)(PanoramaViewContext);
12408
+ const controlsRef = (0, import_react43.useContext)(PanoramaViewContext);
12231
12409
  const manager = useSharedTileTextureManager();
12232
- const transition = (0, import_react42.useMemo)(
12410
+ const transition = (0, import_react43.useMemo)(
12233
12411
  () => resolveTransition(transitionInput),
12234
12412
  [transitionInput]
12235
12413
  );
12236
- const sceneMap = (0, import_react42.useMemo)(
12414
+ const sceneMap = (0, import_react43.useMemo)(
12237
12415
  () => new Map(scenes.map((scene) => [scene.id, scene])),
12238
12416
  [scenes]
12239
12417
  );
12240
12418
  const initialScene = sceneMap.get(activeSceneId) ?? null;
12241
- const [slots, setSlots] = (0, import_react42.useState)([
12419
+ const [slots, setSlots] = (0, import_react43.useState)([
12242
12420
  initialScene,
12243
12421
  null
12244
12422
  ]);
12245
- const [activeSlot, setActiveSlot] = (0, import_react42.useState)(0);
12246
- const [liveSlot, setLiveSlot] = (0, import_react42.useState)(0);
12247
- const [pendingSlot, setPendingSlot] = (0, import_react42.useState)(null);
12248
- const [phase, setPhase] = (0, import_react42.useState)(initialScene ? "idle" : "preloading");
12249
- const [captureRequestId, setCaptureRequestId] = (0, import_react42.useState)(0);
12250
- const [transitionRunId, setTransitionRunId] = (0, import_react42.useState)(0);
12251
- const [snapshot, setSnapshot] = (0, import_react42.useState)(null);
12252
- const [recoveryKey, setRecoveryKey] = (0, import_react42.useState)(0);
12253
- const requestedSceneIdRef = (0, import_react42.useRef)(activeSceneId);
12254
- const captureReasonRef = (0, import_react42.useRef)("start");
12255
- const interactionReleaseRef = (0, import_react42.useRef)(null);
12256
- const slotsRef = (0, import_react42.useRef)(slots);
12257
- const phaseRef = (0, import_react42.useRef)(phase);
12258
- const liveSlotRef = (0, import_react42.useRef)(liveSlot);
12259
- const transitionFromRef = (0, import_react42.useRef)(initialScene);
12423
+ const [activeSlot, setActiveSlot] = (0, import_react43.useState)(0);
12424
+ const [liveSlot, setLiveSlot] = (0, import_react43.useState)(0);
12425
+ const [pendingSlot, setPendingSlot] = (0, import_react43.useState)(null);
12426
+ const [phase, setPhase] = (0, import_react43.useState)(initialScene ? "idle" : "preloading");
12427
+ const [captureRequestId, setCaptureRequestId] = (0, import_react43.useState)(0);
12428
+ const [transitionRunId, setTransitionRunId] = (0, import_react43.useState)(0);
12429
+ const [snapshot, setSnapshot] = (0, import_react43.useState)(null);
12430
+ const [recoveryKey, setRecoveryKey] = (0, import_react43.useState)(0);
12431
+ const requestedSceneIdRef = (0, import_react43.useRef)(activeSceneId);
12432
+ const captureReasonRef = (0, import_react43.useRef)("start");
12433
+ const interactionReleaseRef = (0, import_react43.useRef)(null);
12434
+ const slotsRef = (0, import_react43.useRef)(slots);
12435
+ const phaseRef = (0, import_react43.useRef)(phase);
12436
+ const liveSlotRef = (0, import_react43.useRef)(liveSlot);
12437
+ const transitionFromRef = (0, import_react43.useRef)(initialScene);
12260
12438
  slotsRef.current = slots;
12261
12439
  phaseRef.current = phase;
12262
12440
  if (externalPhaseRef) {
12263
12441
  externalPhaseRef.current = phase;
12264
12442
  }
12265
12443
  liveSlotRef.current = liveSlot;
12266
- const releaseInteraction = (0, import_react42.useCallback)(() => {
12444
+ const releaseInteraction = (0, import_react43.useCallback)(() => {
12267
12445
  interactionReleaseRef.current?.();
12268
12446
  interactionReleaseRef.current = null;
12269
12447
  }, []);
12270
- const reportError = (0, import_react42.useCallback)((sceneId, error) => {
12448
+ const reportError = (0, import_react43.useCallback)((sceneId, error) => {
12271
12449
  onTransitionError?.({ sceneId, error });
12272
12450
  }, [onTransitionError]);
12273
- const startPreload = (0, import_react42.useCallback)((scene) => {
12451
+ const startPreload = (0, import_react43.useCallback)((scene) => {
12274
12452
  const nextSlot = 1 - liveSlotRef.current;
12275
12453
  requestedSceneIdRef.current = scene.id;
12276
12454
  setSlots((current) => {
@@ -12281,7 +12459,7 @@ function ScenesController({
12281
12459
  setPendingSlot(nextSlot);
12282
12460
  setPhase("preloading");
12283
12461
  }, []);
12284
- (0, import_react42.useEffect)(() => {
12462
+ (0, import_react43.useEffect)(() => {
12285
12463
  const requested = sceneMap.get(activeSceneId);
12286
12464
  if (!requested) {
12287
12465
  reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
@@ -12305,7 +12483,7 @@ function ScenesController({
12305
12483
  }
12306
12484
  startPreload(requested);
12307
12485
  }, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);
12308
- const handleReady = (0, import_react42.useCallback)((slot) => {
12486
+ const handleReady = (0, import_react43.useCallback)((slot) => {
12309
12487
  if (slot !== pendingSlot || phaseRef.current !== "preloading") {
12310
12488
  return;
12311
12489
  }
@@ -12336,7 +12514,7 @@ function ScenesController({
12336
12514
  setPhase("capturing");
12337
12515
  setCaptureRequestId((current) => current + 1);
12338
12516
  }, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);
12339
- const handleCaptured = (0, import_react42.useCallback)((nextSnapshot) => {
12517
+ const handleCaptured = (0, import_react43.useCallback)((nextSnapshot) => {
12340
12518
  setSnapshot((current) => {
12341
12519
  current?.dispose();
12342
12520
  return nextSnapshot;
@@ -12358,7 +12536,7 @@ function ScenesController({
12358
12536
  setPhase("transitioning");
12359
12537
  setTransitionRunId((current) => current + 1);
12360
12538
  }, [manager, pendingSlot, sceneMap, startPreload]);
12361
- const finishTransition = (0, import_react42.useCallback)(() => {
12539
+ const finishTransition = (0, import_react43.useCallback)(() => {
12362
12540
  const nextSlot = pendingSlot;
12363
12541
  const previousScene = transitionFromRef.current;
12364
12542
  const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
@@ -12383,12 +12561,12 @@ function ScenesController({
12383
12561
  });
12384
12562
  }
12385
12563
  }, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
12386
- (0, import_react42.useEffect)(() => () => {
12564
+ (0, import_react43.useEffect)(() => () => {
12387
12565
  releaseInteraction();
12388
12566
  snapshot?.dispose();
12389
12567
  }, [releaseInteraction, snapshot]);
12390
12568
  const { gl } = (0, import_fiber21.useThree)();
12391
- (0, import_react42.useEffect)(() => {
12569
+ (0, import_react43.useEffect)(() => {
12392
12570
  const canvas = gl.domElement;
12393
12571
  const onContextLost = (event) => {
12394
12572
  event.preventDefault();
@@ -12412,7 +12590,7 @@ function ScenesController({
12412
12590
  }, [gl, manager, releaseInteraction, snapshot]);
12413
12591
  const renderedScene = slots[liveSlot];
12414
12592
  const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
12415
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react42.Fragment, { children: [
12593
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react43.Fragment, { children: [
12416
12594
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
12417
12595
  SnapshotCapture,
12418
12596
  {
@@ -12464,11 +12642,11 @@ function Scenes({
12464
12642
  ...rest
12465
12643
  }) {
12466
12644
  const isControlled = controlledId !== void 0;
12467
- const [internalId, setInternalId] = (0, import_react42.useState)(
12645
+ const [internalId, setInternalId] = (0, import_react43.useState)(
12468
12646
  () => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
12469
12647
  );
12470
12648
  const resolvedId = isControlled ? controlledId : internalId;
12471
- const requestSceneChange = (0, import_react42.useCallback)(
12649
+ const requestSceneChange = (0, import_react43.useCallback)(
12472
12650
  (id) => {
12473
12651
  if (isControlled) {
12474
12652
  onActiveSceneIdChange?.(id);
@@ -12478,13 +12656,13 @@ function Scenes({
12478
12656
  },
12479
12657
  [isControlled, onActiveSceneIdChange]
12480
12658
  );
12481
- const scenesRef = (0, import_react42.useRef)(scenes);
12659
+ const scenesRef = (0, import_react43.useRef)(scenes);
12482
12660
  scenesRef.current = scenes;
12483
- const resolvedIdRef = (0, import_react42.useRef)(resolvedId);
12661
+ const resolvedIdRef = (0, import_react43.useRef)(resolvedId);
12484
12662
  resolvedIdRef.current = resolvedId;
12485
- const host = (0, import_react42.useContext)(ScenesHostContext);
12486
- const phaseRef = (0, import_react42.useRef)("idle");
12487
- (0, import_react42.useEffect)(() => {
12663
+ const host = (0, import_react43.useContext)(ScenesHostContext);
12664
+ const phaseRef = (0, import_react43.useRef)("idle");
12665
+ (0, import_react43.useEffect)(() => {
12488
12666
  if (!host) {
12489
12667
  return;
12490
12668
  }
@@ -12554,25 +12732,25 @@ function Scenes({
12554
12732
 
12555
12733
  // src/hotspot/image-hotspot.tsx
12556
12734
  var import_fiber23 = require("@react-three/fiber");
12557
- var import_react46 = require("react");
12735
+ var import_react47 = require("react");
12558
12736
  var import_three22 = require("three");
12559
12737
 
12560
12738
  // src/hotspot/hotspot-anchor.tsx
12561
12739
  var import_fiber22 = require("@react-three/fiber");
12562
- var import_react45 = require("react");
12740
+ var import_react46 = require("react");
12563
12741
  var import_three20 = require("three");
12564
12742
 
12565
12743
  // src/hotspot/hotspot-tooltip.tsx
12566
- var import_react44 = require("react");
12744
+ var import_react45 = require("react");
12567
12745
 
12568
12746
  // src/webvr/stereo-html.tsx
12569
12747
  var import_drei = require("@react-three/drei");
12570
- var import_react43 = require("react");
12748
+ var import_react44 = require("react");
12571
12749
  var import_jsx_runtime24 = require("react/jsx-runtime");
12572
12750
  function useFallbackStereoView() {
12573
- const runtime = (0, import_react43.useContext)(WebVRRuntimeContext);
12751
+ const runtime = (0, import_react44.useContext)(WebVRRuntimeContext);
12574
12752
  const host = runtime?.host ?? null;
12575
- const fallback = (0, import_react43.useSyncExternalStore)(
12753
+ const fallback = (0, import_react44.useSyncExternalStore)(
12576
12754
  (onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
12577
12755
  () => isFallbackStereoMode(host?.snapshot.mode ?? null),
12578
12756
  () => false
@@ -12686,16 +12864,16 @@ function HotspotTooltip({
12686
12864
  offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
12687
12865
  appearance
12688
12866
  }) {
12689
- const [imageFailed, setImageFailed] = (0, import_react44.useState)(false);
12690
- (0, import_react44.useEffect)(() => {
12867
+ const [imageFailed, setImageFailed] = (0, import_react45.useState)(false);
12868
+ (0, import_react45.useEffect)(() => {
12691
12869
  setImageFailed(false);
12692
12870
  }, [content.image]);
12693
12871
  const showImage = Boolean(content.image) && !imageFailed;
12694
- const resolvedAppearance = (0, import_react44.useMemo)(
12872
+ const resolvedAppearance = (0, import_react45.useMemo)(
12695
12873
  () => resolveHotspotTooltipAppearance(appearance),
12696
12874
  [appearance]
12697
12875
  );
12698
- const bubbleStyle = (0, import_react44.useMemo)(
12876
+ const bubbleStyle = (0, import_react45.useMemo)(
12699
12877
  () => ({
12700
12878
  background: resolvedAppearance.background,
12701
12879
  border: resolvedAppearance.border,
@@ -13074,22 +13252,29 @@ function HotspotAnchor({
13074
13252
  onPositionChange,
13075
13253
  onDragEnd
13076
13254
  }) {
13077
- const controlsRef = (0, import_react45.useContext)(PanoramaViewContext);
13078
- const eventBus = (0, import_react45.useContext)(PanoEventBusContext);
13255
+ const controlsRef = (0, import_react46.useContext)(PanoramaViewContext);
13256
+ const hotspotTargetRegistry = (0, import_react46.useContext)(HotspotTargetRegistryContext);
13257
+ const eventBus = (0, import_react46.useContext)(PanoEventBusContext);
13079
13258
  const cursorApi = usePanoCursor();
13080
13259
  const { camera, size } = (0, import_fiber22.useThree)();
13081
- const groupRef = (0, import_react45.useRef)(null);
13082
- const tooltipAnchorRef = (0, import_react45.useRef)(null);
13083
- const dragStateRef = (0, import_react45.useRef)(null);
13084
- const suppressNextClickRef = (0, import_react45.useRef)(false);
13085
- const [hovered, setHovered] = (0, import_react45.useState)(false);
13086
- const [dragging, setDragging] = (0, import_react45.useState)(false);
13087
- const [pinned, setPinned] = (0, import_react45.useState)(false);
13088
- const tooltipContent = (0, import_react45.useMemo)(
13260
+ const groupRef = (0, import_react46.useRef)(null);
13261
+ const tooltipAnchorRef = (0, import_react46.useRef)(null);
13262
+ const dragStateRef = (0, import_react46.useRef)(null);
13263
+ const suppressNextClickRef = (0, import_react46.useRef)(false);
13264
+ const [hovered, setHovered] = (0, import_react46.useState)(false);
13265
+ const [dragging, setDragging] = (0, import_react46.useState)(false);
13266
+ const [pinned, setPinned] = (0, import_react46.useState)(false);
13267
+ const tooltipContent = (0, import_react46.useMemo)(
13089
13268
  () => resolveHotspotTooltipContent(tooltip),
13090
13269
  [tooltip]
13091
13270
  );
13092
13271
  const normalizedPosition = normalizePanoPosition(position);
13272
+ (0, import_react46.useEffect)(() => {
13273
+ if (!hotspotTargetRegistry) {
13274
+ return;
13275
+ }
13276
+ return hotspotTargetRegistry.register(id, normalizedPosition);
13277
+ }, [hotspotTargetRegistry, id, normalizedPosition.pitch, normalizedPosition.yaw]);
13093
13278
  const rendering = internalOrientation && internalPlacement ? { orientation: internalOrientation, placement: internalPlacement } : HOTSPOT_MODE_RENDERING[mode];
13094
13279
  const { orientation: orientation2, placement } = rendering;
13095
13280
  const resolvedScale = resolveScale(scale);
@@ -13101,17 +13286,17 @@ function HotspotAnchor({
13101
13286
  scaledWidth,
13102
13287
  scaledHeight
13103
13288
  );
13104
- const worldPosition = (0, import_react45.useMemo)(
13289
+ const worldPosition = (0, import_react46.useMemo)(
13105
13290
  () => panoPositionToVector3(normalizedPosition, resolvedDistance),
13106
13291
  [normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
13107
13292
  );
13108
- const surfaceQuaternion3 = (0, import_react45.useMemo)(
13293
+ const surfaceQuaternion3 = (0, import_react46.useMemo)(
13109
13294
  () => createSurfaceQuaternion(normalizedPosition),
13110
13295
  [normalizedPosition.pitch, normalizedPosition.yaw]
13111
13296
  );
13112
13297
  const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
13113
13298
  const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
13114
- const focusGeometry = (0, import_react45.useMemo)(() => {
13299
+ const focusGeometry = (0, import_react46.useMemo)(() => {
13115
13300
  const planeGeometry = new import_three20.PlaneGeometry(1, 1);
13116
13301
  const geometry = new import_three20.EdgesGeometry(planeGeometry);
13117
13302
  planeGeometry.dispose();
@@ -13138,14 +13323,14 @@ function HotspotAnchor({
13138
13323
  });
13139
13324
  const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
13140
13325
  const cursorClaimId = hotspotCursorClaimId(id);
13141
- (0, import_react45.useEffect)(
13326
+ (0, import_react46.useEffect)(
13142
13327
  () => () => {
13143
13328
  dragStateRef.current?.releaseInteractionLock();
13144
13329
  dragStateRef.current = null;
13145
13330
  },
13146
13331
  []
13147
13332
  );
13148
- (0, import_react45.useEffect)(() => {
13333
+ (0, import_react46.useEffect)(() => {
13149
13334
  if (!cursorApi) {
13150
13335
  return;
13151
13336
  }
@@ -13167,14 +13352,14 @@ function HotspotAnchor({
13167
13352
  hovered,
13168
13353
  visible
13169
13354
  ]);
13170
- (0, import_react45.useEffect)(
13355
+ (0, import_react46.useEffect)(
13171
13356
  () => () => {
13172
13357
  cursorApi?.release(cursorClaimId);
13173
13358
  },
13174
13359
  [cursorApi, cursorClaimId]
13175
13360
  );
13176
- (0, import_react45.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
13177
- (0, import_react45.useEffect)(() => {
13361
+ (0, import_react46.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
13362
+ (0, import_react46.useEffect)(() => {
13178
13363
  if (tooltipTrigger !== "click") {
13179
13364
  setPinned(false);
13180
13365
  return;
@@ -13183,12 +13368,12 @@ function HotspotAnchor({
13183
13368
  setPinned(false);
13184
13369
  });
13185
13370
  }, [eventBus, tooltipTrigger]);
13186
- (0, import_react45.useEffect)(() => {
13371
+ (0, import_react46.useEffect)(() => {
13187
13372
  if (tooltipTrigger !== "hover") {
13188
13373
  setHovered(false);
13189
13374
  }
13190
13375
  }, [tooltipTrigger]);
13191
- (0, import_react45.useEffect)(() => {
13376
+ (0, import_react46.useEffect)(() => {
13192
13377
  if (acceptsPointer) {
13193
13378
  return;
13194
13379
  }
@@ -13201,7 +13386,7 @@ function HotspotAnchor({
13201
13386
  dragStateRef.current = null;
13202
13387
  setDragging(false);
13203
13388
  }, [acceptsPointer]);
13204
- (0, import_react45.useLayoutEffect)(() => {
13389
+ (0, import_react46.useLayoutEffect)(() => {
13205
13390
  const group = groupRef.current;
13206
13391
  if (!group) {
13207
13392
  return;
@@ -13527,12 +13712,12 @@ function HotspotPlane({
13527
13712
  var import_jsx_runtime28 = require("react/jsx-runtime");
13528
13713
  function useHotspotImageTexture(src, onLoad, onError) {
13529
13714
  const gl = (0, import_fiber23.useThree)((state) => state.gl);
13530
- const [texture, setTexture] = (0, import_react46.useState)(null);
13531
- const onLoadRef = (0, import_react46.useRef)(onLoad);
13532
- const onErrorRef = (0, import_react46.useRef)(onError);
13715
+ const [texture, setTexture] = (0, import_react47.useState)(null);
13716
+ const onLoadRef = (0, import_react47.useRef)(onLoad);
13717
+ const onErrorRef = (0, import_react47.useRef)(onError);
13533
13718
  onLoadRef.current = onLoad;
13534
13719
  onErrorRef.current = onError;
13535
- (0, import_react46.useEffect)(() => {
13720
+ (0, import_react47.useEffect)(() => {
13536
13721
  let active = true;
13537
13722
  setTexture(null);
13538
13723
  if (!src) {
@@ -13570,7 +13755,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
13570
13755
  active = false;
13571
13756
  };
13572
13757
  }, [gl, src]);
13573
- (0, import_react46.useEffect)(
13758
+ (0, import_react47.useEffect)(
13574
13759
  () => () => {
13575
13760
  texture?.dispose();
13576
13761
  },
@@ -13592,13 +13777,13 @@ function ImageHotspot({
13592
13777
  }
13593
13778
 
13594
13779
  // src/hotspot/polygon-hotspot.tsx
13595
- var import_react48 = require("react");
13780
+ var import_react49 = require("react");
13596
13781
  var import_three24 = require("three");
13597
13782
 
13598
13783
  // src/hotspot/hotspot-stroke-line.tsx
13599
13784
  var import_drei2 = require("@react-three/drei");
13600
13785
  var import_fiber24 = require("@react-three/fiber");
13601
- var import_react47 = require("react");
13786
+ var import_react48 = require("react");
13602
13787
  var import_three23 = require("three");
13603
13788
  var import_jsx_runtime29 = require("react/jsx-runtime");
13604
13789
  var LINE_WORLD_POSITION = new import_three23.Vector3();
@@ -13631,10 +13816,10 @@ function HotspotStrokeLine({
13631
13816
  dashSize,
13632
13817
  gapSize
13633
13818
  }) {
13634
- const lineRef = (0, import_react47.useRef)(null);
13819
+ const lineRef = (0, import_react48.useRef)(null);
13635
13820
  const { camera, size } = (0, import_fiber24.useThree)();
13636
13821
  const dash = resolveDash(dashSize, gapSize);
13637
- (0, import_react47.useLayoutEffect)(() => {
13822
+ (0, import_react48.useLayoutEffect)(() => {
13638
13823
  if (!dash.dashed) {
13639
13824
  return;
13640
13825
  }
@@ -13924,24 +14109,24 @@ function PolygonHotspot({
13924
14109
  onInvalid,
13925
14110
  ...anchorProps
13926
14111
  }) {
13927
- const issues = (0, import_react48.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
14112
+ const issues = (0, import_react49.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
13928
14113
  const valid = issues.length === 0;
13929
- const center = (0, import_react48.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
13930
- const fillGeometry = (0, import_react48.useMemo)(
14114
+ const center = (0, import_react49.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
14115
+ const fillGeometry = (0, import_react49.useMemo)(
13931
14116
  () => valid && center ? makeFillGeometry(vertices, center) : null,
13932
14117
  [center, valid, vertices]
13933
14118
  );
13934
- const strokePoints = (0, import_react48.useMemo)(
14119
+ const strokePoints = (0, import_react49.useMemo)(
13935
14120
  () => valid && center ? makeStrokePositions(vertices, center) : null,
13936
14121
  [center, valid, vertices]
13937
14122
  );
13938
14123
  const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
13939
- const startVerticesRef = (0, import_react48.useRef)(null);
14124
+ const startVerticesRef = (0, import_react49.useRef)(null);
13940
14125
  const issuesKey = issues.map((issue) => issue.code).join(",");
13941
- (0, import_react48.useEffect)(() => {
14126
+ (0, import_react49.useEffect)(() => {
13942
14127
  if (!valid) onInvalid?.(issues);
13943
14128
  }, [issues, issuesKey, onInvalid, valid]);
13944
- (0, import_react48.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
14129
+ (0, import_react49.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
13945
14130
  if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
13946
14131
  return null;
13947
14132
  }
@@ -14021,7 +14206,7 @@ function PolygonHotspot({
14021
14206
  }
14022
14207
 
14023
14208
  // src/hotspot/polyline-hotspot.tsx
14024
- var import_react49 = require("react");
14209
+ var import_react50 = require("react");
14025
14210
  var import_three25 = require("three");
14026
14211
  var import_jsx_runtime31 = require("react/jsx-runtime");
14027
14212
  var POLYLINE_RADIUS = 990;
@@ -14140,16 +14325,16 @@ function PolylineHotspot({
14140
14325
  onInvalid,
14141
14326
  ...anchorProps
14142
14327
  }) {
14143
- const issues = (0, import_react49.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
14328
+ const issues = (0, import_react50.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
14144
14329
  const valid = issues.length === 0;
14145
- const center = (0, import_react49.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
14146
- const linePoints = (0, import_react49.useMemo)(
14330
+ const center = (0, import_react50.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
14331
+ const linePoints = (0, import_react50.useMemo)(
14147
14332
  () => valid && center ? makeLinePositions(vertices, center) : null,
14148
14333
  [center, valid, vertices]
14149
14334
  );
14150
14335
  const opacity = Math.max(0, Math.min(strokeOpacity, 1));
14151
- const startVerticesRef = (0, import_react49.useRef)(null);
14152
- (0, import_react49.useEffect)(() => {
14336
+ const startVerticesRef = (0, import_react50.useRef)(null);
14337
+ (0, import_react50.useEffect)(() => {
14153
14338
  if (!valid) onInvalid?.(issues);
14154
14339
  }, [issues, onInvalid, valid]);
14155
14340
  if (!valid || !center || !linePoints || linePoints.length < 2) return null;
@@ -14215,7 +14400,7 @@ function PolylineHotspot({
14215
14400
  }
14216
14401
 
14217
14402
  // src/hotspot/graphic-hotspot.tsx
14218
- var import_react50 = require("react");
14403
+ var import_react51 = require("react");
14219
14404
  var import_three26 = require("three");
14220
14405
  var import_jsx_runtime32 = require("react/jsx-runtime");
14221
14406
  var GRAPHIC_TEXTURE_SIZE = 512;
@@ -14406,12 +14591,12 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
14406
14591
  return texture;
14407
14592
  }
14408
14593
  function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
14409
- const [texture, setTexture] = (0, import_react50.useState)(null);
14410
- const onLoadRef = (0, import_react50.useRef)(onLoad);
14411
- const onErrorRef = (0, import_react50.useRef)(onError);
14594
+ const [texture, setTexture] = (0, import_react51.useState)(null);
14595
+ const onLoadRef = (0, import_react51.useRef)(onLoad);
14596
+ const onErrorRef = (0, import_react51.useRef)(onError);
14412
14597
  onLoadRef.current = onLoad;
14413
14598
  onErrorRef.current = onError;
14414
- (0, import_react50.useEffect)(() => {
14599
+ (0, import_react51.useEffect)(() => {
14415
14600
  let nextTexture = null;
14416
14601
  try {
14417
14602
  nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
@@ -14450,7 +14635,7 @@ function GraphicHotspot(props) {
14450
14635
 
14451
14636
  // src/hotspot/sequence-hotspot.tsx
14452
14637
  var import_fiber25 = require("@react-three/fiber");
14453
- var import_react51 = require("react");
14638
+ var import_react52 = require("react");
14454
14639
  var import_three27 = require("three");
14455
14640
  var import_jsx_runtime33 = require("react/jsx-runtime");
14456
14641
  var DEFAULT_SEQUENCE_FPS = 12;
@@ -14467,12 +14652,12 @@ function useSpriteTexture({
14467
14652
  onLoadProgress
14468
14653
  }) {
14469
14654
  const gl = (0, import_fiber25.useThree)((state) => state.gl);
14470
- const [texture, setTexture] = (0, import_react51.useState)(null);
14471
- const onErrorRef = (0, import_react51.useRef)(onError);
14472
- const onLoadProgressRef = (0, import_react51.useRef)(onLoadProgress);
14655
+ const [texture, setTexture] = (0, import_react52.useState)(null);
14656
+ const onErrorRef = (0, import_react52.useRef)(onError);
14657
+ const onLoadProgressRef = (0, import_react52.useRef)(onLoadProgress);
14473
14658
  onErrorRef.current = onError;
14474
14659
  onLoadProgressRef.current = onLoadProgress;
14475
- (0, import_react51.useEffect)(() => {
14660
+ (0, import_react52.useEffect)(() => {
14476
14661
  let active = true;
14477
14662
  setTexture(null);
14478
14663
  if (!src) {
@@ -14513,7 +14698,7 @@ function useSpriteTexture({
14513
14698
  active = false;
14514
14699
  };
14515
14700
  }, [gl, id, src]);
14516
- (0, import_react51.useEffect)(
14701
+ (0, import_react52.useEffect)(
14517
14702
  () => () => {
14518
14703
  texture?.dispose();
14519
14704
  },
@@ -14542,24 +14727,24 @@ function SequenceHotspot({
14542
14727
  const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
14543
14728
  const frameCount = resolveFrameCount(requestedFrameCount);
14544
14729
  const safeFps = resolveFps(fps);
14545
- const [frameIndex, setFrameIndex] = (0, import_react51.useState)(0);
14546
- const elapsedRef = (0, import_react51.useRef)(0);
14547
- const frameIndexRef = (0, import_react51.useRef)(0);
14548
- const endedRef = (0, import_react51.useRef)(false);
14549
- const lastPlaybackStateRef = (0, import_react51.useRef)(null);
14550
- const onFrameChangeRef = (0, import_react51.useRef)(onFrameChange);
14551
- const onPlaybackStateChangeRef = (0, import_react51.useRef)(onPlaybackStateChange);
14552
- const onEndedRef = (0, import_react51.useRef)(onEnded);
14730
+ const [frameIndex, setFrameIndex] = (0, import_react52.useState)(0);
14731
+ const elapsedRef = (0, import_react52.useRef)(0);
14732
+ const frameIndexRef = (0, import_react52.useRef)(0);
14733
+ const endedRef = (0, import_react52.useRef)(false);
14734
+ const lastPlaybackStateRef = (0, import_react52.useRef)(null);
14735
+ const onFrameChangeRef = (0, import_react52.useRef)(onFrameChange);
14736
+ const onPlaybackStateChangeRef = (0, import_react52.useRef)(onPlaybackStateChange);
14737
+ const onEndedRef = (0, import_react52.useRef)(onEnded);
14553
14738
  onFrameChangeRef.current = onFrameChange;
14554
14739
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14555
14740
  onEndedRef.current = onEnded;
14556
- (0, import_react51.useEffect)(() => {
14741
+ (0, import_react52.useEffect)(() => {
14557
14742
  elapsedRef.current = 0;
14558
14743
  frameIndexRef.current = 0;
14559
14744
  endedRef.current = false;
14560
14745
  setFrameIndex(0);
14561
14746
  }, [frameCount, frameDirection, src]);
14562
- (0, import_react51.useEffect)(() => {
14747
+ (0, import_react52.useEffect)(() => {
14563
14748
  if (!texture) {
14564
14749
  return;
14565
14750
  }
@@ -14573,13 +14758,13 @@ function SequenceHotspot({
14573
14758
  );
14574
14759
  texture.needsUpdate = true;
14575
14760
  }, [frameCount, frameDirection, frameIndex, texture]);
14576
- (0, import_react51.useEffect)(() => {
14761
+ (0, import_react52.useEffect)(() => {
14577
14762
  if (!texture) {
14578
14763
  return;
14579
14764
  }
14580
14765
  onFrameChangeRef.current?.({ id, index: 0, src });
14581
14766
  }, [id, src, texture]);
14582
- (0, import_react51.useEffect)(() => {
14767
+ (0, import_react52.useEffect)(() => {
14583
14768
  if (!texture) {
14584
14769
  return;
14585
14770
  }
@@ -14633,7 +14818,7 @@ function SequenceHotspot({
14633
14818
 
14634
14819
  // src/hotspot/video-hotspot.tsx
14635
14820
  var import_fiber26 = require("@react-three/fiber");
14636
- var import_react52 = require("react");
14821
+ var import_react53 = require("react");
14637
14822
  var import_three28 = require("three");
14638
14823
  var import_jsx_runtime34 = require("react/jsx-runtime");
14639
14824
  function clampVolume2(volume) {
@@ -14644,10 +14829,10 @@ function clampVolume2(volume) {
14644
14829
  }
14645
14830
  function usePosterTexture2(id, poster, onError) {
14646
14831
  const gl = (0, import_fiber26.useThree)((state) => state.gl);
14647
- const [texture, setTexture] = (0, import_react52.useState)(null);
14648
- const onErrorRef = (0, import_react52.useRef)(onError);
14832
+ const [texture, setTexture] = (0, import_react53.useState)(null);
14833
+ const onErrorRef = (0, import_react53.useRef)(onError);
14649
14834
  onErrorRef.current = onError;
14650
- (0, import_react52.useEffect)(() => {
14835
+ (0, import_react53.useEffect)(() => {
14651
14836
  let active = true;
14652
14837
  setTexture(null);
14653
14838
  if (!poster) {
@@ -14684,7 +14869,7 @@ function usePosterTexture2(id, poster, onError) {
14684
14869
  active = false;
14685
14870
  };
14686
14871
  }, [gl, id, poster]);
14687
- (0, import_react52.useEffect)(
14872
+ (0, import_react53.useEffect)(
14688
14873
  () => () => {
14689
14874
  texture?.dispose();
14690
14875
  },
@@ -14702,14 +14887,14 @@ function useVideoResource({
14702
14887
  poster,
14703
14888
  src
14704
14889
  }) {
14705
- const [resource, setResource] = (0, import_react52.useState)(null);
14706
- const onEndedRef = (0, import_react52.useRef)(onEnded);
14707
- const onErrorRef = (0, import_react52.useRef)(onError);
14708
- const onPlaybackStateChangeRef = (0, import_react52.useRef)(onPlaybackStateChange);
14890
+ const [resource, setResource] = (0, import_react53.useState)(null);
14891
+ const onEndedRef = (0, import_react53.useRef)(onEnded);
14892
+ const onErrorRef = (0, import_react53.useRef)(onError);
14893
+ const onPlaybackStateChangeRef = (0, import_react53.useRef)(onPlaybackStateChange);
14709
14894
  onEndedRef.current = onEnded;
14710
14895
  onErrorRef.current = onError;
14711
14896
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14712
- (0, import_react52.useEffect)(() => {
14897
+ (0, import_react53.useEffect)(() => {
14713
14898
  if (!src) {
14714
14899
  setResource(null);
14715
14900
  return;
@@ -14816,11 +15001,11 @@ function VideoHotspot({
14816
15001
  src
14817
15002
  });
14818
15003
  const posterTexture = usePosterTexture2(id, poster, onError);
14819
- const onPlaybackErrorRef = (0, import_react52.useRef)(onPlaybackError);
14820
- const onPlaybackStateChangeRef = (0, import_react52.useRef)(onPlaybackStateChange);
15004
+ const onPlaybackErrorRef = (0, import_react53.useRef)(onPlaybackError);
15005
+ const onPlaybackStateChangeRef = (0, import_react53.useRef)(onPlaybackStateChange);
14821
15006
  onPlaybackErrorRef.current = onPlaybackError;
14822
15007
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14823
- (0, import_react52.useEffect)(() => {
15008
+ (0, import_react53.useEffect)(() => {
14824
15009
  if (!resource) {
14825
15010
  return;
14826
15011
  }
@@ -14837,7 +15022,7 @@ function VideoHotspot({
14837
15022
  }
14838
15023
  resource.video.preload = preload;
14839
15024
  }, [loop, muted, playsInline, preload, resource, volume]);
14840
- (0, import_react52.useEffect)(() => {
15025
+ (0, import_react53.useEffect)(() => {
14841
15026
  if (!resource) {
14842
15027
  return;
14843
15028
  }
@@ -14865,7 +15050,7 @@ function VideoHotspot({
14865
15050
 
14866
15051
  // src/hotspot/audio-hotspot.tsx
14867
15052
  var import_fiber27 = require("@react-three/fiber");
14868
- var import_react53 = require("react");
15053
+ var import_react54 = require("react");
14869
15054
  var import_three29 = require("three");
14870
15055
  var import_jsx_runtime35 = require("react/jsx-runtime");
14871
15056
  var SPEAKER_TEXTURE_SIZE = 512;
@@ -14931,8 +15116,8 @@ function createSpeakerTexture(state) {
14931
15116
  return texture;
14932
15117
  }
14933
15118
  function useSpeakerTextures(enabled) {
14934
- const [textures, setTextures] = (0, import_react53.useState)({ playing: null, stopped: null });
14935
- (0, import_react53.useEffect)(() => {
15119
+ const [textures, setTextures] = (0, import_react54.useState)({ playing: null, stopped: null });
15120
+ (0, import_react54.useEffect)(() => {
14936
15121
  if (!enabled) {
14937
15122
  setTextures({ playing: null, stopped: null });
14938
15123
  return;
@@ -14949,10 +15134,10 @@ function useSpeakerTextures(enabled) {
14949
15134
  }
14950
15135
  function useIconTexture(icon, enabled, onError, id) {
14951
15136
  const gl = (0, import_fiber27.useThree)((state) => state.gl);
14952
- const [texture, setTexture] = (0, import_react53.useState)(null);
14953
- const onErrorRef = (0, import_react53.useRef)(onError);
15137
+ const [texture, setTexture] = (0, import_react54.useState)(null);
15138
+ const onErrorRef = (0, import_react54.useRef)(onError);
14954
15139
  onErrorRef.current = onError;
14955
- (0, import_react53.useEffect)(() => {
15140
+ (0, import_react54.useEffect)(() => {
14956
15141
  let active = true;
14957
15142
  setTexture(null);
14958
15143
  if (!enabled || !icon) {
@@ -14989,7 +15174,7 @@ function useIconTexture(icon, enabled, onError, id) {
14989
15174
  active = false;
14990
15175
  };
14991
15176
  }, [enabled, gl, icon, id]);
14992
- (0, import_react53.useEffect)(
15177
+ (0, import_react54.useEffect)(
14993
15178
  () => () => {
14994
15179
  texture?.dispose();
14995
15180
  },
@@ -15008,13 +15193,13 @@ function useAudioHowl({
15008
15193
  playing,
15009
15194
  src
15010
15195
  }) {
15011
- const [howl, setHowl] = (0, import_react53.useState)(null);
15012
- const playingRef = (0, import_react53.useRef)(playing);
15013
- const loopRef = (0, import_react53.useRef)(loop ?? false);
15014
- const onEndedRef = (0, import_react53.useRef)(onEnded);
15015
- const onErrorRef = (0, import_react53.useRef)(onError);
15016
- const onPlaybackErrorRef = (0, import_react53.useRef)(onPlaybackError);
15017
- const onPlaybackStateChangeRef = (0, import_react53.useRef)(onPlaybackStateChange);
15196
+ const [howl, setHowl] = (0, import_react54.useState)(null);
15197
+ const playingRef = (0, import_react54.useRef)(playing);
15198
+ const loopRef = (0, import_react54.useRef)(loop ?? false);
15199
+ const onEndedRef = (0, import_react54.useRef)(onEnded);
15200
+ const onErrorRef = (0, import_react54.useRef)(onError);
15201
+ const onPlaybackErrorRef = (0, import_react54.useRef)(onPlaybackError);
15202
+ const onPlaybackStateChangeRef = (0, import_react54.useRef)(onPlaybackStateChange);
15018
15203
  playingRef.current = playing;
15019
15204
  loopRef.current = loop ?? false;
15020
15205
  onEndedRef.current = onEnded;
@@ -15022,7 +15207,7 @@ function useAudioHowl({
15022
15207
  onPlaybackErrorRef.current = onPlaybackError;
15023
15208
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
15024
15209
  const sourcesKey = sourceList(src).join("\0");
15025
- (0, import_react53.useEffect)(() => {
15210
+ (0, import_react54.useEffect)(() => {
15026
15211
  const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
15027
15212
  if (sources.length === 0) {
15028
15213
  setHowl(null);
@@ -15059,7 +15244,7 @@ function useAudioHowl({
15059
15244
  handle.dispose();
15060
15245
  };
15061
15246
  }, [crossOrigin, id, sourcesKey]);
15062
- (0, import_react53.useEffect)(() => {
15247
+ (0, import_react54.useEffect)(() => {
15063
15248
  howl?.loop(loop ?? false);
15064
15249
  }, [howl, loop]);
15065
15250
  return howl;
@@ -15103,15 +15288,15 @@ function AudioHotspot({
15103
15288
  const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
15104
15289
  const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
15105
15290
  const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
15106
- const playingRef = (0, import_react53.useRef)(playing);
15291
+ const playingRef = (0, import_react54.useRef)(playing);
15107
15292
  playingRef.current = playing;
15108
- const mutedRef = (0, import_react53.useRef)(muted);
15109
- const volumeRef = (0, import_react53.useRef)(volume);
15110
- const rangeRef = (0, import_react53.useRef)(range);
15293
+ const mutedRef = (0, import_react54.useRef)(muted);
15294
+ const volumeRef = (0, import_react54.useRef)(volume);
15295
+ const rangeRef = (0, import_react54.useRef)(range);
15111
15296
  mutedRef.current = muted;
15112
15297
  volumeRef.current = volume;
15113
15298
  rangeRef.current = range;
15114
- (0, import_react53.useEffect)(() => {
15299
+ (0, import_react54.useEffect)(() => {
15115
15300
  if (!howl) {
15116
15301
  return;
15117
15302
  }
@@ -15121,7 +15306,7 @@ function AudioHotspot({
15121
15306
  }
15122
15307
  howl.play();
15123
15308
  }, [howl, playing]);
15124
- (0, import_react53.useEffect)(() => {
15309
+ (0, import_react54.useEffect)(() => {
15125
15310
  if (!howl || !pauseWhenHidden) {
15126
15311
  return;
15127
15312
  }
@@ -15156,7 +15341,7 @@ function AudioHotspot({
15156
15341
  }
15157
15342
 
15158
15343
  // src/hotspot/text-hotspot.tsx
15159
- var import_react54 = require("react");
15344
+ var import_react55 = require("react");
15160
15345
  var import_three30 = require("three");
15161
15346
  var import_jsx_runtime36 = require("react/jsx-runtime");
15162
15347
  var TEXT_TEXTURE_LONG_SIDE = 1024;
@@ -15378,12 +15563,12 @@ function createTextTexture(text, width, height, style) {
15378
15563
  return texture;
15379
15564
  }
15380
15565
  function useTextTexture(text, width, height, style, onLoad, onError) {
15381
- const [texture, setTexture] = (0, import_react54.useState)(null);
15382
- const onLoadRef = (0, import_react54.useRef)(onLoad);
15383
- const onErrorRef = (0, import_react54.useRef)(onError);
15566
+ const [texture, setTexture] = (0, import_react55.useState)(null);
15567
+ const onLoadRef = (0, import_react55.useRef)(onLoad);
15568
+ const onErrorRef = (0, import_react55.useRef)(onError);
15384
15569
  onLoadRef.current = onLoad;
15385
15570
  onErrorRef.current = onError;
15386
- (0, import_react54.useEffect)(() => {
15571
+ (0, import_react55.useEffect)(() => {
15387
15572
  let cancelled = false;
15388
15573
  let nextTexture = null;
15389
15574
  const run = async () => {