@ericchen1990/pano-view 2.5.1 → 3.0.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.mjs CHANGED
@@ -2244,12 +2244,13 @@ import { createXRStore, XR } from "@react-three/xr";
2244
2244
  import {
2245
2245
  forwardRef as forwardRef2,
2246
2246
  useCallback as useCallback6,
2247
- useContext as useContext14,
2248
- useEffect as useEffect12,
2247
+ useContext as useContext15,
2248
+ useEffect as useEffect13,
2249
2249
  useImperativeHandle as useImperativeHandle2,
2250
2250
  useMemo as useMemo7,
2251
- useRef as useRef12,
2252
- useState as useState5
2251
+ useRef as useRef13,
2252
+ useState as useState5,
2253
+ useSyncExternalStore as useSyncExternalStore6
2253
2254
  } from "react";
2254
2255
 
2255
2256
  // src/background-audio-host.ts
@@ -2294,6 +2295,107 @@ function cn(...values) {
2294
2295
  return values.filter(Boolean).join(" ");
2295
2296
  }
2296
2297
 
2298
+ // src/audio/howl.ts
2299
+ var import_howler = __toESM(require_howler());
2300
+ import_howler.Howler.autoUnlock = true;
2301
+ function resumePanoAudio() {
2302
+ if (!import_howler.Howler.ctx || import_howler.Howler.ctx.state === "running") {
2303
+ return Promise.resolve();
2304
+ }
2305
+ return import_howler.Howler.ctx.resume();
2306
+ }
2307
+ function sourceList(src) {
2308
+ if (src == null) {
2309
+ return [];
2310
+ }
2311
+ if (typeof src === "string") {
2312
+ return src ? [src] : [];
2313
+ }
2314
+ return src.filter((item) => Boolean(item));
2315
+ }
2316
+ function createUnlockingHowl({
2317
+ src,
2318
+ loop,
2319
+ crossOrigin,
2320
+ isActive,
2321
+ shouldRetryPlay,
2322
+ onEnded,
2323
+ onPlay,
2324
+ onPause,
2325
+ onLoadError,
2326
+ onPlayError
2327
+ }) {
2328
+ let disposed = false;
2329
+ let blockedNotified = false;
2330
+ const unlockListeners = [];
2331
+ const removeUnlockListeners = () => {
2332
+ for (const { type, listener } of unlockListeners) {
2333
+ window.removeEventListener(type, listener, true);
2334
+ }
2335
+ unlockListeners.length = 0;
2336
+ };
2337
+ const instance = new import_howler.Howl({
2338
+ src: [...src],
2339
+ html5: false,
2340
+ preload: true,
2341
+ loop,
2342
+ xhr: crossOrigin === "use-credentials" ? { withCredentials: true } : void 0,
2343
+ onend: () => {
2344
+ if (disposed || !isActive() || instance.loop()) {
2345
+ return;
2346
+ }
2347
+ onEnded?.();
2348
+ },
2349
+ onplay: () => {
2350
+ if (!disposed && isActive()) {
2351
+ onPlay?.();
2352
+ }
2353
+ },
2354
+ onpause: () => {
2355
+ if (!disposed && isActive()) {
2356
+ onPause?.();
2357
+ }
2358
+ },
2359
+ onloaderror: (_soundId, error) => {
2360
+ if (!disposed && isActive()) {
2361
+ onLoadError?.(error);
2362
+ }
2363
+ },
2364
+ onplayerror: (_soundId, error) => {
2365
+ if (disposed || !isActive()) {
2366
+ return;
2367
+ }
2368
+ if (!blockedNotified) {
2369
+ blockedNotified = true;
2370
+ onPlayError?.(error);
2371
+ }
2372
+ const retry = () => {
2373
+ removeUnlockListeners();
2374
+ if (!disposed && isActive() && shouldRetryPlay()) {
2375
+ void resumePanoAudio();
2376
+ instance.play();
2377
+ }
2378
+ };
2379
+ removeUnlockListeners();
2380
+ unlockListeners.push({ type: "pointerdown", listener: retry });
2381
+ unlockListeners.push({ type: "keydown", listener: retry });
2382
+ window.addEventListener("pointerdown", retry, { capture: true });
2383
+ window.addEventListener("keydown", retry, { capture: true });
2384
+ }
2385
+ });
2386
+ return {
2387
+ howl: instance,
2388
+ dispose: () => {
2389
+ if (disposed) {
2390
+ return;
2391
+ }
2392
+ disposed = true;
2393
+ removeUnlockListeners();
2394
+ instance.unload();
2395
+ }
2396
+ };
2397
+ }
2398
+
2297
2399
  // src/auto-rotate.tsx
2298
2400
  import { useFrame as useFrame2 } from "@react-three/fiber";
2299
2401
  import { useContext, useEffect as useEffect2, useRef as useRef2 } from "react";
@@ -3539,23 +3641,85 @@ function isProduction2() {
3539
3641
  return nodeEnv === "production";
3540
3642
  }
3541
3643
 
3644
+ // src/media-activation.tsx
3645
+ import { createContext as createContext7, useContext as useContext7, useEffect as useEffect6, useRef as useRef6 } from "react";
3646
+ import { jsx as jsx2 } from "react/jsx-runtime";
3647
+ var PanoMediaActivationHostContext = createContext7(null);
3648
+ function createPanoMediaActivationHost() {
3649
+ return { intents: /* @__PURE__ */ new Set(), listeners: /* @__PURE__ */ new Set(), revision: 0 };
3650
+ }
3651
+ function notify(host) {
3652
+ host.revision += 1;
3653
+ for (const listener of host.listeners) {
3654
+ listener();
3655
+ }
3656
+ }
3657
+ function getPanoMediaActivationRevision(host) {
3658
+ return host.revision;
3659
+ }
3660
+ function subscribePanoMediaActivation(host, listener) {
3661
+ host.listeners.add(listener);
3662
+ return () => {
3663
+ host.listeners.delete(listener);
3664
+ };
3665
+ }
3666
+ function hasPanoMediaActivationIntent(host) {
3667
+ return host.intents.size > 0;
3668
+ }
3669
+ function usePanoMediaActivationIntent(required) {
3670
+ const host = useContext7(PanoMediaActivationHostContext);
3671
+ const keyRef = useRef6(null);
3672
+ if (keyRef.current === null) {
3673
+ keyRef.current = /* @__PURE__ */ Symbol("pano-media-intent");
3674
+ }
3675
+ useEffect6(() => {
3676
+ if (!host || !required) {
3677
+ return;
3678
+ }
3679
+ const key = keyRef.current;
3680
+ host.intents.add(key);
3681
+ notify(host);
3682
+ return () => {
3683
+ host.intents.delete(key);
3684
+ notify(host);
3685
+ };
3686
+ }, [host, required]);
3687
+ }
3688
+ function PanoMediaActivationOverlay({
3689
+ ariaLabel = "Enable sound",
3690
+ className,
3691
+ message = "Tap to enable sound",
3692
+ onActivate
3693
+ }) {
3694
+ return /* @__PURE__ */ jsx2("div", { className: cn("pano-media-activation", className), children: /* @__PURE__ */ jsx2(
3695
+ "button",
3696
+ {
3697
+ "aria-label": ariaLabel,
3698
+ className: "pano-media-activation-button",
3699
+ onClick: onActivate,
3700
+ type: "button",
3701
+ children: message
3702
+ }
3703
+ ) });
3704
+ }
3705
+
3542
3706
  // src/pano-context-menu.tsx
3543
3707
  import {
3544
- createContext as createContext7,
3708
+ createContext as createContext8,
3545
3709
  useCallback as useCallback2,
3546
- useContext as useContext7,
3547
- useEffect as useEffect6,
3710
+ useContext as useContext8,
3711
+ useEffect as useEffect7,
3548
3712
  useId,
3549
3713
  useLayoutEffect,
3550
3714
  useMemo as useMemo3,
3551
- useRef as useRef6,
3715
+ useRef as useRef7,
3552
3716
  useState as useState2
3553
3717
  } from "react";
3554
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
3718
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
3555
3719
  var DEFAULT_ICON_SIZE = 16;
3556
3720
  var MENU_EDGE_PADDING = 8;
3557
3721
  var MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY = 0.4;
3558
- var PanoContextMenuOverlayContext = createContext7(null);
3722
+ var PanoContextMenuOverlayContext = createContext8(null);
3559
3723
  var DEFAULT_APPEARANCE = {
3560
3724
  background: "#161616",
3561
3725
  color: "#f4f4f4",
@@ -3595,7 +3759,7 @@ function DefaultContextMenuPanel({
3595
3759
  selectContext,
3596
3760
  onRequestClose
3597
3761
  }) {
3598
- const menuRef = useRef6(null);
3762
+ const menuRef = useRef7(null);
3599
3763
  const [activeIndex, setActiveIndex] = useState2(0);
3600
3764
  const resolved = { ...DEFAULT_APPEARANCE, ...appearance };
3601
3765
  const iconSize = Number.isFinite(resolved.iconSize) ? Math.max(0, resolved.iconSize) : DEFAULT_ICON_SIZE;
@@ -3617,7 +3781,7 @@ function DefaultContextMenuPanel({
3617
3781
  });
3618
3782
  return indices;
3619
3783
  }, [visibleItems]);
3620
- useEffect6(() => {
3784
+ useEffect7(() => {
3621
3785
  const first = focusableIndices[0];
3622
3786
  setActiveIndex(first ?? 0);
3623
3787
  const frame = requestAnimationFrame(() => {
@@ -3725,7 +3889,7 @@ function DefaultContextMenuPanel({
3725
3889
  style: panelStyle,
3726
3890
  tabIndex: -1,
3727
3891
  children: [
3728
- /* @__PURE__ */ jsx2(
3892
+ /* @__PURE__ */ jsx3(
3729
3893
  "div",
3730
3894
  {
3731
3895
  "aria-hidden": true,
@@ -3737,9 +3901,9 @@ function DefaultContextMenuPanel({
3737
3901
  }
3738
3902
  }
3739
3903
  ),
3740
- /* @__PURE__ */ jsx2("div", { className: "pano-context-menu-items", children: visibleItems.map((item, index) => {
3904
+ /* @__PURE__ */ jsx3("div", { className: "pano-context-menu-items", children: visibleItems.map((item, index) => {
3741
3905
  if (!isActionItem(item)) {
3742
- return /* @__PURE__ */ jsx2(
3906
+ return /* @__PURE__ */ jsx3(
3743
3907
  "div",
3744
3908
  {
3745
3909
  "aria-hidden": true,
@@ -3756,7 +3920,7 @@ function DefaultContextMenuPanel({
3756
3920
  );
3757
3921
  }
3758
3922
  const disabled = item.disabled === true;
3759
- const iconNode = item.icon ?? (item.image ? /* @__PURE__ */ jsx2(
3923
+ const iconNode = item.icon ?? (item.image ? /* @__PURE__ */ jsx3(
3760
3924
  "img",
3761
3925
  {
3762
3926
  alt: item.imageAlt ?? "",
@@ -3806,7 +3970,7 @@ function DefaultContextMenuPanel({
3806
3970
  tabIndex: disabled ? -1 : activeIndex === index ? 0 : -1,
3807
3971
  type: "button",
3808
3972
  children: [
3809
- /* @__PURE__ */ jsx2(
3973
+ /* @__PURE__ */ jsx3(
3810
3974
  "span",
3811
3975
  {
3812
3976
  "aria-hidden": true,
@@ -3818,7 +3982,7 @@ function DefaultContextMenuPanel({
3818
3982
  children: iconNode
3819
3983
  }
3820
3984
  ),
3821
- /* @__PURE__ */ jsx2("span", { style: { flex: 1 }, children: item.label })
3985
+ /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: item.label })
3822
3986
  ]
3823
3987
  },
3824
3988
  item.id
@@ -3834,8 +3998,21 @@ function PositionedMenuShell({
3834
3998
  overlayElement,
3835
3999
  children
3836
4000
  }) {
3837
- const shellRef = useRef6(null);
4001
+ const shellRef = useRef7(null);
3838
4002
  const [offset, setOffset] = useState2({ left: 0, top: 0 });
4003
+ const [viewportRevision, setViewportRevision] = useState2(0);
4004
+ useEffect7(() => {
4005
+ const refresh = () => setViewportRevision((revision) => revision + 1);
4006
+ const viewport = window.visualViewport;
4007
+ window.addEventListener("resize", refresh);
4008
+ window.addEventListener("orientationchange", refresh);
4009
+ viewport?.addEventListener("resize", refresh);
4010
+ return () => {
4011
+ window.removeEventListener("resize", refresh);
4012
+ window.removeEventListener("orientationchange", refresh);
4013
+ viewport?.removeEventListener("resize", refresh);
4014
+ };
4015
+ }, []);
3839
4016
  useLayoutEffect(() => {
3840
4017
  const shell = shellRef.current;
3841
4018
  if (!overlayElement || !shell) {
@@ -3857,8 +4034,8 @@ function PositionedMenuShell({
3857
4034
  left: Math.min(Math.max(rawLeft, MENU_EDGE_PADDING), maxLeft),
3858
4035
  top: Math.min(Math.max(rawTop, MENU_EDGE_PADDING), maxTop)
3859
4036
  });
3860
- }, [clientX, clientY, overlayElement, children]);
3861
- return /* @__PURE__ */ jsx2(
4037
+ }, [clientX, clientY, overlayElement, children, viewportRevision]);
4038
+ return /* @__PURE__ */ jsx3(
3862
4039
  "div",
3863
4040
  {
3864
4041
  className: "pano-context-menu-shell",
@@ -3873,7 +4050,7 @@ function PositionedMenuShell({
3873
4050
  }
3874
4051
  function usePanoContextMenuOverlay() {
3875
4052
  const [session2, setSession] = useState2(null);
3876
- const overlayRef = useRef6(null);
4053
+ const overlayRef = useRef7(null);
3877
4054
  const [overlayElement, setOverlayElement] = useState2(
3878
4055
  null
3879
4056
  );
@@ -3885,7 +4062,7 @@ function usePanoContextMenuOverlay() {
3885
4062
  overlayRef.current = node;
3886
4063
  setOverlayElement(node);
3887
4064
  }, []);
3888
- useEffect6(() => {
4065
+ useEffect7(() => {
3889
4066
  if (!session2) {
3890
4067
  return;
3891
4068
  }
@@ -3917,7 +4094,7 @@ function usePanoContextMenuOverlay() {
3917
4094
  document.removeEventListener("keydown", handleKeyDown);
3918
4095
  };
3919
4096
  }, [session2]);
3920
- const overlay = /* @__PURE__ */ jsx2(
4097
+ const overlay = /* @__PURE__ */ jsx3(
3921
4098
  "div",
3922
4099
  {
3923
4100
  ref: setOverlayNode,
@@ -3928,7 +4105,7 @@ function usePanoContextMenuOverlay() {
3928
4105
  position: "absolute",
3929
4106
  zIndex: 20
3930
4107
  },
3931
- children: session2 ? /* @__PURE__ */ jsx2(
4108
+ children: session2 ? /* @__PURE__ */ jsx3(
3932
4109
  PositionedMenuShell,
3933
4110
  {
3934
4111
  clientX: session2.event.clientX,
@@ -3953,13 +4130,13 @@ function PanoContextMenu({
3953
4130
  separatorClassName,
3954
4131
  children
3955
4132
  }) {
3956
- const eventBus = useContext7(PanoEventBusContext);
3957
- const controlsRef = useContext7(PanoramaViewContext);
3958
- const overlayApi = useContext7(PanoContextMenuOverlayContext);
3959
- const actions = useContext7(PanoContextMenuActionsContext);
4133
+ const eventBus = useContext8(PanoEventBusContext);
4134
+ const controlsRef = useContext8(PanoramaViewContext);
4135
+ const overlayApi = useContext8(PanoContextMenuOverlayContext);
4136
+ const actions = useContext8(PanoContextMenuActionsContext);
3960
4137
  const instanceId = useId();
3961
- const sessionKeyRef = useRef6(0);
3962
- const propsRef = useRef6({
4138
+ const sessionKeyRef = useRef7(0);
4139
+ const propsRef = useRef7({
3963
4140
  items,
3964
4141
  prepend,
3965
4142
  append,
@@ -4021,9 +4198,9 @@ function PanoContextMenu({
4021
4198
  view,
4022
4199
  render: () => {
4023
4200
  if (hasCustomChildren && current.children) {
4024
- return /* @__PURE__ */ jsx2("div", { "data-pano-context-menu": true, style: { pointerEvents: "auto" }, children: current.children({ event, view, close }) });
4201
+ return /* @__PURE__ */ jsx3("div", { "data-pano-context-menu": true, style: { pointerEvents: "auto" }, children: current.children({ event, view, close }) });
4025
4202
  }
4026
- return /* @__PURE__ */ jsx2(
4203
+ return /* @__PURE__ */ jsx3(
4027
4204
  DefaultContextMenuPanel,
4028
4205
  {
4029
4206
  appearance: current.appearance,
@@ -4041,7 +4218,7 @@ function PanoContextMenu({
4041
4218
  },
4042
4219
  [actions, close, controlsRef, instanceId, overlayApi]
4043
4220
  );
4044
- useEffect6(() => {
4221
+ useEffect7(() => {
4045
4222
  const unsubscribeContextMenu = eventBus.subscribe(
4046
4223
  "contextmenu",
4047
4224
  openMenu
@@ -4074,14 +4251,14 @@ function ResetViewIcon() {
4074
4251
  viewBox: "0 0 16 16",
4075
4252
  width: "100%",
4076
4253
  children: [
4077
- /* @__PURE__ */ jsx2("path", { d: "M3.5 6.5A4.5 4.5 0 1 1 4 10" }),
4078
- /* @__PURE__ */ jsx2("path", { d: "M3.5 3.5v3h3" })
4254
+ /* @__PURE__ */ jsx3("path", { d: "M3.5 6.5A4.5 4.5 0 1 1 4 10" }),
4255
+ /* @__PURE__ */ jsx3("path", { d: "M3.5 3.5v3h3" })
4079
4256
  ]
4080
4257
  }
4081
4258
  );
4082
4259
  }
4083
4260
  function FullscreenIcon() {
4084
- return /* @__PURE__ */ jsx2(
4261
+ return /* @__PURE__ */ jsx3(
4085
4262
  "svg",
4086
4263
  {
4087
4264
  "aria-hidden": true,
@@ -4093,12 +4270,12 @@ function FullscreenIcon() {
4093
4270
  strokeWidth: "1.75",
4094
4271
  viewBox: "0 0 16 16",
4095
4272
  width: "100%",
4096
- children: /* @__PURE__ */ jsx2("path", { d: "M3 6V3h3M10 3h3v3M13 10v3h-3M6 13H3v-3" })
4273
+ children: /* @__PURE__ */ jsx3("path", { d: "M3 6V3h3M10 3h3v3M13 10v3h-3M6 13H3v-3" })
4097
4274
  }
4098
4275
  );
4099
4276
  }
4100
4277
  function ExitFullscreenIcon() {
4101
- return /* @__PURE__ */ jsx2(
4278
+ return /* @__PURE__ */ jsx3(
4102
4279
  "svg",
4103
4280
  {
4104
4281
  "aria-hidden": true,
@@ -4110,7 +4287,7 @@ function ExitFullscreenIcon() {
4110
4287
  strokeWidth: "1.75",
4111
4288
  viewBox: "0 0 16 16",
4112
4289
  width: "100%",
4113
- children: /* @__PURE__ */ jsx2("path", { d: "M6 3v3H3M10 3v3h3M3 10h3v3M10 10h3v3" })
4290
+ children: /* @__PURE__ */ jsx3("path", { d: "M6 3v3H3M10 3v3h3M3 10h3v3M10 10h3v3" })
4114
4291
  }
4115
4292
  );
4116
4293
  }
@@ -4119,7 +4296,7 @@ function createPanoContextMenuPresets(actions) {
4119
4296
  const resetView = {
4120
4297
  id: "pano-reset-view",
4121
4298
  label: "Reset view",
4122
- icon: /* @__PURE__ */ jsx2(ResetViewIcon, {}),
4299
+ icon: /* @__PURE__ */ jsx3(ResetViewIcon, {}),
4123
4300
  onSelect: () => {
4124
4301
  actions.reset();
4125
4302
  }
@@ -4127,7 +4304,7 @@ function createPanoContextMenuPresets(actions) {
4127
4304
  const fullscreen = {
4128
4305
  id: "pano-fullscreen",
4129
4306
  label: isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
4130
- icon: isFullscreen ? /* @__PURE__ */ jsx2(ExitFullscreenIcon, {}) : /* @__PURE__ */ jsx2(FullscreenIcon, {}),
4307
+ icon: isFullscreen ? /* @__PURE__ */ jsx3(ExitFullscreenIcon, {}) : /* @__PURE__ */ jsx3(FullscreenIcon, {}),
4131
4308
  onSelect: () => {
4132
4309
  actions.toggleFullscreen();
4133
4310
  }
@@ -4220,19 +4397,19 @@ function composePanoContextMenuItems(props, presets) {
4220
4397
  ...resolvePanoContextMenuEntries(props.append ?? [], presets)
4221
4398
  ];
4222
4399
  }
4223
- var PanoContextMenuActionsContext = createContext7(null);
4400
+ var PanoContextMenuActionsContext = createContext8(null);
4224
4401
 
4225
4402
  // src/pano-cursor.tsx
4226
4403
  import { useThree as useThree4 } from "@react-three/fiber";
4227
4404
  import {
4228
- createContext as createContext8,
4405
+ createContext as createContext9,
4229
4406
  useCallback as useCallback3,
4230
- useContext as useContext8,
4231
- useEffect as useEffect7,
4407
+ useContext as useContext9,
4408
+ useEffect as useEffect8,
4232
4409
  useMemo as useMemo4,
4233
- useRef as useRef7
4410
+ useRef as useRef8
4234
4411
  } from "react";
4235
- import { jsx as jsx3 } from "react/jsx-runtime";
4412
+ import { jsx as jsx4 } from "react/jsx-runtime";
4236
4413
  var DEFAULT_PANO_CURSORS = {
4237
4414
  default: "grab",
4238
4415
  dragging: "grabbing",
@@ -4246,9 +4423,9 @@ var LAYER_PRIORITY = {
4246
4423
  hotspotDragging: 3,
4247
4424
  hidden: 4
4248
4425
  };
4249
- var PanoCursorContext = createContext8(null);
4426
+ var PanoCursorContext = createContext9(null);
4250
4427
  function usePanoCursor() {
4251
- return useContext8(PanoCursorContext);
4428
+ return useContext9(PanoCursorContext);
4252
4429
  }
4253
4430
  function hotspotCursorClaimId(id) {
4254
4431
  return `pano-cursor:hotspot:${id}`;
@@ -4300,10 +4477,10 @@ function PanoCursorController({
4300
4477
  children
4301
4478
  }) {
4302
4479
  const { gl } = useThree4();
4303
- const eventBus = useContext8(PanoEventBusContext);
4304
- const claimsRef = useRef7(/* @__PURE__ */ new Map());
4305
- const cursorsRef = useRef7(cursors);
4306
- const appliedCursorRef = useRef7(null);
4480
+ const eventBus = useContext9(PanoEventBusContext);
4481
+ const claimsRef = useRef8(/* @__PURE__ */ new Map());
4482
+ const cursorsRef = useRef8(cursors);
4483
+ const appliedCursorRef = useRef8(null);
4307
4484
  cursorsRef.current = cursors;
4308
4485
  const applyCursor = useCallback3(() => {
4309
4486
  const next = resolveHighestCursor(claimsRef.current, cursorsRef.current);
@@ -4337,7 +4514,7 @@ function PanoCursorController({
4337
4514
  }),
4338
4515
  [claim, cursors, release]
4339
4516
  );
4340
- useEffect7(() => {
4517
+ useEffect8(() => {
4341
4518
  const element = gl.domElement;
4342
4519
  const previous = element.style.cursor;
4343
4520
  return () => {
@@ -4346,10 +4523,10 @@ function PanoCursorController({
4346
4523
  element.style.cursor = previous;
4347
4524
  };
4348
4525
  }, [gl]);
4349
- useEffect7(() => {
4526
+ useEffect8(() => {
4350
4527
  applyCursor();
4351
4528
  }, [applyCursor, cursors]);
4352
- useEffect7(() => {
4529
+ useEffect8(() => {
4353
4530
  if (!eventBus) {
4354
4531
  return;
4355
4532
  }
@@ -4374,12 +4551,12 @@ function PanoCursorController({
4374
4551
  release(PANO_DRAG_CLAIM_ID);
4375
4552
  };
4376
4553
  }, [claim, eventBus, release]);
4377
- return /* @__PURE__ */ jsx3(PanoCursorContext.Provider, { value: api, children });
4554
+ return /* @__PURE__ */ jsx4(PanoCursorContext.Provider, { value: api, children });
4378
4555
  }
4379
4556
 
4380
4557
  // src/pano-events.tsx
4381
4558
  import { useFrame as useFrame4, useThree as useThree5 } from "@react-three/fiber";
4382
- import { useContext as useContext9, useEffect as useEffect8, useRef as useRef8 } from "react";
4559
+ import { useContext as useContext10, useEffect as useEffect9, useRef as useRef9 } from "react";
4383
4560
  var DEFAULT_IDLE_TIME_MS = 2e3;
4384
4561
  function resolveIdleTime(value) {
4385
4562
  return Number.isFinite(value) && value >= 0 ? value : DEFAULT_IDLE_TIME_MS;
@@ -4417,13 +4594,13 @@ function usePanoEvents({
4417
4594
  onVRDenied,
4418
4595
  onVRUnknownDevice
4419
4596
  }) {
4420
- const eventBus = useContext9(PanoEventBusContext);
4421
- const controlsRef = useContext9(PanoramaViewContext);
4597
+ const eventBus = useContext10(PanoEventBusContext);
4598
+ const controlsRef = useContext10(PanoramaViewContext);
4422
4599
  const { gl } = useThree5();
4423
4600
  if (!eventBus || !controlsRef) {
4424
4601
  throw new Error("usePanoEvents must be used inside <PanoViewer>.");
4425
4602
  }
4426
- const callbacksRef = useRef8({
4603
+ const callbacksRef = useRef9({
4427
4604
  onViewChange,
4428
4605
  onViewSettled,
4429
4606
  onViewInteractionStart,
@@ -4487,15 +4664,15 @@ function usePanoEvents({
4487
4664
  onVRDenied,
4488
4665
  onVRUnknownDevice
4489
4666
  };
4490
- const idleElapsedRef = useRef8(0);
4491
- const isIdleRef = useRef8(false);
4492
- const idleTimeRef = useRef8(resolveIdleTime(idleTime));
4667
+ const idleElapsedRef = useRef9(0);
4668
+ const isIdleRef = useRef9(false);
4669
+ const idleTimeRef = useRef9(resolveIdleTime(idleTime));
4493
4670
  idleTimeRef.current = resolveIdleTime(idleTime);
4494
- useEffect8(() => {
4671
+ useEffect9(() => {
4495
4672
  idleElapsedRef.current = 0;
4496
4673
  isIdleRef.current = false;
4497
4674
  }, [idleTime]);
4498
- useEffect8(() => {
4675
+ useEffect9(() => {
4499
4676
  const unsubscribers = [
4500
4677
  eventBus.subscribe("viewchange", (view) => {
4501
4678
  callbacksRef.current.onViewChange?.(view);
@@ -4576,7 +4753,7 @@ function usePanoEvents({
4576
4753
  }
4577
4754
  };
4578
4755
  }, [eventBus]);
4579
- useEffect8(() => {
4756
+ useEffect9(() => {
4580
4757
  const element = gl.domElement;
4581
4758
  const handleWheel = (nativeEvent) => {
4582
4759
  callbacksRef.current.onWheel?.({
@@ -4589,7 +4766,7 @@ function usePanoEvents({
4589
4766
  element.removeEventListener("wheel", handleWheel);
4590
4767
  };
4591
4768
  }, [gl]);
4592
- useEffect8(() => {
4769
+ useEffect9(() => {
4593
4770
  if (typeof document === "undefined") {
4594
4771
  return;
4595
4772
  }
@@ -4615,7 +4792,7 @@ function usePanoEvents({
4615
4792
  wasFullscreenRef.current = isViewerFullscreen();
4616
4793
  return subscribeFullscreenChange(handleFullscreenChange);
4617
4794
  }, [gl]);
4618
- useEffect8(() => {
4795
+ useEffect9(() => {
4619
4796
  const element = gl.domElement;
4620
4797
  if (typeof ResizeObserver === "undefined") {
4621
4798
  return;
@@ -4657,7 +4834,7 @@ function PanoEvents(props) {
4657
4834
 
4658
4835
  // src/panorama-event-surface.tsx
4659
4836
  import { useThree as useThree6 } from "@react-three/fiber";
4660
- import { useContext as useContext10, useEffect as useEffect9 } from "react";
4837
+ import { useContext as useContext11, useEffect as useEffect10 } from "react";
4661
4838
  import { BackSide, Raycaster, Vector2, Vector3 as Vector32 } from "three";
4662
4839
 
4663
4840
  // src/hotspot/coordinates.ts
@@ -4735,7 +4912,7 @@ var DEFAULT_PANORAMA_CAMERA_NEAR = 0.1;
4735
4912
  var DEFAULT_PANORAMA_CAMERA_FAR = DEFAULT_PANORAMA_RADIUS * 2;
4736
4913
 
4737
4914
  // src/panorama-event-surface.tsx
4738
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
4915
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
4739
4916
  var EVENT_SURFACE_RADIUS = DEFAULT_PANORAMA_RADIUS - 1;
4740
4917
  function makePanoramaPointerEvent(event) {
4741
4918
  const nativeEvent = event.nativeEvent;
@@ -4750,9 +4927,9 @@ function makePanoramaPointerEvent(event) {
4750
4927
  };
4751
4928
  }
4752
4929
  function PanoramaEventSurface() {
4753
- const eventBus = useContext10(PanoEventBusContext);
4930
+ const eventBus = useContext11(PanoEventBusContext);
4754
4931
  const { camera, gl } = useThree6();
4755
- useEffect9(() => {
4932
+ useEffect10(() => {
4756
4933
  if (!eventBus) {
4757
4934
  return;
4758
4935
  }
@@ -4803,8 +4980,8 @@ function PanoramaEventSurface() {
4803
4980
  onPointerUp: (event) => emit("pointerup", event),
4804
4981
  onPointerMove: (event) => emit("pointermove", event),
4805
4982
  children: [
4806
- /* @__PURE__ */ jsx4("sphereGeometry", { args: [EVENT_SURFACE_RADIUS, 64, 32] }),
4807
- /* @__PURE__ */ jsx4(
4983
+ /* @__PURE__ */ jsx5("sphereGeometry", { args: [EVENT_SURFACE_RADIUS, 64, 32] }),
4984
+ /* @__PURE__ */ jsx5(
4808
4985
  "meshBasicMaterial",
4809
4986
  {
4810
4987
  colorWrite: false,
@@ -4821,8 +4998,8 @@ function PanoramaEventSurface() {
4821
4998
  }
4822
4999
 
4823
5000
  // src/scenes-host.ts
4824
- import { createContext as createContext9 } from "react";
4825
- var ScenesHostContext = createContext9(null);
5001
+ import { createContext as createContext10 } from "react";
5002
+ var ScenesHostContext = createContext10(null);
4826
5003
  function createScenesHost() {
4827
5004
  return {
4828
5005
  controller: null,
@@ -4839,7 +5016,7 @@ function notifyScenesHost(host) {
4839
5016
 
4840
5017
  // src/touch-controls.tsx
4841
5018
  import { useThree as useThree7 } from "@react-three/fiber";
4842
- import { useContext as useContext11, useEffect as useEffect10, useRef as useRef9 } from "react";
5019
+ import { useContext as useContext12, useEffect as useEffect11, useRef as useRef10 } from "react";
4843
5020
  var DEFAULT_ROTATE_SPEED3 = 0.35;
4844
5021
  function resolveSpeed3(value, fallback) {
4845
5022
  return Number.isFinite(value) && value >= 0 ? value : fallback;
@@ -4854,16 +5031,16 @@ function TouchControls({
4854
5031
  pinchZoom = true
4855
5032
  }) {
4856
5033
  useClaimControlChannel("touch");
4857
- const controlsRef = useContext11(PanoramaViewContext);
5034
+ const controlsRef = useContext12(PanoramaViewContext);
4858
5035
  const { gl } = useThree7();
4859
- const pointersRef = useRef9(/* @__PURE__ */ new Map());
4860
- const pinchDistanceRef = useRef9(null);
4861
- const optionsRef = useRef9({ rotateSpeed, invert, pinchZoom });
5036
+ const pointersRef = useRef10(/* @__PURE__ */ new Map());
5037
+ const pinchDistanceRef = useRef10(null);
5038
+ const optionsRef = useRef10({ rotateSpeed, invert, pinchZoom });
4862
5039
  if (!controlsRef) {
4863
5040
  throw new Error("<TouchControls> must be rendered inside <PanoViewer>.");
4864
5041
  }
4865
5042
  optionsRef.current = { rotateSpeed, invert, pinchZoom };
4866
- useEffect10(() => {
5043
+ useEffect11(() => {
4867
5044
  const element = gl.domElement;
4868
5045
  const clearPointers = () => {
4869
5046
  for (const pointerId of pointersRef.current.keys()) {
@@ -4985,9 +5162,9 @@ function TouchControls({
4985
5162
  }
4986
5163
 
4987
5164
  // src/video/chrome-overlay.tsx
4988
- import { createContext as createContext10, useCallback as useCallback4, useMemo as useMemo5, useState as useState3 } from "react";
4989
- import { jsx as jsx5 } from "react/jsx-runtime";
4990
- var PanoChromeOverlayContext = createContext10(null);
5165
+ import { createContext as createContext11, useCallback as useCallback4, useMemo as useMemo5, useState as useState3 } from "react";
5166
+ import { jsx as jsx6 } from "react/jsx-runtime";
5167
+ var PanoChromeOverlayContext = createContext11(null);
4991
5168
  function usePanoChromeOverlay() {
4992
5169
  const [overlayElement, setOverlayElement] = useState3(
4993
5170
  null
@@ -4999,7 +5176,7 @@ function usePanoChromeOverlay() {
4999
5176
  () => ({ overlayElement }),
5000
5177
  [overlayElement]
5001
5178
  );
5002
- const overlay = /* @__PURE__ */ jsx5(
5179
+ const overlay = /* @__PURE__ */ jsx6(
5003
5180
  "div",
5004
5181
  {
5005
5182
  className: "pano-chrome-overlay",
@@ -5011,9 +5188,9 @@ function usePanoChromeOverlay() {
5011
5188
  }
5012
5189
 
5013
5190
  // src/video/host.ts
5014
- import { createContext as createContext11, useContext as useContext12 } from "react";
5015
- var PanoVideoHostContext = createContext11(null);
5016
- var DefaultPanoVideoControlsContext = createContext11(false);
5191
+ import { createContext as createContext12, useContext as useContext13 } from "react";
5192
+ var PanoVideoHostContext = createContext12(null);
5193
+ var DefaultPanoVideoControlsContext = createContext12(false);
5017
5194
  function createPanoVideoHost() {
5018
5195
  return {
5019
5196
  controller: null,
@@ -5058,8 +5235,8 @@ function isProduction3() {
5058
5235
  return nodeEnv === "production";
5059
5236
  }
5060
5237
  function useClaimPanoVideoControls() {
5061
- const host = useContext12(PanoVideoHostContext);
5062
- const isDefault = useContext12(DefaultPanoVideoControlsContext);
5238
+ const host = useContext13(PanoVideoHostContext);
5239
+ const isDefault = useContext13(DefaultPanoVideoControlsContext);
5063
5240
  if (!host || isDefault) {
5064
5241
  return;
5065
5242
  }
@@ -5076,7 +5253,7 @@ import { useSyncExternalStore as useSyncExternalStore4 } from "react";
5076
5253
 
5077
5254
  // src/video/pano-video-captions.tsx
5078
5255
  import { useSyncExternalStore as useSyncExternalStore2 } from "react";
5079
- import { jsx as jsx6 } from "react/jsx-runtime";
5256
+ import { jsx as jsx7 } from "react/jsx-runtime";
5080
5257
  var DEFAULT_PANO_VIDEO_CAPTION_APPEARANCE = {
5081
5258
  color: "#ffffff",
5082
5259
  background: "rgba(0, 0, 0, 0.55)",
@@ -5124,13 +5301,13 @@ function PanoVideoCaptionsOverlay({
5124
5301
  textShadow: snapshot.captionAppearance.textShadow,
5125
5302
  whiteSpace: "pre-wrap"
5126
5303
  };
5127
- return /* @__PURE__ */ jsx6(
5304
+ return /* @__PURE__ */ jsx7(
5128
5305
  "div",
5129
5306
  {
5130
5307
  className: "pano-video-captions",
5131
5308
  "data-pano-video-captions": "",
5132
5309
  style: wrapperStyle,
5133
- children: /* @__PURE__ */ jsx6("div", { style: textStyle, children: snapshot.captionText })
5310
+ children: /* @__PURE__ */ jsx7("div", { style: textStyle, children: snapshot.captionText })
5134
5311
  }
5135
5312
  );
5136
5313
  }
@@ -5143,11 +5320,11 @@ function PanoVideoCaptions({
5143
5320
  // src/video/pano-video-controls.tsx
5144
5321
  import {
5145
5322
  useCallback as useCallback5,
5146
- useContext as useContext13,
5147
- useEffect as useEffect11,
5323
+ useContext as useContext14,
5324
+ useEffect as useEffect12,
5148
5325
  useId as useId2,
5149
5326
  useMemo as useMemo6,
5150
- useRef as useRef10,
5327
+ useRef as useRef11,
5151
5328
  useState as useState4,
5152
5329
  useSyncExternalStore as useSyncExternalStore3
5153
5330
  } from "react";
@@ -5282,7 +5459,7 @@ function cueText(cue) {
5282
5459
  }
5283
5460
 
5284
5461
  // src/video/pano-video-controls.tsx
5285
- import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
5462
+ import { Fragment, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
5286
5463
  var DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE = {
5287
5464
  background: "rgba(16, 16, 16, 0.88)",
5288
5465
  color: "#f4f4f4",
@@ -5343,7 +5520,7 @@ function volumeFromClientY(clientY, track) {
5343
5520
  return Math.max(0, Math.min(1, (rect.bottom - clientY) / rect.height));
5344
5521
  }
5345
5522
  function Icon({ path }) {
5346
- return /* @__PURE__ */ jsx7(
5523
+ return /* @__PURE__ */ jsx8(
5347
5524
  "svg",
5348
5525
  {
5349
5526
  "aria-hidden": true,
@@ -5355,7 +5532,7 @@ function Icon({ path }) {
5355
5532
  strokeWidth: "1.75",
5356
5533
  viewBox: "0 0 16 16",
5357
5534
  width: "16",
5358
- children: /* @__PURE__ */ jsx7("path", { d: path })
5535
+ children: /* @__PURE__ */ jsx8("path", { d: path })
5359
5536
  }
5360
5537
  );
5361
5538
  }
@@ -5367,7 +5544,7 @@ function ChromeButton({
5367
5544
  label,
5368
5545
  onClick
5369
5546
  }) {
5370
- return /* @__PURE__ */ jsx7(
5547
+ return /* @__PURE__ */ jsx8(
5371
5548
  "button",
5372
5549
  {
5373
5550
  "aria-label": label,
@@ -5393,14 +5570,14 @@ function ChromeMenu({
5393
5570
  labelledBy,
5394
5571
  items
5395
5572
  }) {
5396
- return /* @__PURE__ */ jsx7(
5573
+ return /* @__PURE__ */ jsx8(
5397
5574
  ChromeMenuSurface,
5398
5575
  {
5399
5576
  appearance,
5400
5577
  id,
5401
5578
  labelledBy,
5402
5579
  role: "menu",
5403
- children: items.map((item) => /* @__PURE__ */ jsx7(
5580
+ children: items.map((item) => /* @__PURE__ */ jsx8(
5404
5581
  ChromeMenuRadioItem,
5405
5582
  {
5406
5583
  active: item.active,
@@ -5420,7 +5597,7 @@ function ChromeMenuSurface({
5420
5597
  labelledBy,
5421
5598
  role
5422
5599
  }) {
5423
- return /* @__PURE__ */ jsx7(
5600
+ return /* @__PURE__ */ jsx8(
5424
5601
  "div",
5425
5602
  {
5426
5603
  "aria-labelledby": labelledBy,
@@ -5444,7 +5621,7 @@ function ChromeMenuRadioItem({
5444
5621
  label,
5445
5622
  onClick
5446
5623
  }) {
5447
- return /* @__PURE__ */ jsx7(
5624
+ return /* @__PURE__ */ jsx8(
5448
5625
  "button",
5449
5626
  {
5450
5627
  "aria-checked": active,
@@ -5484,7 +5661,7 @@ function ChromeMenuActionItem({
5484
5661
  },
5485
5662
  type: "button",
5486
5663
  children: [
5487
- /* @__PURE__ */ jsx7("span", { children: label }),
5664
+ /* @__PURE__ */ jsx8("span", { children: label }),
5488
5665
  secondary
5489
5666
  ]
5490
5667
  }
@@ -5493,10 +5670,10 @@ function ChromeMenuActionItem({
5493
5670
  function ChromeMenuSectionLabel({
5494
5671
  children
5495
5672
  }) {
5496
- return /* @__PURE__ */ jsx7("div", { className: "pano-video-chrome-menu-label", children });
5673
+ return /* @__PURE__ */ jsx8("div", { className: "pano-video-chrome-menu-label", children });
5497
5674
  }
5498
5675
  function ChromeMenuDivider() {
5499
- return /* @__PURE__ */ jsx7("div", { className: "pano-video-chrome-menu-divider" });
5676
+ return /* @__PURE__ */ jsx8("div", { className: "pano-video-chrome-menu-divider" });
5500
5677
  }
5501
5678
  function CaptionsMenu({
5502
5679
  appearance,
@@ -5509,7 +5686,7 @@ function CaptionsMenu({
5509
5686
  panel,
5510
5687
  snapshot
5511
5688
  }) {
5512
- return /* @__PURE__ */ jsx7(
5689
+ return /* @__PURE__ */ jsx8(
5513
5690
  ChromeMenuSurface,
5514
5691
  {
5515
5692
  appearance,
@@ -5518,7 +5695,7 @@ function CaptionsMenu({
5518
5695
  role: "menu",
5519
5696
  children: panel === "tracks" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
5520
5697
  /* @__PURE__ */ jsxs3("div", { className: "pano-video-chrome-menu-list", children: [
5521
- /* @__PURE__ */ jsx7(
5698
+ /* @__PURE__ */ jsx8(
5522
5699
  ChromeMenuRadioItem,
5523
5700
  {
5524
5701
  active: snapshot.trackId === null,
@@ -5531,7 +5708,7 @@ function CaptionsMenu({
5531
5708
  ),
5532
5709
  snapshot.tracks.map((track) => {
5533
5710
  const trackItemId = panoVideoTrackId(track);
5534
- return /* @__PURE__ */ jsx7(
5711
+ return /* @__PURE__ */ jsx8(
5535
5712
  ChromeMenuRadioItem,
5536
5713
  {
5537
5714
  active: snapshot.trackId === trackItemId,
@@ -5545,29 +5722,29 @@ function CaptionsMenu({
5545
5722
  );
5546
5723
  })
5547
5724
  ] }),
5548
- /* @__PURE__ */ jsx7(ChromeMenuDivider, {}),
5549
- /* @__PURE__ */ jsx7(
5725
+ /* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
5726
+ /* @__PURE__ */ jsx8(
5550
5727
  ChromeMenuActionItem,
5551
5728
  {
5552
5729
  appearance,
5553
5730
  label: "Settings",
5554
5731
  onClick: onOpenSettings,
5555
- secondary: /* @__PURE__ */ jsx7("span", { "aria-hidden": true, children: "\u203A" })
5732
+ secondary: /* @__PURE__ */ jsx8("span", { "aria-hidden": true, children: "\u203A" })
5556
5733
  }
5557
5734
  )
5558
5735
  ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
5559
- /* @__PURE__ */ jsx7(
5736
+ /* @__PURE__ */ jsx8(
5560
5737
  ChromeMenuActionItem,
5561
5738
  {
5562
5739
  appearance,
5563
5740
  label: "Back",
5564
5741
  onClick: onShowTracks,
5565
- secondary: /* @__PURE__ */ jsx7("span", { "aria-hidden": true, children: "\u2039" })
5742
+ secondary: /* @__PURE__ */ jsx8("span", { "aria-hidden": true, children: "\u2039" })
5566
5743
  }
5567
5744
  ),
5568
- /* @__PURE__ */ jsx7(ChromeMenuDivider, {}),
5569
- /* @__PURE__ */ jsx7(ChromeMenuSectionLabel, { children: "Font size" }),
5570
- CAPTION_SIZE_OPTIONS.map((option) => /* @__PURE__ */ jsx7(
5745
+ /* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
5746
+ /* @__PURE__ */ jsx8(ChromeMenuSectionLabel, { children: "Font size" }),
5747
+ CAPTION_SIZE_OPTIONS.map((option) => /* @__PURE__ */ jsx8(
5571
5748
  ChromeMenuRadioItem,
5572
5749
  {
5573
5750
  active: Number(snapshot.captionAppearance.fontSize) === option.value,
@@ -5579,9 +5756,9 @@ function CaptionsMenu({
5579
5756
  },
5580
5757
  option.id
5581
5758
  )),
5582
- /* @__PURE__ */ jsx7(ChromeMenuDivider, {}),
5583
- /* @__PURE__ */ jsx7(ChromeMenuSectionLabel, { children: "Background" }),
5584
- CAPTION_BACKGROUND_OPTIONS.map((option) => /* @__PURE__ */ jsx7(
5759
+ /* @__PURE__ */ jsx8(ChromeMenuDivider, {}),
5760
+ /* @__PURE__ */ jsx8(ChromeMenuSectionLabel, { children: "Background" }),
5761
+ CAPTION_BACKGROUND_OPTIONS.map((option) => /* @__PURE__ */ jsx8(
5585
5762
  ChromeMenuRadioItem,
5586
5763
  {
5587
5764
  active: snapshot.captionAppearance.background === option.value,
@@ -5602,7 +5779,7 @@ function VerticalVolumeSlider({
5602
5779
  onVolume,
5603
5780
  volume
5604
5781
  }) {
5605
- const trackRef = useRef10(null);
5782
+ const trackRef = useRef11(null);
5606
5783
  const applyPointer = (event) => {
5607
5784
  const track = trackRef.current;
5608
5785
  if (!track) {
@@ -5636,7 +5813,7 @@ function VerticalVolumeSlider({
5636
5813
  pointerEvents: "auto"
5637
5814
  },
5638
5815
  children: [
5639
- /* @__PURE__ */ jsx7(
5816
+ /* @__PURE__ */ jsx8(
5640
5817
  "span",
5641
5818
  {
5642
5819
  "aria-hidden": true,
@@ -5648,7 +5825,7 @@ function VerticalVolumeSlider({
5648
5825
  children: percentLabel
5649
5826
  }
5650
5827
  ),
5651
- /* @__PURE__ */ jsx7(
5828
+ /* @__PURE__ */ jsx8(
5652
5829
  "div",
5653
5830
  {
5654
5831
  style: {
@@ -5688,7 +5865,7 @@ function VerticalVolumeSlider({
5688
5865
  },
5689
5866
  tabIndex: 0,
5690
5867
  children: [
5691
- /* @__PURE__ */ jsx7(
5868
+ /* @__PURE__ */ jsx8(
5692
5869
  "div",
5693
5870
  {
5694
5871
  style: {
@@ -5703,7 +5880,7 @@ function VerticalVolumeSlider({
5703
5880
  }
5704
5881
  }
5705
5882
  ),
5706
- /* @__PURE__ */ jsx7(
5883
+ /* @__PURE__ */ jsx8(
5707
5884
  "div",
5708
5885
  {
5709
5886
  style: {
@@ -5738,14 +5915,14 @@ function VolumeControl({
5738
5915
  volume,
5739
5916
  volumeAdjustable
5740
5917
  }) {
5741
- const rootRef = useRef10(null);
5918
+ const rootRef = useRef11(null);
5742
5919
  const [open, setOpen] = useState4(false);
5743
5920
  const displayVolume = muted ? 0 : volume;
5744
5921
  const mutedOrSilent = muted || volume === 0;
5745
- useEffect11(() => {
5922
+ useEffect12(() => {
5746
5923
  onOpenChange(open);
5747
5924
  }, [onOpenChange, open]);
5748
- useEffect11(() => {
5925
+ useEffect12(() => {
5749
5926
  if (!open || !volumeAdjustable || hasFinePointerHover()) {
5750
5927
  return;
5751
5928
  }
@@ -5762,13 +5939,13 @@ function VolumeControl({
5762
5939
  };
5763
5940
  }, [open, volumeAdjustable]);
5764
5941
  if (!volumeAdjustable) {
5765
- return /* @__PURE__ */ jsx7(
5942
+ return /* @__PURE__ */ jsx8(
5766
5943
  ChromeButton,
5767
5944
  {
5768
5945
  appearance,
5769
5946
  label: mutedOrSilent ? "Unmute" : "Mute",
5770
5947
  onClick: onToggleMuted,
5771
- children: mutedOrSilent ? /* @__PURE__ */ jsx7(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx7(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
5948
+ children: mutedOrSilent ? /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
5772
5949
  }
5773
5950
  );
5774
5951
  }
@@ -5800,7 +5977,7 @@ function VolumeControl({
5800
5977
  },
5801
5978
  ref: rootRef,
5802
5979
  children: [
5803
- open ? /* @__PURE__ */ jsx7(
5980
+ open ? /* @__PURE__ */ jsx8(
5804
5981
  VerticalVolumeSlider,
5805
5982
  {
5806
5983
  appearance,
@@ -5808,7 +5985,7 @@ function VolumeControl({
5808
5985
  volume: displayVolume
5809
5986
  }
5810
5987
  ) : null,
5811
- /* @__PURE__ */ jsx7(
5988
+ /* @__PURE__ */ jsx8(
5812
5989
  ChromeButton,
5813
5990
  {
5814
5991
  appearance,
@@ -5819,7 +5996,7 @@ function VolumeControl({
5819
5996
  }
5820
5997
  onToggleMuted();
5821
5998
  },
5822
- children: mutedOrSilent ? /* @__PURE__ */ jsx7(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx7(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
5999
+ children: mutedOrSilent ? /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.2 6.2l3.2 3.6M13.4 6.2l-3.2 3.6" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3 6.5h2.2L8.5 4v8L5.2 9.5H3zM10.5 5.5a3 3 0 0 1 0 5" })
5823
6000
  }
5824
6001
  )
5825
6002
  ]
@@ -5848,7 +6025,7 @@ function PanoVideoControlsHud({
5848
6025
  const [overlayWidth, setOverlayWidth] = useState4(
5849
6026
  () => overlayElement.clientWidth
5850
6027
  );
5851
- const idleTimerRef = useRef10(0);
6028
+ const idleTimerRef = useRef11(0);
5852
6029
  const barId = useId2();
5853
6030
  const rateMenuId = `${barId}-rate`;
5854
6031
  const variantMenuId = `${barId}-variant`;
@@ -5870,7 +6047,7 @@ function PanoVideoControlsHud({
5870
6047
  },
5871
6048
  [menu, volumeOpen]
5872
6049
  );
5873
- useEffect11(() => {
6050
+ useEffect12(() => {
5874
6051
  if (typeof ResizeObserver === "undefined") {
5875
6052
  return;
5876
6053
  }
@@ -5885,15 +6062,15 @@ function PanoVideoControlsHud({
5885
6062
  observer.disconnect();
5886
6063
  };
5887
6064
  }, [overlayElement]);
5888
- useEffect11(() => {
6065
+ useEffect12(() => {
5889
6066
  if (!compact && menu === "more") {
5890
6067
  setMenu(null);
5891
6068
  }
5892
6069
  }, [compact, menu]);
5893
- useEffect11(() => {
6070
+ useEffect12(() => {
5894
6071
  bumpVisibility(snapshot.playing);
5895
6072
  }, [bumpVisibility, snapshot.playing]);
5896
- useEffect11(() => {
6073
+ useEffect12(() => {
5897
6074
  const root = overlayElement.parentElement;
5898
6075
  if (!root) {
5899
6076
  return;
@@ -5952,7 +6129,7 @@ function PanoVideoControlsHud({
5952
6129
  document.removeEventListener("pointerdown", handlePointerDown, true);
5953
6130
  };
5954
6131
  }, [bumpVisibility, controller, menu, overlayElement, snapshot.playing, volumeOpen]);
5955
- useEffect11(
6132
+ useEffect12(
5956
6133
  () => () => {
5957
6134
  window.clearTimeout(idleTimerRef.current);
5958
6135
  },
@@ -5979,7 +6156,7 @@ function PanoVideoControlsHud({
5979
6156
  let menuNode = null;
5980
6157
  switch (menu) {
5981
6158
  case "rate":
5982
- menuNode = /* @__PURE__ */ jsx7(
6159
+ menuNode = /* @__PURE__ */ jsx8(
5983
6160
  ChromeMenu,
5984
6161
  {
5985
6162
  appearance: resolved,
@@ -5998,7 +6175,7 @@ function PanoVideoControlsHud({
5998
6175
  );
5999
6176
  break;
6000
6177
  case "variant":
6001
- menuNode = /* @__PURE__ */ jsx7(
6178
+ menuNode = /* @__PURE__ */ jsx8(
6002
6179
  ChromeMenu,
6003
6180
  {
6004
6181
  appearance: resolved,
@@ -6017,7 +6194,7 @@ function PanoVideoControlsHud({
6017
6194
  );
6018
6195
  break;
6019
6196
  case "captions":
6020
- menuNode = /* @__PURE__ */ jsx7(
6197
+ menuNode = /* @__PURE__ */ jsx8(
6021
6198
  CaptionsMenu,
6022
6199
  {
6023
6200
  appearance: resolved,
@@ -6041,7 +6218,7 @@ function PanoVideoControlsHud({
6041
6218
  );
6042
6219
  break;
6043
6220
  case "more":
6044
- menuNode = /* @__PURE__ */ jsx7(
6221
+ menuNode = /* @__PURE__ */ jsx8(
6045
6222
  ChromeMenu,
6046
6223
  {
6047
6224
  appearance: resolved,
@@ -6109,7 +6286,7 @@ function PanoVideoControlsHud({
6109
6286
  };
6110
6287
  const rateButton = /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "rate", children: [
6111
6288
  !compact && menu === "rate" ? menuNode : null,
6112
- /* @__PURE__ */ jsx7(
6289
+ /* @__PURE__ */ jsx8(
6113
6290
  ChromeButton,
6114
6291
  {
6115
6292
  appearance: resolved,
@@ -6117,13 +6294,13 @@ function PanoVideoControlsHud({
6117
6294
  onClick: () => {
6118
6295
  toggleMenu("rate");
6119
6296
  },
6120
- children: /* @__PURE__ */ jsx7("span", { className: "pano-video-chrome-label", id: `${barId}-rate-btn`, children: snapshot.playbackRate === 1 ? "1x" : `${snapshot.playbackRate}x` })
6297
+ children: /* @__PURE__ */ jsx8("span", { className: "pano-video-chrome-label", id: `${barId}-rate-btn`, children: snapshot.playbackRate === 1 ? "1x" : `${snapshot.playbackRate}x` })
6121
6298
  }
6122
6299
  )
6123
6300
  ] });
6124
6301
  const variantButton = canSwitchVariant ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "variant", children: [
6125
6302
  !compact && menu === "variant" ? menuNode : null,
6126
- /* @__PURE__ */ jsx7(
6303
+ /* @__PURE__ */ jsx8(
6127
6304
  ChromeButton,
6128
6305
  {
6129
6306
  appearance: resolved,
@@ -6131,13 +6308,13 @@ function PanoVideoControlsHud({
6131
6308
  onClick: () => {
6132
6309
  toggleMenu("variant");
6133
6310
  },
6134
- children: /* @__PURE__ */ jsx7("span", { className: "pano-video-chrome-label", id: `${barId}-variant-btn`, children: snapshot.variants.find((variant) => variant.id === snapshot.variantId)?.label ?? "Quality" })
6311
+ children: /* @__PURE__ */ jsx8("span", { className: "pano-video-chrome-label", id: `${barId}-variant-btn`, children: snapshot.variants.find((variant) => variant.id === snapshot.variantId)?.label ?? "Quality" })
6135
6312
  }
6136
6313
  )
6137
6314
  ] }) : null;
6138
6315
  const captionsButton = showCaptionsMenu ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "captions", children: [
6139
6316
  !compact && menu === "captions" ? menuNode : null,
6140
- /* @__PURE__ */ jsx7(
6317
+ /* @__PURE__ */ jsx8(
6141
6318
  ChromeButton,
6142
6319
  {
6143
6320
  appearance: resolved,
@@ -6145,7 +6322,7 @@ function PanoVideoControlsHud({
6145
6322
  onClick: () => {
6146
6323
  toggleMenu("captions");
6147
6324
  },
6148
- children: /* @__PURE__ */ jsx7("span", { id: `${barId}-captions-btn`, children: /* @__PURE__ */ jsx7(Icon, { path: "M2.5 4.5h11v7h-11zM5 7.2h2.4M5 9.2h5.5" }) })
6325
+ children: /* @__PURE__ */ jsx8("span", { id: `${barId}-captions-btn`, children: /* @__PURE__ */ jsx8(Icon, { path: "M2.5 4.5h11v7h-11zM5 7.2h2.4M5 9.2h5.5" }) })
6149
6326
  }
6150
6327
  )
6151
6328
  ] }) : null;
@@ -6156,7 +6333,7 @@ function PanoVideoControlsHud({
6156
6333
  "data-pano-video-controls": "",
6157
6334
  style: barStyle,
6158
6335
  children: [
6159
- /* @__PURE__ */ jsx7(
6336
+ /* @__PURE__ */ jsx8(
6160
6337
  ChromeButton,
6161
6338
  {
6162
6339
  appearance: resolved,
@@ -6164,11 +6341,11 @@ function PanoVideoControlsHud({
6164
6341
  onClick: () => {
6165
6342
  controller.togglePlay();
6166
6343
  },
6167
- children: snapshot.playing ? /* @__PURE__ */ jsx7(Icon, { path: "M5 3.5h2.2v9H5zM8.8 3.5H11v9H8.8z" }) : /* @__PURE__ */ jsx7(Icon, { path: "M5 3.2v9.6L13 8z" })
6344
+ children: snapshot.playing ? /* @__PURE__ */ jsx8(Icon, { path: "M5 3.5h2.2v9H5zM8.8 3.5H11v9H8.8z" }) : /* @__PURE__ */ jsx8(Icon, { path: "M5 3.2v9.6L13 8z" })
6168
6345
  }
6169
6346
  ),
6170
- hideTime ? null : /* @__PURE__ */ jsx7("span", { className: "pano-video-time", children: formatMediaTime(snapshot.currentTime) }),
6171
- /* @__PURE__ */ jsx7(
6347
+ hideTime ? null : /* @__PURE__ */ jsx8("span", { className: "pano-video-time", children: formatMediaTime(snapshot.currentTime) }),
6348
+ /* @__PURE__ */ jsx8(
6172
6349
  "input",
6173
6350
  {
6174
6351
  "aria-label": "Seek",
@@ -6190,8 +6367,8 @@ function PanoVideoControlsHud({
6190
6367
  value: duration > 0 ? snapshot.currentTime : 0
6191
6368
  }
6192
6369
  ),
6193
- hideTime ? null : /* @__PURE__ */ jsx7("span", { className: "pano-video-time", children: formatMediaTime(duration) }),
6194
- /* @__PURE__ */ jsx7(
6370
+ hideTime ? null : /* @__PURE__ */ jsx8("span", { className: "pano-video-time", children: formatMediaTime(duration) }),
6371
+ /* @__PURE__ */ jsx8(
6195
6372
  VolumeControl,
6196
6373
  {
6197
6374
  appearance: resolved,
@@ -6209,7 +6386,7 @@ function PanoVideoControlsHud({
6209
6386
  ),
6210
6387
  compact ? /* @__PURE__ */ jsxs3("div", { className: "pano-video-menu", "data-pano-video-menu": "more", children: [
6211
6388
  menu !== null ? menuNode : null,
6212
- /* @__PURE__ */ jsx7(
6389
+ /* @__PURE__ */ jsx8(
6213
6390
  ChromeButton,
6214
6391
  {
6215
6392
  appearance: resolved,
@@ -6218,7 +6395,7 @@ function PanoVideoControlsHud({
6218
6395
  onClick: () => {
6219
6396
  toggleMenu("more");
6220
6397
  },
6221
- children: /* @__PURE__ */ jsx7(Icon, { path: "M3 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M7 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M11 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0" })
6398
+ children: /* @__PURE__ */ jsx8(Icon, { path: "M3 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M7 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M11 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0" })
6222
6399
  }
6223
6400
  )
6224
6401
  ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
@@ -6226,7 +6403,7 @@ function PanoVideoControlsHud({
6226
6403
  variantButton,
6227
6404
  captionsButton
6228
6405
  ] }),
6229
- showFullscreen ? /* @__PURE__ */ jsx7(
6406
+ showFullscreen ? /* @__PURE__ */ jsx8(
6230
6407
  ChromeButton,
6231
6408
  {
6232
6409
  appearance: resolved,
@@ -6234,7 +6411,7 @@ function PanoVideoControlsHud({
6234
6411
  onClick: () => {
6235
6412
  fullscreen?.toggleFullscreen();
6236
6413
  },
6237
- children: fullscreen?.isFullscreen ? /* @__PURE__ */ jsx7(Icon, { path: "M6 3.5H3.5V6M10 3.5h2.5V6M6 12.5H3.5V10M10 12.5h2.5V10" }) : /* @__PURE__ */ jsx7(Icon, { path: "M3.5 6V3.5H6M10 3.5h2.5V6M3.5 10v2.5H6M10 12.5h2.5V10" })
6414
+ children: fullscreen?.isFullscreen ? /* @__PURE__ */ jsx8(Icon, { path: "M6 3.5H3.5V6M10 3.5h2.5V6M6 12.5H3.5V10M10 12.5h2.5V10" }) : /* @__PURE__ */ jsx8(Icon, { path: "M3.5 6V3.5H6M10 3.5h2.5V6M3.5 10v2.5H6M10 12.5h2.5V10" })
6238
6415
  }
6239
6416
  ) : null
6240
6417
  ]
@@ -6243,7 +6420,7 @@ function PanoVideoControlsHud({
6243
6420
  }
6244
6421
  function PanoVideoControls({ appearance }) {
6245
6422
  useClaimPanoVideoControls();
6246
- const host = useContext13(PanoVideoHostContext);
6423
+ const host = useContext14(PanoVideoHostContext);
6247
6424
  if (host && appearance) {
6248
6425
  host.controls = appearance;
6249
6426
  }
@@ -6251,7 +6428,7 @@ function PanoVideoControls({ appearance }) {
6251
6428
  }
6252
6429
 
6253
6430
  // src/video/pano-video-chrome-bridge.tsx
6254
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
6431
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
6255
6432
  function PanoVideoChromeBridge({
6256
6433
  fullscreen,
6257
6434
  host,
@@ -6267,7 +6444,7 @@ function PanoVideoChromeBridge({
6267
6444
  }
6268
6445
  const showDefaultControls = host.controller !== null && host.controls !== false && host.controlClaims === 0;
6269
6446
  return /* @__PURE__ */ jsxs4(Fragment2, { children: [
6270
- showDefaultControls ? /* @__PURE__ */ jsx8(
6447
+ showDefaultControls ? /* @__PURE__ */ jsx9(
6271
6448
  PanoVideoControlsHud,
6272
6449
  {
6273
6450
  appearance: typeof host.controls === "object" ? host.controls : void 0,
@@ -6276,7 +6453,7 @@ function PanoVideoChromeBridge({
6276
6453
  overlayElement
6277
6454
  }
6278
6455
  ) : null,
6279
- host.captions !== false && host.controller ? /* @__PURE__ */ jsx8(PanoVideoCaptionsOverlay, { controller: host.controller }) : null
6456
+ host.captions !== false && host.controller ? /* @__PURE__ */ jsx9(PanoVideoCaptionsOverlay, { controller: host.controller }) : null
6280
6457
  ] });
6281
6458
  }
6282
6459
 
@@ -6284,8 +6461,8 @@ function PanoVideoChromeBridge({
6284
6461
  import { useSyncExternalStore as useSyncExternalStore5 } from "react";
6285
6462
 
6286
6463
  // src/webvr/host.ts
6287
- import { createContext as createContext12 } from "react";
6288
- var WebVRRuntimeContext = createContext12(null);
6464
+ import { createContext as createContext13 } from "react";
6465
+ var WebVRRuntimeContext = createContext13(null);
6289
6466
  function createWebVRHost() {
6290
6467
  return {
6291
6468
  controller: null,
@@ -6429,7 +6606,7 @@ function clamp2(value, min, max) {
6429
6606
  }
6430
6607
 
6431
6608
  // src/webvr/chrome.tsx
6432
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
6609
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
6433
6610
  function resolveAppearance(value) {
6434
6611
  return {
6435
6612
  ...DEFAULT_WEBVR_CHROME_APPEARANCE,
@@ -6441,7 +6618,7 @@ function ChromeButton2({
6441
6618
  children,
6442
6619
  onClick
6443
6620
  }) {
6444
- return /* @__PURE__ */ jsx9(
6621
+ return /* @__PURE__ */ jsx10(
6445
6622
  "button",
6446
6623
  {
6447
6624
  className: "pano-webvr-button",
@@ -6486,11 +6663,11 @@ function SetupPanel({
6486
6663
  role: "dialog",
6487
6664
  style: panelStyle,
6488
6665
  children: [
6489
- /* @__PURE__ */ jsx9("h2", { className: "pano-webvr-setup-title", children: appearance.setupTitle ?? "MobileVR Setup" }),
6666
+ /* @__PURE__ */ jsx10("h2", { className: "pano-webvr-setup-title", children: appearance.setupTitle ?? "MobileVR Setup" }),
6490
6667
  /* @__PURE__ */ jsxs5("label", { className: "pano-webvr-setup-field", children: [
6491
6668
  "Screen size (inch)",
6492
6669
  /* @__PURE__ */ jsxs5("div", { className: "pano-webvr-setup-row", children: [
6493
- /* @__PURE__ */ jsx9(
6670
+ /* @__PURE__ */ jsx10(
6494
6671
  "button",
6495
6672
  {
6496
6673
  "aria-label": "Decrease screen size",
@@ -6502,8 +6679,8 @@ function SetupPanel({
6502
6679
  children: "\u2039"
6503
6680
  }
6504
6681
  ),
6505
- /* @__PURE__ */ jsx9("strong", { className: "pano-webvr-setup-value", children: settings.screensize === "auto" ? "Auto" : settings.screensize.toFixed(1) }),
6506
- /* @__PURE__ */ jsx9(
6682
+ /* @__PURE__ */ jsx10("strong", { className: "pano-webvr-setup-value", children: settings.screensize === "auto" ? "Auto" : settings.screensize.toFixed(1) }),
6683
+ /* @__PURE__ */ jsx10(
6507
6684
  "button",
6508
6685
  {
6509
6686
  "aria-label": "Increase screen size",
@@ -6518,9 +6695,9 @@ function SetupPanel({
6518
6695
  ] })
6519
6696
  ] }),
6520
6697
  /* @__PURE__ */ jsxs5("fieldset", { className: "pano-webvr-setup-fieldset", children: [
6521
- /* @__PURE__ */ jsx9("legend", { className: "pano-webvr-setup-legend", children: "VR headset preset" }),
6698
+ /* @__PURE__ */ jsx10("legend", { className: "pano-webvr-setup-legend", children: "VR headset preset" }),
6522
6699
  /* @__PURE__ */ jsxs5("div", { className: "pano-webvr-setup-row", children: [
6523
- /* @__PURE__ */ jsx9(
6700
+ /* @__PURE__ */ jsx10(
6524
6701
  "button",
6525
6702
  {
6526
6703
  "aria-label": "Previous headset preset",
@@ -6530,8 +6707,8 @@ function SetupPanel({
6530
6707
  children: "\u2039"
6531
6708
  }
6532
6709
  ),
6533
- /* @__PURE__ */ jsx9("strong", { className: "pano-webvr-setup-value-wide", children: WEBVR_PROFILES[settings.profileId].label }),
6534
- /* @__PURE__ */ jsx9(
6710
+ /* @__PURE__ */ jsx10("strong", { className: "pano-webvr-setup-value-wide", children: WEBVR_PROFILES[settings.profileId].label }),
6711
+ /* @__PURE__ */ jsx10(
6535
6712
  "button",
6536
6713
  {
6537
6714
  "aria-label": "Next headset preset",
@@ -6543,7 +6720,7 @@ function SetupPanel({
6543
6720
  )
6544
6721
  ] })
6545
6722
  ] }),
6546
- /* @__PURE__ */ jsx9(
6723
+ /* @__PURE__ */ jsx10(
6547
6724
  ChromeButton2,
6548
6725
  {
6549
6726
  appearance,
@@ -6567,8 +6744,8 @@ function WebVRChromeBridge({ host }) {
6567
6744
  }
6568
6745
  const appearance = resolveAppearance(chrome);
6569
6746
  return /* @__PURE__ */ jsxs5(Fragment3, { children: [
6570
- /* @__PURE__ */ jsx9("div", { className: "pano-webvr-toolbar", children: mode ? /* @__PURE__ */ jsxs5("div", { className: "pano-webvr-toolbar-actions", children: [
6571
- mode !== "webxr" ? /* @__PURE__ */ jsx9(
6747
+ /* @__PURE__ */ jsx10("div", { className: "pano-webvr-toolbar", children: mode ? /* @__PURE__ */ jsxs5("div", { className: "pano-webvr-toolbar-actions", children: [
6748
+ mode !== "webxr" ? /* @__PURE__ */ jsx10(
6572
6749
  ChromeButton2,
6573
6750
  {
6574
6751
  appearance,
@@ -6576,7 +6753,7 @@ function WebVRChromeBridge({ host }) {
6576
6753
  children: "VR Setup"
6577
6754
  }
6578
6755
  ) : null,
6579
- /* @__PURE__ */ jsx9(
6756
+ /* @__PURE__ */ jsx10(
6580
6757
  ChromeButton2,
6581
6758
  {
6582
6759
  appearance,
@@ -6584,7 +6761,7 @@ function WebVRChromeBridge({ host }) {
6584
6761
  children: "Exit VR"
6585
6762
  }
6586
6763
  )
6587
- ] }) : /* @__PURE__ */ jsx9(
6764
+ ] }) : /* @__PURE__ */ jsx10(
6588
6765
  ChromeButton2,
6589
6766
  {
6590
6767
  appearance,
@@ -6592,7 +6769,7 @@ function WebVRChromeBridge({ host }) {
6592
6769
  children: available ? "Enter VR" : "VR unavailable"
6593
6770
  }
6594
6771
  ) }),
6595
- mode === "fake" ? /* @__PURE__ */ jsx9(
6772
+ mode === "fake" ? /* @__PURE__ */ jsx10(
6596
6773
  "p",
6597
6774
  {
6598
6775
  className: "pano-webvr-hint",
@@ -6600,7 +6777,7 @@ function WebVRChromeBridge({ host }) {
6600
6777
  children: "Simulated VR Mode \xB7 Click the view to lock the mouse, then move to look around. Use a headset or phone for real VR."
6601
6778
  }
6602
6779
  ) : null,
6603
- setupOpen ? /* @__PURE__ */ jsx9(
6780
+ setupOpen ? /* @__PURE__ */ jsx10(
6604
6781
  SetupPanel,
6605
6782
  {
6606
6783
  appearance,
@@ -6640,12 +6817,12 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
6640
6817
  // src/webvr/xr-origin.tsx
6641
6818
  import { useFrame as useFrame5, useThree as useThree8 } from "@react-three/fiber";
6642
6819
  import { useXR as useXR2, XROrigin } from "@react-three/xr";
6643
- import { useRef as useRef11 } from "react";
6820
+ import { useRef as useRef12 } from "react";
6644
6821
  import { Vector3 as Vector34 } from "three";
6645
- import { jsx as jsx10 } from "react/jsx-runtime";
6822
+ import { jsx as jsx11 } from "react/jsx-runtime";
6646
6823
  function PanoramaXROrigin() {
6647
- const originRef = useRef11(null);
6648
- const localHeadPositionRef = useRef11(new Vector34());
6824
+ const originRef = useRef12(null);
6825
+ const localHeadPositionRef = useRef12(new Vector34());
6649
6826
  const session2 = useXR2((state) => state.session);
6650
6827
  const gl = useThree8((state) => state.gl);
6651
6828
  useFrame5(() => {
@@ -6658,11 +6835,11 @@ function PanoramaXROrigin() {
6658
6835
  origin.position.copy(localHeadPositionRef.current).multiplyScalar(-1);
6659
6836
  origin.updateMatrixWorld();
6660
6837
  }, -100);
6661
- return /* @__PURE__ */ jsx10(XROrigin, { ref: originRef });
6838
+ return /* @__PURE__ */ jsx11(XROrigin, { ref: originRef });
6662
6839
  }
6663
6840
 
6664
6841
  // src/pano-viewer.tsx
6665
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
6842
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
6666
6843
  var DEFAULT_VIEW = {
6667
6844
  yaw: 0,
6668
6845
  pitch: 0,
@@ -6707,10 +6884,10 @@ function PanoCursorTree({
6707
6884
  if (!cursors) {
6708
6885
  return children;
6709
6886
  }
6710
- return /* @__PURE__ */ jsx11(PanoCursorController, { cursors, children });
6887
+ return /* @__PURE__ */ jsx12(PanoCursorController, { cursors, children });
6711
6888
  }
6712
6889
  function PanoVideoHostReset() {
6713
- const host = useContext14(PanoVideoHostContext);
6890
+ const host = useContext15(PanoVideoHostContext);
6714
6891
  if (host) {
6715
6892
  host.controlClaims = 0;
6716
6893
  }
@@ -6723,14 +6900,14 @@ function DefaultControlChannels({
6723
6900
  keyboardChannel,
6724
6901
  fovSpeed
6725
6902
  }) {
6726
- const claims = useContext14(ControlClaimsContext);
6903
+ const claims = useContext15(ControlClaimsContext);
6727
6904
  if (!claims) {
6728
6905
  return null;
6729
6906
  }
6730
6907
  return /* @__PURE__ */ jsxs6(DefaultControlChannelContext.Provider, { value: true, children: [
6731
- userControlsEnabled && mouseChannel.mount && claims.mouse === 0 ? /* @__PURE__ */ jsx11(MouseControls, { ...mouseChannel.props, fovSpeed }) : null,
6732
- userControlsEnabled && touchChannel.mount && claims.touch === 0 ? /* @__PURE__ */ jsx11(TouchControls, { ...touchChannel.props }) : null,
6733
- userControlsEnabled && keyboardChannel.mount && claims.keyboard === 0 ? /* @__PURE__ */ jsx11(
6908
+ userControlsEnabled && mouseChannel.mount && claims.mouse === 0 ? /* @__PURE__ */ jsx12(MouseControls, { ...mouseChannel.props, fovSpeed }) : null,
6909
+ userControlsEnabled && touchChannel.mount && claims.touch === 0 ? /* @__PURE__ */ jsx12(TouchControls, { ...touchChannel.props }) : null,
6910
+ userControlsEnabled && keyboardChannel.mount && claims.keyboard === 0 ? /* @__PURE__ */ jsx12(
6734
6911
  KeyboardControls,
6735
6912
  {
6736
6913
  ...keyboardChannel.props,
@@ -6748,6 +6925,7 @@ var PanoViewer = forwardRef2(
6748
6925
  controls = true,
6749
6926
  cursors,
6750
6927
  contextMenu = true,
6928
+ mediaActivation,
6751
6929
  onViewChange,
6752
6930
  onPanoramaClick,
6753
6931
  onPanoramaDoubleClick,
@@ -6757,8 +6935,8 @@ var PanoViewer = forwardRef2(
6757
6935
  "aria-label": ariaLabel = "Panorama viewer",
6758
6936
  ...divProps
6759
6937
  }, ref) {
6760
- const rootRef = useRef12(null);
6761
- const controlsRef = useRef12(null);
6938
+ const rootRef = useRef13(null);
6939
+ const controlsRef = useRef13(null);
6762
6940
  const eventBus = useMemo7(() => createPanoEventBus(), []);
6763
6941
  const { controls: hotspotAccessibilityControls, registry } = useHotspotAccessibilityLayer();
6764
6942
  const { api: contextMenuOverlayApi, overlay: contextMenuOverlay } = usePanoContextMenuOverlay();
@@ -6768,6 +6946,17 @@ var PanoViewer = forwardRef2(
6768
6946
  const webVRHost = useMemo7(() => createWebVRHost(), []);
6769
6947
  const scenesHost = useMemo7(() => createScenesHost(), []);
6770
6948
  const bgmHost = useMemo7(() => createBackgroundAudioHost(), []);
6949
+ const mediaActivationHost = useMemo7(() => createPanoMediaActivationHost(), []);
6950
+ const mediaActivationOptions = useMemo7(
6951
+ () => mediaActivation === false ? null : mediaActivation ?? {},
6952
+ [mediaActivation]
6953
+ );
6954
+ const mediaActivationRevision = useSyncExternalStore6(
6955
+ (onStoreChange) => subscribePanoMediaActivation(mediaActivationHost, onStoreChange),
6956
+ () => getPanoMediaActivationRevision(mediaActivationHost),
6957
+ () => getPanoMediaActivationRevision(mediaActivationHost)
6958
+ );
6959
+ const [mediaActivated, setMediaActivated] = useState5(false);
6771
6960
  const stereoView = useMemo7(() => createWebVRStereoView(), []);
6772
6961
  const xrStore = useMemo7(
6773
6962
  () => createXRStore({
@@ -6785,7 +6974,33 @@ var PanoViewer = forwardRef2(
6785
6974
  }),
6786
6975
  []
6787
6976
  );
6788
- const fallbackViewRef = useRef12(DEFAULT_VIEW);
6977
+ const mediaActivationControls = useMemo7(
6978
+ () => ({
6979
+ resumeAudio: () => resumePanoAudio(),
6980
+ playVideo: async ({ unmute = false } = {}) => {
6981
+ const controller = videoHost.controller;
6982
+ if (!controller) {
6983
+ return false;
6984
+ }
6985
+ if (unmute) {
6986
+ controller.setMuted(false);
6987
+ }
6988
+ await controller.play();
6989
+ return !controller.getSnapshot().blocked;
6990
+ },
6991
+ playBackgroundAudio: () => bgmHost.controller?.play() ?? false
6992
+ }),
6993
+ [bgmHost, videoHost]
6994
+ );
6995
+ const activateMedia = useCallback6(() => {
6996
+ setMediaActivated(true);
6997
+ const resume = mediaActivationControls.resumeAudio();
6998
+ mediaActivationOptions?.onActivate?.(mediaActivationControls);
6999
+ return resume;
7000
+ }, [mediaActivationControls, mediaActivationOptions]);
7001
+ const hasMediaActivationIntent = mediaActivationRevision >= 0 && hasPanoMediaActivationIntent(mediaActivationHost);
7002
+ const shouldShowMediaActivation = mediaActivationOptions !== null && hasMediaActivationIntent && !mediaActivated;
7003
+ const fallbackViewRef = useRef13(DEFAULT_VIEW);
6789
7004
  const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
6790
7005
  const normalizedMaxFov = Math.min(
6791
7006
  179,
@@ -6888,7 +7103,7 @@ var PanoViewer = forwardRef2(
6888
7103
  await requestElementFullscreen(root);
6889
7104
  }, []);
6890
7105
  const [isViewerFullscreen, setIsViewerFullscreen] = useState5(false);
6891
- useEffect12(() => {
7106
+ useEffect13(() => {
6892
7107
  if (typeof document === "undefined") {
6893
7108
  return;
6894
7109
  }
@@ -6906,7 +7121,7 @@ var PanoViewer = forwardRef2(
6906
7121
  syncFullscreen();
6907
7122
  return subscribeFullscreenChange(syncFullscreen);
6908
7123
  }, []);
6909
- useEffect12(() => {
7124
+ useEffect13(() => {
6910
7125
  const root = rootRef.current;
6911
7126
  if (!root) {
6912
7127
  return;
@@ -6943,10 +7158,10 @@ var PanoViewer = forwardRef2(
6943
7158
  const [legacyAutoRotate, setLegacyAutoRotate] = useState5(
6944
7159
  legacyAutoRotateOptions.autoRotate ?? false
6945
7160
  );
6946
- useEffect12(() => {
7161
+ useEffect13(() => {
6947
7162
  setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);
6948
7163
  }, [legacyAutoRotateOptions.autoRotate]);
6949
- const isFullscreenRef = useRef12(false);
7164
+ const isFullscreenRef = useRef13(false);
6950
7165
  isFullscreenRef.current = isViewerFullscreen;
6951
7166
  useImperativeHandle2(
6952
7167
  ref,
@@ -6959,6 +7174,7 @@ var PanoViewer = forwardRef2(
6959
7174
  reset: () => {
6960
7175
  controlsRef.current?.reset();
6961
7176
  },
7177
+ activateMedia,
6962
7178
  // -- Fullscreen --
6963
7179
  enterFullscreen,
6964
7180
  exitFullscreen,
@@ -7011,6 +7227,7 @@ var PanoViewer = forwardRef2(
7011
7227
  }),
7012
7228
  [
7013
7229
  bgmHost,
7230
+ activateMedia,
7014
7231
  enterFullscreen,
7015
7232
  exitFullscreen,
7016
7233
  scenesHost,
@@ -7037,7 +7254,7 @@ var PanoViewer = forwardRef2(
7037
7254
  "aria-label": ariaLabel,
7038
7255
  style: rootStyle,
7039
7256
  children: [
7040
- /* @__PURE__ */ jsx11(
7257
+ /* @__PURE__ */ jsx12(
7041
7258
  Canvas,
7042
7259
  {
7043
7260
  "aria-label": `${ariaLabel} canvas`,
@@ -7059,23 +7276,23 @@ var PanoViewer = forwardRef2(
7059
7276
  ...DEFAULT_CANVAS_STYLE,
7060
7277
  touchAction: userControlsEnabled ? "none" : "auto"
7061
7278
  },
7062
- children: /* @__PURE__ */ jsx11(XR, { store: xrStore, children: /* @__PURE__ */ jsxs6(
7279
+ children: /* @__PURE__ */ jsx12(XR, { store: xrStore, children: /* @__PURE__ */ jsxs6(
7063
7280
  WebVRRuntimeContext.Provider,
7064
7281
  {
7065
7282
  value: { host: webVRHost, xrStore, stereoView },
7066
7283
  children: [
7067
- /* @__PURE__ */ jsx11(PanoramaXROrigin, {}),
7068
- /* @__PURE__ */ jsx11(HotspotAccessibilityContext.Provider, { value: registry, children: /* @__PURE__ */ jsx11(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ jsx11(PanoCursorTree, { cursors: resolvedCursors, children: /* @__PURE__ */ jsx11(PanoramaViewContext.Provider, { value: controlsRef, children: /* @__PURE__ */ jsx11(
7284
+ /* @__PURE__ */ jsx12(PanoramaXROrigin, {}),
7285
+ /* @__PURE__ */ jsx12(HotspotAccessibilityContext.Provider, { value: registry, children: /* @__PURE__ */ jsx12(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ jsx12(PanoCursorTree, { cursors: resolvedCursors, children: /* @__PURE__ */ jsx12(PanoramaViewContext.Provider, { value: controlsRef, children: /* @__PURE__ */ jsx12(
7069
7286
  PanoContextMenuOverlayContext.Provider,
7070
7287
  {
7071
7288
  value: contextMenuOverlayApi,
7072
- children: /* @__PURE__ */ jsx11(PanoChromeOverlayContext.Provider, { value: chromeOverlayApi, children: /* @__PURE__ */ jsx11(PanoVideoHostContext.Provider, { value: videoHost, children: /* @__PURE__ */ jsx11(PanoFilterHostContext.Provider, { value: filterHost, children: /* @__PURE__ */ jsx11(
7289
+ children: /* @__PURE__ */ jsx12(PanoChromeOverlayContext.Provider, { value: chromeOverlayApi, children: /* @__PURE__ */ jsx12(PanoVideoHostContext.Provider, { value: videoHost, children: /* @__PURE__ */ jsx12(PanoFilterHostContext.Provider, { value: filterHost, children: /* @__PURE__ */ jsx12(
7073
7290
  PanoContextMenuActionsContext.Provider,
7074
7291
  {
7075
7292
  value: contextMenuActions,
7076
- children: /* @__PURE__ */ jsx11(ScenesHostContext.Provider, { value: scenesHost, children: /* @__PURE__ */ jsxs6(BackgroundAudioHostContext.Provider, { value: bgmHost, children: [
7077
- /* @__PURE__ */ jsx11(PanoVideoHostReset, {}),
7078
- /* @__PURE__ */ jsx11(
7293
+ children: /* @__PURE__ */ jsx12(ScenesHostContext.Provider, { value: scenesHost, children: /* @__PURE__ */ jsx12(BackgroundAudioHostContext.Provider, { value: bgmHost, children: /* @__PURE__ */ jsxs6(PanoMediaActivationHostContext.Provider, { value: mediaActivationHost, children: [
7294
+ /* @__PURE__ */ jsx12(PanoVideoHostReset, {}),
7295
+ /* @__PURE__ */ jsx12(
7079
7296
  PanoramaViewRuntime,
7080
7297
  {
7081
7298
  ref: controlsRef,
@@ -7086,7 +7303,7 @@ var PanoViewer = forwardRef2(
7086
7303
  options: controlOptions
7087
7304
  }
7088
7305
  ),
7089
- (onViewChange || onPanoramaClick || onPanoramaDoubleClick || onPanoramaPointerMove) && /* @__PURE__ */ jsx11(
7306
+ (onViewChange || onPanoramaClick || onPanoramaDoubleClick || onPanoramaPointerMove) && /* @__PURE__ */ jsx12(
7090
7307
  PanoEvents,
7091
7308
  {
7092
7309
  onViewChange,
@@ -7095,18 +7312,18 @@ var PanoViewer = forwardRef2(
7095
7312
  onPointerMove: onPanoramaPointerMove
7096
7313
  }
7097
7314
  ),
7098
- /* @__PURE__ */ jsx11(
7315
+ /* @__PURE__ */ jsx12(
7099
7316
  AutoRotate,
7100
7317
  {
7101
7318
  enabled: legacyAutoRotate,
7102
7319
  speed: legacyAutoRotateOptions.autoRotateSpeed
7103
7320
  }
7104
7321
  ),
7105
- /* @__PURE__ */ jsx11(PanoramaEventSurface, {}),
7106
- contextMenuChannel.mount ? /* @__PURE__ */ jsx11(PanoContextMenu, { ...contextMenuChannel.props }) : null,
7322
+ /* @__PURE__ */ jsx12(PanoramaEventSurface, {}),
7323
+ contextMenuChannel.mount ? /* @__PURE__ */ jsx12(PanoContextMenu, { ...contextMenuChannel.props }) : null,
7107
7324
  /* @__PURE__ */ jsxs6(ControlClaimsContext.Provider, { value: controlClaims, children: [
7108
7325
  children,
7109
- /* @__PURE__ */ jsx11(
7326
+ /* @__PURE__ */ jsx12(
7110
7327
  DefaultControlChannels,
7111
7328
  {
7112
7329
  fovSpeed: controlOptions.fovSpeed,
@@ -7117,7 +7334,7 @@ var PanoViewer = forwardRef2(
7117
7334
  }
7118
7335
  )
7119
7336
  ] })
7120
- ] }) })
7337
+ ] }) }) })
7121
7338
  }
7122
7339
  ) }) }) })
7123
7340
  }
@@ -7134,123 +7351,37 @@ var PanoViewer = forwardRef2(
7134
7351
  "data-pano-chrome-overlay": "",
7135
7352
  ref: setOverlayNode,
7136
7353
  children: [
7137
- /* @__PURE__ */ jsx11(
7354
+ /* @__PURE__ */ jsx12(
7138
7355
  PanoVideoChromeBridge,
7139
7356
  {
7140
7357
  fullscreen: contextMenuActions,
7141
7358
  host: videoHost,
7142
7359
  overlayElement
7143
7360
  }
7144
- ),
7145
- /* @__PURE__ */ jsx11(WebVRChromeBridge, { host: webVRHost })
7146
- ]
7147
- }
7148
- ),
7149
- contextMenuOverlay,
7150
- hotspotAccessibilityControls
7151
- ]
7152
- }
7153
- );
7154
- }
7155
- );
7156
-
7157
- // src/background-audio.tsx
7158
- import { useContext as useContext15, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef13, useState as useState6 } from "react";
7159
-
7160
- // src/audio/howl.ts
7161
- var import_howler = __toESM(require_howler());
7162
- import_howler.Howler.autoUnlock = true;
7163
- function sourceList(src) {
7164
- if (src == null) {
7165
- return [];
7166
- }
7167
- if (typeof src === "string") {
7168
- return src ? [src] : [];
7169
- }
7170
- return src.filter((item) => Boolean(item));
7171
- }
7172
- function createUnlockingHowl({
7173
- src,
7174
- loop,
7175
- crossOrigin,
7176
- isActive,
7177
- shouldRetryPlay,
7178
- onEnded,
7179
- onPlay,
7180
- onPause,
7181
- onLoadError,
7182
- onPlayError
7183
- }) {
7184
- let disposed = false;
7185
- let blockedNotified = false;
7186
- const unlockListeners = [];
7187
- const removeUnlockListeners = () => {
7188
- for (const { type, listener } of unlockListeners) {
7189
- window.removeEventListener(type, listener, true);
7190
- }
7191
- unlockListeners.length = 0;
7192
- };
7193
- const instance = new import_howler.Howl({
7194
- src: [...src],
7195
- html5: false,
7196
- preload: true,
7197
- loop,
7198
- xhr: crossOrigin === "use-credentials" ? { withCredentials: true } : void 0,
7199
- onend: () => {
7200
- if (disposed || !isActive() || instance.loop()) {
7201
- return;
7202
- }
7203
- onEnded?.();
7204
- },
7205
- onplay: () => {
7206
- if (!disposed && isActive()) {
7207
- onPlay?.();
7208
- }
7209
- },
7210
- onpause: () => {
7211
- if (!disposed && isActive()) {
7212
- onPause?.();
7213
- }
7214
- },
7215
- onloaderror: (_soundId, error) => {
7216
- if (!disposed && isActive()) {
7217
- onLoadError?.(error);
7218
- }
7219
- },
7220
- onplayerror: (_soundId, error) => {
7221
- if (disposed || !isActive()) {
7222
- return;
7223
- }
7224
- if (!blockedNotified) {
7225
- blockedNotified = true;
7226
- onPlayError?.(error);
7227
- }
7228
- const retry = () => {
7229
- removeUnlockListeners();
7230
- if (!disposed && isActive() && shouldRetryPlay()) {
7231
- void import_howler.Howler.ctx?.resume();
7232
- instance.play();
7233
- }
7234
- };
7235
- removeUnlockListeners();
7236
- unlockListeners.push({ type: "pointerdown", listener: retry });
7237
- unlockListeners.push({ type: "keydown", listener: retry });
7238
- window.addEventListener("pointerdown", retry, { capture: true });
7239
- window.addEventListener("keydown", retry, { capture: true });
7240
- }
7241
- });
7242
- return {
7243
- howl: instance,
7244
- dispose: () => {
7245
- if (disposed) {
7246
- return;
7361
+ ),
7362
+ /* @__PURE__ */ jsx12(WebVRChromeBridge, { host: webVRHost })
7363
+ ]
7364
+ }
7365
+ ),
7366
+ contextMenuOverlay,
7367
+ hotspotAccessibilityControls,
7368
+ shouldShowMediaActivation ? /* @__PURE__ */ jsx12(
7369
+ PanoMediaActivationOverlay,
7370
+ {
7371
+ ...mediaActivationOptions,
7372
+ onActivate: () => {
7373
+ void activateMedia();
7374
+ }
7375
+ }
7376
+ ) : null
7377
+ ]
7247
7378
  }
7248
- disposed = true;
7249
- removeUnlockListeners();
7250
- instance.unload();
7251
- }
7252
- };
7253
- }
7379
+ );
7380
+ }
7381
+ );
7382
+
7383
+ // src/background-audio.tsx
7384
+ import { useContext as useContext16, useEffect as useEffect14, useMemo as useMemo8, useRef as useRef14, useState as useState6 } from "react";
7254
7385
 
7255
7386
  // src/hotspot/audio-spatial.ts
7256
7387
  import { MathUtils as MathUtils3, Vector3 as Vector35 } from "three";
@@ -7338,7 +7469,7 @@ function BackgroundAudio({
7338
7469
  onEnded,
7339
7470
  onError
7340
7471
  }) {
7341
- const controlsRef = useContext15(PanoramaViewContext);
7472
+ const controlsRef = useContext16(PanoramaViewContext);
7342
7473
  if (!controlsRef) {
7343
7474
  throw new Error("<BackgroundAudio> must be rendered inside <PanoViewer>.");
7344
7475
  }
@@ -7346,22 +7477,23 @@ function BackgroundAudio({
7346
7477
  const [internalPlaying, setInternalPlaying] = useState6(defaultPlaying);
7347
7478
  const playing = isControlled ? controlledPlaying : internalPlaying;
7348
7479
  const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
7480
+ usePanoMediaActivationIntent(playing && urls.length > 0);
7349
7481
  const trackKey = urls.join("\0");
7350
- const currentRef = useRef13(null);
7351
- const outgoingRef = useRef13([]);
7352
- const fadingInRef = useRef13(false);
7353
- const isFirstTrackRef = useRef13(true);
7354
- const playingRef = useRef13(playing);
7355
- const loopRef = useRef13(loop);
7356
- const mutedRef = useRef13(muted);
7357
- const volumeRef = useRef13(volume);
7358
- const mutedPropRef = useRef13(muted);
7359
- const volumePropRef = useRef13(volume);
7360
- const fadeMsRef = useRef13(resolveFadeMs(fadeMs));
7361
- const onPlaybackStateChangeRef = useRef13(onPlaybackStateChange);
7362
- const onPlaybackErrorRef = useRef13(onPlaybackError);
7363
- const onEndedRef = useRef13(onEnded);
7364
- const onErrorRef = useRef13(onError);
7482
+ const currentRef = useRef14(null);
7483
+ const outgoingRef = useRef14([]);
7484
+ const fadingInRef = useRef14(false);
7485
+ const isFirstTrackRef = useRef14(true);
7486
+ const playingRef = useRef14(playing);
7487
+ const loopRef = useRef14(loop);
7488
+ const mutedRef = useRef14(muted);
7489
+ const volumeRef = useRef14(volume);
7490
+ const mutedPropRef = useRef14(muted);
7491
+ const volumePropRef = useRef14(volume);
7492
+ const fadeMsRef = useRef14(resolveFadeMs(fadeMs));
7493
+ const onPlaybackStateChangeRef = useRef14(onPlaybackStateChange);
7494
+ const onPlaybackErrorRef = useRef14(onPlaybackError);
7495
+ const onEndedRef = useRef14(onEnded);
7496
+ const onErrorRef = useRef14(onError);
7365
7497
  playingRef.current = playing;
7366
7498
  loopRef.current = loop;
7367
7499
  fadeMsRef.current = resolveFadeMs(fadeMs);
@@ -7377,7 +7509,7 @@ function BackgroundAudio({
7377
7509
  onPlaybackErrorRef.current = onPlaybackError;
7378
7510
  onEndedRef.current = onEnded;
7379
7511
  onErrorRef.current = onError;
7380
- const snapshotRef = useRef13({
7512
+ const snapshotRef = useRef14({
7381
7513
  ready: false,
7382
7514
  playing: false,
7383
7515
  blocked: false,
@@ -7385,7 +7517,7 @@ function BackgroundAudio({
7385
7517
  muted,
7386
7518
  volume
7387
7519
  });
7388
- const snapshotListenersRef = useRef13(/* @__PURE__ */ new Set());
7520
+ const snapshotListenersRef = useRef14(/* @__PURE__ */ new Set());
7389
7521
  const notifySnapshot = (patch) => {
7390
7522
  const prev = snapshotRef.current;
7391
7523
  snapshotRef.current = { ...prev, ...patch };
@@ -7393,7 +7525,7 @@ function BackgroundAudio({
7393
7525
  listener();
7394
7526
  }
7395
7527
  };
7396
- const isControlledRef = useRef13(isControlled);
7528
+ const isControlledRef = useRef14(isControlled);
7397
7529
  isControlledRef.current = isControlled;
7398
7530
  const controller = useMemo8(
7399
7531
  () => ({
@@ -7406,9 +7538,11 @@ function BackgroundAudio({
7406
7538
  getSnapshot: () => snapshotRef.current,
7407
7539
  play: () => {
7408
7540
  if (isControlledRef.current) {
7409
- return;
7541
+ return false;
7410
7542
  }
7543
+ currentRef.current?.handle.howl.play();
7411
7544
  setInternalPlaying(true);
7545
+ return true;
7412
7546
  },
7413
7547
  pause: () => {
7414
7548
  if (isControlledRef.current) {
@@ -7451,8 +7585,8 @@ function BackgroundAudio({
7451
7585
  }),
7452
7586
  []
7453
7587
  );
7454
- const bgmHost = useContext15(BackgroundAudioHostContext);
7455
- useEffect13(() => {
7588
+ const bgmHost = useContext16(BackgroundAudioHostContext);
7589
+ useEffect14(() => {
7456
7590
  if (!bgmHost) {
7457
7591
  return;
7458
7592
  }
@@ -7465,7 +7599,7 @@ function BackgroundAudio({
7465
7599
  }
7466
7600
  };
7467
7601
  }, [bgmHost, controller]);
7468
- useEffect13(() => {
7602
+ useEffect14(() => {
7469
7603
  return () => {
7470
7604
  fadingInRef.current = false;
7471
7605
  isFirstTrackRef.current = true;
@@ -7477,7 +7611,7 @@ function BackgroundAudio({
7477
7611
  outgoingRef.current = [];
7478
7612
  };
7479
7613
  }, []);
7480
- useEffect13(() => {
7614
+ useEffect14(() => {
7481
7615
  const previous = currentRef.current;
7482
7616
  if (previous?.key === trackKey && previous.crossOrigin === crossOrigin) {
7483
7617
  return;
@@ -7580,7 +7714,7 @@ function BackgroundAudio({
7580
7714
  retire(previous);
7581
7715
  }
7582
7716
  }, [crossOrigin, trackKey]);
7583
- useEffect13(() => {
7717
+ useEffect14(() => {
7584
7718
  const howl = currentRef.current?.handle.howl;
7585
7719
  if (!howl) {
7586
7720
  return;
@@ -7596,9 +7730,11 @@ function BackgroundAudio({
7596
7730
  outgoingRef.current = [];
7597
7731
  return;
7598
7732
  }
7599
- howl.play();
7733
+ if (!howl.playing()) {
7734
+ howl.play();
7735
+ }
7600
7736
  }, [playing, trackKey]);
7601
- useEffect13(() => {
7737
+ useEffect14(() => {
7602
7738
  const slot = currentRef.current;
7603
7739
  if (!slot) {
7604
7740
  return;
@@ -7613,7 +7749,7 @@ function BackgroundAudio({
7613
7749
  volume: clampAudioVolume(volumeRef.current)
7614
7750
  });
7615
7751
  }, [loop, muted, trackKey, volume]);
7616
- useEffect13(() => {
7752
+ useEffect14(() => {
7617
7753
  if (!pauseWhenHidden) {
7618
7754
  return;
7619
7755
  }
@@ -7639,13 +7775,13 @@ function BackgroundAudio({
7639
7775
  }
7640
7776
 
7641
7777
  // src/pano-filter/pano-filter.tsx
7642
- import { useContext as useContext16, useEffect as useEffect14, useMemo as useMemo9 } from "react";
7778
+ import { useContext as useContext17, useEffect as useEffect15, useMemo as useMemo9 } from "react";
7643
7779
  function PanoFilter({
7644
7780
  preset = "none",
7645
7781
  intensity,
7646
7782
  enabled = true
7647
7783
  }) {
7648
- const host = useContext16(PanoFilterHostContext);
7784
+ const host = useContext17(PanoFilterHostContext);
7649
7785
  if (!host) {
7650
7786
  throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
7651
7787
  }
@@ -7653,13 +7789,13 @@ function PanoFilter({
7653
7789
  () => resolvePanoFilterSnapshot({ preset, intensity, enabled }),
7654
7790
  [enabled, intensity, preset]
7655
7791
  );
7656
- useEffect14(() => {
7792
+ useEffect15(() => {
7657
7793
  claimPanoFilter(host);
7658
7794
  return () => {
7659
7795
  releasePanoFilter(host);
7660
7796
  };
7661
7797
  }, [host]);
7662
- useEffect14(() => {
7798
+ useEffect15(() => {
7663
7799
  setPanoFilterSnapshot(host, snapshot);
7664
7800
  }, [host, snapshot]);
7665
7801
  return null;
@@ -7670,10 +7806,10 @@ import { useFrame as useFrame6, useThree as useThree9 } from "@react-three/fiber
7670
7806
  import {
7671
7807
  forwardRef as forwardRef3,
7672
7808
  useCallback as useCallback7,
7673
- useContext as useContext17,
7674
- useEffect as useEffect15,
7809
+ useContext as useContext18,
7810
+ useEffect as useEffect16,
7675
7811
  useImperativeHandle as useImperativeHandle3,
7676
- useRef as useRef14,
7812
+ useRef as useRef15,
7677
7813
  useState as useState7
7678
7814
  } from "react";
7679
7815
 
@@ -7775,24 +7911,24 @@ var Gyro = forwardRef3(function Gyro2({
7775
7911
  onDisable,
7776
7912
  onDenied
7777
7913
  }, ref) {
7778
- const controlsRef = useContext17(PanoramaViewContext);
7779
- const eventBus = useContext17(PanoEventBusContext);
7914
+ const controlsRef = useContext18(PanoramaViewContext);
7915
+ const eventBus = useContext18(PanoEventBusContext);
7780
7916
  const { gl } = useThree9();
7781
7917
  const [internallyDisabled, setInternallyDisabled] = useState7(false);
7782
- const availableRef = useRef14(false);
7783
- const availabilityReportedRef = useRef14(null);
7784
- const activeRef = useRef14(false);
7785
- const permissionRef = useRef14(deviceOrientationPermissionState);
7786
- const absoluteEventSourceRef = useRef14(null);
7787
- const rawQuaternionRef = useRef14(null);
7788
- const calibrationRef = useRef14(null);
7789
- const absoluteOffsetRef = useRef14({ yaw: 0, pitch: 0 });
7790
- const screenAngleRef = useRef14(getScreenOrientationAngle());
7791
- const startPoseRef = useRef14(null);
7792
- const enabledAtRef = useRef14(0);
7793
- const filteredPoseRef = useRef14(null);
7794
- const lastAppliedPoseRef = useRef14(null);
7795
- const callbacksRef = useRef14({
7918
+ const availableRef = useRef15(false);
7919
+ const availabilityReportedRef = useRef15(null);
7920
+ const activeRef = useRef15(false);
7921
+ const permissionRef = useRef15(deviceOrientationPermissionState);
7922
+ const absoluteEventSourceRef = useRef15(null);
7923
+ const rawQuaternionRef = useRef15(null);
7924
+ const calibrationRef = useRef15(null);
7925
+ const absoluteOffsetRef = useRef15({ yaw: 0, pitch: 0 });
7926
+ const screenAngleRef = useRef15(getScreenOrientationAngle());
7927
+ const startPoseRef = useRef15(null);
7928
+ const enabledAtRef = useRef15(0);
7929
+ const filteredPoseRef = useRef15(null);
7930
+ const lastAppliedPoseRef = useRef15(null);
7931
+ const callbacksRef = useRef15({
7796
7932
  onAvailable,
7797
7933
  onUnavailable,
7798
7934
  onEnable,
@@ -7937,22 +8073,22 @@ var Gyro = forwardRef3(function Gyro2({
7937
8073
  }),
7938
8074
  [requestPermission, resetSensor]
7939
8075
  );
7940
- useEffect15(() => {
8076
+ useEffect16(() => {
7941
8077
  if (!enabled) {
7942
8078
  setInternallyDisabled(false);
7943
8079
  }
7944
8080
  }, [enabled]);
7945
- useEffect15(() => {
8081
+ useEffect16(() => {
7946
8082
  const supported = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined" && (desktopSupport || isMobileDevice());
7947
8083
  setAvailable(supported);
7948
8084
  return () => {
7949
8085
  availableRef.current = false;
7950
8086
  };
7951
8087
  }, [desktopSupport, setAvailable]);
7952
- useEffect15(() => {
8088
+ useEffect16(() => {
7953
8089
  controlsRef.current?.setGyroTouchMode(touchMode);
7954
8090
  }, [controlsRef, touchMode]);
7955
- useEffect15(() => {
8091
+ useEffect16(() => {
7956
8092
  if (!enabled || internallyDisabled || touchMode !== "disablegyro") {
7957
8093
  return;
7958
8094
  }
@@ -7966,7 +8102,7 @@ var Gyro = forwardRef3(function Gyro2({
7966
8102
  gl.domElement.removeEventListener("pointerdown", onPointerDown);
7967
8103
  };
7968
8104
  }, [enabled, gl, internallyDisabled, touchMode]);
7969
- useEffect15(() => {
8105
+ useEffect16(() => {
7970
8106
  if (!enabled || internallyDisabled || !availableRef.current) {
7971
8107
  deactivate();
7972
8108
  return;
@@ -8131,11 +8267,11 @@ import { useThree as useThree12 } from "@react-three/fiber";
8131
8267
  import {
8132
8268
  forwardRef as forwardRef4,
8133
8269
  useCallback as useCallback8,
8134
- useContext as useContext19,
8135
- useEffect as useEffect19,
8270
+ useContext as useContext20,
8271
+ useEffect as useEffect20,
8136
8272
  useImperativeHandle as useImperativeHandle4,
8137
8273
  useMemo as useMemo11,
8138
- useRef as useRef18,
8274
+ useRef as useRef19,
8139
8275
  useState as useState8
8140
8276
  } from "react";
8141
8277
 
@@ -8160,14 +8296,14 @@ async function detectWebVRCapabilities() {
8160
8296
 
8161
8297
  // src/webvr/reticle.tsx
8162
8298
  import { useFrame as useFrame7, useThree as useThree10 } from "@react-three/fiber";
8163
- import { useRef as useRef15 } from "react";
8299
+ import { useRef as useRef16 } from "react";
8164
8300
  import {
8165
8301
  DoubleSide,
8166
8302
  Raycaster as Raycaster2,
8167
8303
  Vector2 as Vector22,
8168
8304
  Vector3 as Vector37
8169
8305
  } from "three";
8170
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
8306
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
8171
8307
  var CENTER_NDC = new Vector22(0, 0);
8172
8308
  var HUD_DISTANCE = 2;
8173
8309
  var RETICLE_SCALE = 1;
@@ -8251,13 +8387,13 @@ function WebVRReticle({
8251
8387
  dwellMs,
8252
8388
  visible
8253
8389
  }) {
8254
- const groupRef = useRef15(null);
8255
- const ringMeshRef = useRef15(null);
8256
- const directionRef = useRef15(new Vector37());
8257
- const raycasterRef = useRef15(new Raycaster2());
8258
- const hoveredRef = useRef15(null);
8259
- const dwellRef = useRef15(0);
8260
- const clickedRef = useRef15(false);
8390
+ const groupRef = useRef16(null);
8391
+ const ringMeshRef = useRef16(null);
8392
+ const directionRef = useRef16(new Vector37());
8393
+ const raycasterRef = useRef16(new Raycaster2());
8394
+ const hoveredRef = useRef16(null);
8395
+ const dwellRef = useRef16(0);
8396
+ const clickedRef = useRef16(false);
8261
8397
  const { camera, gl, scene } = useThree10();
8262
8398
  useFrame7((_, deltaSeconds) => {
8263
8399
  const group = groupRef.current;
@@ -8342,8 +8478,8 @@ function WebVRReticle({
8342
8478
  raycast: noopRaycast,
8343
8479
  renderOrder: RETICLE_RENDER_ORDER + 1,
8344
8480
  children: [
8345
- /* @__PURE__ */ jsx12("boxGeometry", { args: [CROSSHAIR_LENGTH, CROSSHAIR_THICKNESS, 1e-3] }),
8346
- /* @__PURE__ */ jsx12(
8481
+ /* @__PURE__ */ jsx13("boxGeometry", { args: [CROSSHAIR_LENGTH, CROSSHAIR_THICKNESS, 1e-3] }),
8482
+ /* @__PURE__ */ jsx13(
8347
8483
  "meshBasicMaterial",
8348
8484
  {
8349
8485
  color: "#ffffff",
@@ -8363,8 +8499,8 @@ function WebVRReticle({
8363
8499
  raycast: noopRaycast,
8364
8500
  renderOrder: RETICLE_RENDER_ORDER + 1,
8365
8501
  children: [
8366
- /* @__PURE__ */ jsx12("boxGeometry", { args: [CROSSHAIR_THICKNESS, CROSSHAIR_LENGTH, 1e-3] }),
8367
- /* @__PURE__ */ jsx12(
8502
+ /* @__PURE__ */ jsx13("boxGeometry", { args: [CROSSHAIR_THICKNESS, CROSSHAIR_LENGTH, 1e-3] }),
8503
+ /* @__PURE__ */ jsx13(
8368
8504
  "meshBasicMaterial",
8369
8505
  {
8370
8506
  color: "#ffffff",
@@ -8386,7 +8522,7 @@ function WebVRReticle({
8386
8522
  renderOrder: RETICLE_RENDER_ORDER + 2,
8387
8523
  visible: false,
8388
8524
  children: [
8389
- /* @__PURE__ */ jsx12(
8525
+ /* @__PURE__ */ jsx13(
8390
8526
  "ringGeometry",
8391
8527
  {
8392
8528
  args: [
@@ -8399,7 +8535,7 @@ function WebVRReticle({
8399
8535
  ]
8400
8536
  }
8401
8537
  ),
8402
- /* @__PURE__ */ jsx12(
8538
+ /* @__PURE__ */ jsx13(
8403
8539
  "meshBasicMaterial",
8404
8540
  {
8405
8541
  color: "#ffffff",
@@ -8420,7 +8556,7 @@ function WebVRReticle({
8420
8556
 
8421
8557
  // src/webvr/stereo.tsx
8422
8558
  import { useFrame as useFrame8, useThree as useThree11 } from "@react-three/fiber";
8423
- import { useContext as useContext18, useEffect as useEffect16, useMemo as useMemo10, useRef as useRef16 } from "react";
8559
+ import { useContext as useContext19, useEffect as useEffect17, useMemo as useMemo10, useRef as useRef17 } from "react";
8424
8560
  import {
8425
8561
  Mesh as Mesh2,
8426
8562
  OrthographicCamera,
@@ -8506,25 +8642,25 @@ function WebVRStereoRenderer({
8506
8642
  screensize
8507
8643
  }) {
8508
8644
  const { camera, gl } = useThree11();
8509
- const runtime = useContext18(WebVRRuntimeContext);
8510
- const fallbackStereoRef = useRef16(null);
8645
+ const runtime = useContext19(WebVRRuntimeContext);
8646
+ const fallbackStereoRef = useRef17(null);
8511
8647
  if (!fallbackStereoRef.current) {
8512
8648
  fallbackStereoRef.current = new StereoCamera2();
8513
8649
  }
8514
8650
  const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
8515
- const stereoRef = useRef16(stereo);
8651
+ const stereoRef = useRef17(stereo);
8516
8652
  stereoRef.current = stereo;
8517
8653
  const resources = useMemo10(createDistortionResources, []);
8518
- const drawingSizeRef = useRef16(new Vector23());
8519
- const viewportRef = useRef16(new Vector4());
8520
- const scissorRef = useRef16(new Vector4());
8521
- const originalFovRef = useRef16(null);
8522
- const stereoActiveRef = useRef16(false);
8523
- const profileRef = useRef16(profile);
8524
- const screensizeRef = useRef16(screensize);
8654
+ const drawingSizeRef = useRef17(new Vector23());
8655
+ const viewportRef = useRef17(new Vector4());
8656
+ const scissorRef = useRef17(new Vector4());
8657
+ const originalFovRef = useRef17(null);
8658
+ const stereoActiveRef = useRef17(false);
8659
+ const profileRef = useRef17(profile);
8660
+ const screensizeRef = useRef17(screensize);
8525
8661
  profileRef.current = profile;
8526
8662
  screensizeRef.current = screensize;
8527
- useEffect16(
8663
+ useEffect17(
8528
8664
  () => () => {
8529
8665
  resources.geometry.dispose();
8530
8666
  resources.material.dispose();
@@ -8532,7 +8668,7 @@ function WebVRStereoRenderer({
8532
8668
  },
8533
8669
  [resources]
8534
8670
  );
8535
- useEffect16(() => {
8671
+ useEffect17(() => {
8536
8672
  const originalRender = gl.render.bind(gl);
8537
8673
  gl.render = (sceneToRender, cameraToRender) => {
8538
8674
  if (!stereoActiveRef.current || !(cameraToRender instanceof PerspectiveCamera2)) {
@@ -8596,7 +8732,7 @@ function WebVRStereoRenderer({
8596
8732
  gl.render = originalRender;
8597
8733
  };
8598
8734
  }, [gl, resources]);
8599
- useEffect16(
8735
+ useEffect17(
8600
8736
  () => () => {
8601
8737
  if (runtime) {
8602
8738
  runtime.stereoView.active = false;
@@ -8631,7 +8767,7 @@ function WebVRStereoRenderer({
8631
8767
  }
8632
8768
 
8633
8769
  // src/webvr/pointerlock.ts
8634
- import { useEffect as useEffect17, useRef as useRef17 } from "react";
8770
+ import { useEffect as useEffect18, useRef as useRef18 } from "react";
8635
8771
  var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
8636
8772
  async function requestWebVRPointerLock(element) {
8637
8773
  if (typeof document === "undefined") {
@@ -8664,11 +8800,11 @@ function exitWebVRPointerLock(element) {
8664
8800
  }
8665
8801
  function useWebVRPointerLock(enabled, element) {
8666
8802
  const cursor = usePanoCursor();
8667
- const cursorRef = useRef17(cursor);
8668
- const enabledRef = useRef17(enabled);
8803
+ const cursorRef = useRef18(cursor);
8804
+ const enabledRef = useRef18(enabled);
8669
8805
  cursorRef.current = cursor;
8670
8806
  enabledRef.current = enabled;
8671
- useEffect17(() => {
8807
+ useEffect18(() => {
8672
8808
  if (!enabled || !element) {
8673
8809
  return;
8674
8810
  }
@@ -8698,7 +8834,7 @@ function useWebVRPointerLock(enabled, element) {
8698
8834
  }
8699
8835
 
8700
8836
  // src/webvr/wakelock.ts
8701
- import { useEffect as useEffect18 } from "react";
8837
+ import { useEffect as useEffect19 } from "react";
8702
8838
 
8703
8839
  // src/webvr/wakelock-fallback.ts
8704
8840
  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==";
@@ -8832,7 +8968,7 @@ function releaseWebVRWakeLock() {
8832
8968
  stopFallbackVideo();
8833
8969
  }
8834
8970
  function useWebVRWakeLock(enabled) {
8835
- useEffect18(() => {
8971
+ useEffect19(() => {
8836
8972
  if (!enabled) {
8837
8973
  return;
8838
8974
  }
@@ -8851,7 +8987,7 @@ function useWebVRWakeLock(enabled) {
8851
8987
  }
8852
8988
 
8853
8989
  // src/webvr/webvr.tsx
8854
- import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
8990
+ import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
8855
8991
  function initializeSettings(screensize, profile) {
8856
8992
  const stored = loadWebVRSettings();
8857
8993
  return {
@@ -8880,24 +9016,24 @@ var WebVR = forwardRef4(function WebVR2({
8880
9016
  onDenied,
8881
9017
  onUnknownDevice
8882
9018
  }, ref) {
8883
- const runtime = useContext19(WebVRRuntimeContext);
8884
- const controlsRef = useContext19(PanoramaViewContext);
8885
- const eventBus = useContext19(PanoEventBusContext);
9019
+ const runtime = useContext20(WebVRRuntimeContext);
9020
+ const controlsRef = useContext20(PanoramaViewContext);
9021
+ const eventBus = useContext20(PanoEventBusContext);
8886
9022
  const gl = useThree12((state) => state.gl);
8887
- const gyroRef = useRef18(null);
8888
- const capabilitiesRef = useRef18({
9023
+ const gyroRef = useRef19(null);
9024
+ const capabilitiesRef = useRef19({
8889
9025
  mobile: false,
8890
9026
  sensor: false,
8891
9027
  webxr: false
8892
9028
  });
8893
- const availableRef = useRef18(false);
8894
- const modeRef = useRef18(null);
8895
- const webXRSessionRef = useRef18(null);
9029
+ const availableRef = useRef19(false);
9030
+ const modeRef = useRef19(null);
9031
+ const webXRSessionRef = useRef19(null);
8896
9032
  const [mode, setMode] = useState8(null);
8897
9033
  const [settings, setSettings] = useState8(
8898
9034
  () => initializeSettings(screensize, profile)
8899
9035
  );
8900
- const callbacksRef = useRef18({
9036
+ const callbacksRef = useRef19({
8901
9037
  onAvailable,
8902
9038
  onDenied,
8903
9039
  onEnterVR,
@@ -9107,7 +9243,7 @@ var WebVR = forwardRef4(function WebVR2({
9107
9243
  }),
9108
9244
  [enterVR, exitVR, requestPermission, toggleVR]
9109
9245
  );
9110
- useEffect19(() => {
9246
+ useEffect20(() => {
9111
9247
  let active = true;
9112
9248
  void detectWebVRCapabilities().then((capabilities) => {
9113
9249
  if (!active) {
@@ -9129,7 +9265,7 @@ var WebVR = forwardRef4(function WebVR2({
9129
9265
  active = false;
9130
9266
  };
9131
9267
  }, [desktopSupport, eventBus, fakeSupport, host, mobileVr]);
9132
- useEffect19(() => {
9268
+ useEffect20(() => {
9133
9269
  host.controller = controller;
9134
9270
  return () => {
9135
9271
  if (host.controller === controller) {
@@ -9138,10 +9274,10 @@ var WebVR = forwardRef4(function WebVR2({
9138
9274
  }
9139
9275
  };
9140
9276
  }, [controller, host]);
9141
- useEffect19(() => {
9277
+ useEffect20(() => {
9142
9278
  updateWebVRHost(host, { chrome, mode, settings });
9143
9279
  }, [chrome, host, mode, settings]);
9144
- useEffect19(() => {
9280
+ useEffect20(() => {
9145
9281
  if (mode !== "fake") {
9146
9282
  return;
9147
9283
  }
@@ -9165,7 +9301,7 @@ var WebVR = forwardRef4(function WebVR2({
9165
9301
  document.removeEventListener("mousemove", onMouseMove);
9166
9302
  };
9167
9303
  }, [controlsRef, gl.domElement, mode, mousePointerLock]);
9168
- useEffect19(
9304
+ useEffect20(
9169
9305
  () => () => {
9170
9306
  const session2 = webXRSessionRef.current;
9171
9307
  if (session2) {
@@ -9185,7 +9321,7 @@ var WebVR = forwardRef4(function WebVR2({
9185
9321
  wakelock && (mode === "mobilevr" || mode === "fake")
9186
9322
  );
9187
9323
  return /* @__PURE__ */ jsxs8(Fragment4, { children: [
9188
- /* @__PURE__ */ jsx13(
9324
+ /* @__PURE__ */ jsx14(
9189
9325
  Gyro,
9190
9326
  {
9191
9327
  ref: gyroRef,
@@ -9199,7 +9335,7 @@ var WebVR = forwardRef4(function WebVR2({
9199
9335
  touchMode: "off"
9200
9336
  }
9201
9337
  ),
9202
- /* @__PURE__ */ jsx13(
9338
+ /* @__PURE__ */ jsx14(
9203
9339
  WebVRStereoRenderer,
9204
9340
  {
9205
9341
  mode,
@@ -9207,7 +9343,7 @@ var WebVR = forwardRef4(function WebVR2({
9207
9343
  screensize: settings.screensize
9208
9344
  }
9209
9345
  ),
9210
- /* @__PURE__ */ jsx13(
9346
+ /* @__PURE__ */ jsx14(
9211
9347
  WebVRReticle,
9212
9348
  {
9213
9349
  dwellMs: cursorDwellMs,
@@ -9218,7 +9354,7 @@ var WebVR = forwardRef4(function WebVR2({
9218
9354
  });
9219
9355
 
9220
9356
  // src/use-pano-viewer.ts
9221
- import { useMemo as useMemo12, useRef as useRef19 } from "react";
9357
+ import { useMemo as useMemo12, useRef as useRef20 } from "react";
9222
9358
  function createPanoViewerHandle(ref) {
9223
9359
  return {
9224
9360
  getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
@@ -9228,6 +9364,7 @@ function createPanoViewerHandle(ref) {
9228
9364
  reset: () => {
9229
9365
  ref.current?.reset();
9230
9366
  },
9367
+ activateMedia: () => ref.current?.activateMedia() ?? Promise.resolve(),
9231
9368
  enterFullscreen: () => ref.current?.enterFullscreen() ?? Promise.resolve(),
9232
9369
  exitFullscreen: () => ref.current?.exitFullscreen() ?? Promise.resolve(),
9233
9370
  toggleFullscreen: () => ref.current?.toggleFullscreen() ?? Promise.resolve(),
@@ -9295,14 +9432,14 @@ function createPanoViewerHandle(ref) {
9295
9432
  };
9296
9433
  }
9297
9434
  function usePanoViewer() {
9298
- const ref = useRef19(null);
9435
+ const ref = useRef20(null);
9299
9436
  const handle = useMemo12(() => createPanoViewerHandle(ref), []);
9300
9437
  return useMemo12(() => ({ ref, ...handle }), [handle]);
9301
9438
  }
9302
9439
 
9303
9440
  // src/sphere.tsx
9304
9441
  import { useThree as useThree13 } from "@react-three/fiber";
9305
- import { useEffect as useEffect20, useMemo as useMemo14, useRef as useRef21, useState as useState9 } from "react";
9442
+ import { useEffect as useEffect21, useMemo as useMemo14, useRef as useRef22, useState as useState9 } from "react";
9306
9443
  import {
9307
9444
  BackSide as BackSide2,
9308
9445
  LinearFilter,
@@ -9335,7 +9472,7 @@ function resolveUrlAgainstFile(fileUrl, path) {
9335
9472
  }
9336
9473
 
9337
9474
  // src/pano-filter/pano-basic-material.tsx
9338
- import { useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef20 } from "react";
9475
+ import { useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef21 } from "react";
9339
9476
 
9340
9477
  // src/pano-filter/shaders.ts
9341
9478
  var GLSL_FILTER_COMMON = `
@@ -9486,7 +9623,7 @@ diffuseColor.rgb = mix(diffuseColor.rgb, applyPanoFilter(diffuseColor.rgb), clam
9486
9623
  }
9487
9624
 
9488
9625
  // src/pano-filter/pano-basic-material.tsx
9489
- import { jsx as jsx14 } from "react/jsx-runtime";
9626
+ import { jsx as jsx15 } from "react/jsx-runtime";
9490
9627
  function PanoBasicMaterial({
9491
9628
  map,
9492
9629
  side,
@@ -9495,9 +9632,9 @@ function PanoBasicMaterial({
9495
9632
  toneMapped = false
9496
9633
  }) {
9497
9634
  const snapshot = usePanoFilterSnapshot();
9498
- const materialRef = useRef20(null);
9499
- const intensityRef = useRef20(snapshot.intensity);
9500
- const intensityUniformRef = useRef20(null);
9635
+ const materialRef = useRef21(null);
9636
+ const intensityRef = useRef21(snapshot.intensity);
9637
+ const intensityUniformRef = useRef21(null);
9501
9638
  intensityRef.current = snapshot.intensity;
9502
9639
  const active = isPanoFilterActive(snapshot);
9503
9640
  const preset = snapshot.preset;
@@ -9533,7 +9670,7 @@ function PanoBasicMaterial({
9533
9670
  intensityUniformRef.current.value = snapshot.intensity;
9534
9671
  }
9535
9672
  }, [snapshot.intensity]);
9536
- return /* @__PURE__ */ jsx14(
9673
+ return /* @__PURE__ */ jsx15(
9537
9674
  "meshBasicMaterial",
9538
9675
  {
9539
9676
  ref: materialRef,
@@ -9549,14 +9686,14 @@ function PanoBasicMaterial({
9549
9686
  }
9550
9687
 
9551
9688
  // src/sphere.tsx
9552
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
9689
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
9553
9690
  function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9554
9691
  const [texture, setTexture] = useState9(null);
9555
- const onLoadRef = useRef21(onLoad);
9556
- const onErrorRef = useRef21(onError);
9692
+ const onLoadRef = useRef22(onLoad);
9693
+ const onErrorRef = useRef22(onError);
9557
9694
  onLoadRef.current = onLoad;
9558
9695
  onErrorRef.current = onError;
9559
- useEffect20(() => {
9696
+ useEffect21(() => {
9560
9697
  if (!url) {
9561
9698
  setTexture(null);
9562
9699
  return;
@@ -9595,7 +9732,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
9595
9732
  active = false;
9596
9733
  };
9597
9734
  }, [anisotropy, generateMipmaps, url]);
9598
- useEffect20(
9735
+ useEffect21(
9599
9736
  () => () => {
9600
9737
  texture?.dispose();
9601
9738
  },
@@ -9634,11 +9771,11 @@ function Sphere({
9634
9771
  onPreviewError
9635
9772
  );
9636
9773
  const displayTexture = texture ?? previewTexture;
9637
- const readyRef = useRef21(false);
9638
- useEffect20(() => {
9774
+ const readyRef = useRef22(false);
9775
+ useEffect21(() => {
9639
9776
  readyRef.current = false;
9640
9777
  }, [resolvedPreviewUrl, src]);
9641
- useEffect20(() => {
9778
+ useEffect21(() => {
9642
9779
  if (!displayTexture || readyRef.current) {
9643
9780
  return;
9644
9781
  }
@@ -9654,8 +9791,8 @@ function Sphere({
9654
9791
  rotation: [0, MathUtils5.degToRad(90 + yawOffset), 0],
9655
9792
  visible,
9656
9793
  children: [
9657
- /* @__PURE__ */ jsx15("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
9658
- /* @__PURE__ */ jsx15(
9794
+ /* @__PURE__ */ jsx16("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
9795
+ /* @__PURE__ */ jsx16(
9659
9796
  PanoBasicMaterial,
9660
9797
  {
9661
9798
  map: displayTexture,
@@ -9672,11 +9809,11 @@ function Sphere({
9672
9809
  import { useThree as useThree14 } from "@react-three/fiber";
9673
9810
  import {
9674
9811
  useCallback as useCallback9,
9675
- useContext as useContext20,
9676
- useEffect as useEffect21,
9812
+ useContext as useContext21,
9813
+ useEffect as useEffect22,
9677
9814
  useLayoutEffect as useLayoutEffect3,
9678
9815
  useMemo as useMemo15,
9679
- useRef as useRef22,
9816
+ useRef as useRef23,
9680
9817
  useState as useState10
9681
9818
  } from "react";
9682
9819
  import {
@@ -9689,7 +9826,7 @@ import {
9689
9826
  TextureLoader as TextureLoader2,
9690
9827
  VideoTexture
9691
9828
  } from "three";
9692
- import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
9829
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
9693
9830
  var EMPTY_TRACKS = [];
9694
9831
  var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
9695
9832
  function createEmptySnapshot() {
@@ -9775,9 +9912,9 @@ function applyEquirectangularLayout(texture, anisotropy) {
9775
9912
  function usePosterTexture(poster, onError) {
9776
9913
  const gl = useThree14((state) => state.gl);
9777
9914
  const [texture, setTexture] = useState10(null);
9778
- const onErrorRef = useRef22(onError);
9915
+ const onErrorRef = useRef23(onError);
9779
9916
  onErrorRef.current = onError;
9780
- useEffect21(() => {
9917
+ useEffect22(() => {
9781
9918
  let active = true;
9782
9919
  setTexture(null);
9783
9920
  if (!poster) {
@@ -9814,7 +9951,7 @@ function usePosterTexture(poster, onError) {
9814
9951
  active = false;
9815
9952
  };
9816
9953
  }, [gl, poster]);
9817
- useEffect21(
9954
+ useEffect22(
9818
9955
  () => () => {
9819
9956
  texture?.dispose();
9820
9957
  },
@@ -9871,9 +10008,10 @@ function PanoVideo({
9871
10008
  onVariantChange,
9872
10009
  onTrackChange
9873
10010
  }) {
10011
+ usePanoMediaActivationIntent(autoPlay);
9874
10012
  const gl = useThree14((state) => state.gl);
9875
- const host = useContext20(PanoVideoHostContext);
9876
- const overlay = useContext20(PanoChromeOverlayContext);
10013
+ const host = useContext21(PanoVideoHostContext);
10014
+ const overlay = useContext21(PanoChromeOverlayContext);
9877
10015
  const variants = useMemo15(
9878
10016
  () => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
9879
10017
  [poster, src, variantsProp]
@@ -9893,17 +10031,17 @@ function PanoVideo({
9893
10031
  () => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
9894
10032
  );
9895
10033
  const [ready, setReady] = useState10(false);
9896
- const autoPlayRef = useRef22(autoPlay);
10034
+ const autoPlayRef = useRef23(autoPlay);
9897
10035
  autoPlayRef.current = autoPlay;
9898
- const blockedRef = useRef22(false);
9899
- const captionAppearanceOverrideRef = useRef22(
10036
+ const blockedRef = useRef23(false);
10037
+ const captionAppearanceOverrideRef = useRef23(
9900
10038
  {}
9901
10039
  );
9902
- const mediaCapabilitiesRef = useRef22({
10040
+ const mediaCapabilitiesRef = useRef23({
9903
10041
  volumeAdjustable: true,
9904
10042
  playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
9905
10043
  });
9906
- const storeRef = useRef22(null);
10044
+ const storeRef = useRef23(null);
9907
10045
  if (!storeRef.current) {
9908
10046
  storeRef.current = {
9909
10047
  snapshot: {
@@ -9913,7 +10051,7 @@ function PanoVideo({
9913
10051
  listeners: /* @__PURE__ */ new Set()
9914
10052
  };
9915
10053
  }
9916
- const actionsRef = useRef22({
10054
+ const actionsRef = useRef23({
9917
10055
  play: async () => {
9918
10056
  },
9919
10057
  pause: () => {
@@ -9933,12 +10071,12 @@ function PanoVideo({
9933
10071
  setCaptionAppearance: (_appearance) => {
9934
10072
  }
9935
10073
  });
9936
- const onLoadRef = useRef22(onLoad);
9937
- const onErrorRef = useRef22(onError);
9938
- const onPlaybackStateChangeRef = useRef22(onPlaybackStateChange);
9939
- const onEndedRef = useRef22(onEnded);
9940
- const onVariantChangeRef = useRef22(onVariantChange);
9941
- const onTrackChangeRef = useRef22(onTrackChange);
10074
+ const onLoadRef = useRef23(onLoad);
10075
+ const onErrorRef = useRef23(onError);
10076
+ const onPlaybackStateChangeRef = useRef23(onPlaybackStateChange);
10077
+ const onEndedRef = useRef23(onEnded);
10078
+ const onVariantChangeRef = useRef23(onVariantChange);
10079
+ const onTrackChangeRef = useRef23(onTrackChange);
9942
10080
  onLoadRef.current = onLoad;
9943
10081
  onErrorRef.current = onError;
9944
10082
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
@@ -9962,7 +10100,7 @@ function PanoVideo({
9962
10100
  texture.generateMipmaps = false;
9963
10101
  return { video, texture };
9964
10102
  }, []);
9965
- useEffect21(
10103
+ useEffect22(
9966
10104
  () => () => {
9967
10105
  if (!resource) {
9968
10106
  return;
@@ -9977,13 +10115,13 @@ function PanoVideo({
9977
10115
  },
9978
10116
  [resource]
9979
10117
  );
9980
- useEffect21(() => {
10118
+ useEffect22(() => {
9981
10119
  if (!resource) {
9982
10120
  return;
9983
10121
  }
9984
10122
  resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
9985
10123
  }, [gl, resource]);
9986
- useEffect21(() => {
10124
+ useEffect22(() => {
9987
10125
  if (!resource || !overlay?.overlayElement) {
9988
10126
  return;
9989
10127
  }
@@ -10136,10 +10274,10 @@ function PanoVideo({
10136
10274
  };
10137
10275
  emitSnapshot();
10138
10276
  }, [emitSnapshot, playbackRates, resource]);
10139
- useEffect21(() => {
10277
+ useEffect22(() => {
10140
10278
  emitSnapshot();
10141
10279
  }, [emitSnapshot]);
10142
- useEffect21(() => {
10280
+ useEffect22(() => {
10143
10281
  if (!resource || !activeVariant || !mediaKey) {
10144
10282
  return;
10145
10283
  }
@@ -10196,7 +10334,7 @@ function PanoVideo({
10196
10334
  video.removeEventListener("error", handleError);
10197
10335
  };
10198
10336
  }, [mediaKey, resource]);
10199
- useEffect21(() => {
10337
+ useEffect22(() => {
10200
10338
  if (!resource) {
10201
10339
  return;
10202
10340
  }
@@ -10286,7 +10424,7 @@ function PanoVideo({
10286
10424
  }
10287
10425
  };
10288
10426
  }, [emitSnapshot, resource]);
10289
- useEffect21(() => {
10427
+ useEffect22(() => {
10290
10428
  if (!resource) {
10291
10429
  return;
10292
10430
  }
@@ -10297,9 +10435,16 @@ function PanoVideo({
10297
10435
  video.volume = clampVolume(volume);
10298
10436
  }
10299
10437
  video.playsInline = playsInline;
10438
+ if (playsInline) {
10439
+ video.setAttribute("playsinline", "true");
10440
+ video.setAttribute("webkit-playsinline", "true");
10441
+ } else {
10442
+ video.removeAttribute("playsinline");
10443
+ video.removeAttribute("webkit-playsinline");
10444
+ }
10300
10445
  video.preload = preload;
10301
10446
  }, [loop, muted, playsInline, preload, resource, volume]);
10302
- useEffect21(() => {
10447
+ useEffect22(() => {
10303
10448
  if (!resource) {
10304
10449
  return;
10305
10450
  }
@@ -10349,7 +10494,7 @@ function PanoVideo({
10349
10494
  video.removeEventListener("ratechange", handleVolume);
10350
10495
  };
10351
10496
  }, [emitSnapshot, resource]);
10352
- useEffect21(() => {
10497
+ useEffect22(() => {
10353
10498
  if (!resource) {
10354
10499
  return;
10355
10500
  }
@@ -10384,7 +10529,7 @@ function PanoVideo({
10384
10529
  video.textTracks.removeEventListener("change", applyModes);
10385
10530
  };
10386
10531
  }, [emitSnapshot, resource, trackId, tracks]);
10387
- useEffect21(() => {
10532
+ useEffect22(() => {
10388
10533
  if (!captionsEnabled) {
10389
10534
  setTrackId(null);
10390
10535
  return;
@@ -10402,8 +10547,8 @@ function PanoVideo({
10402
10547
  rotation: [0, MathUtils6.degToRad(90 + yawOffset), 0],
10403
10548
  visible,
10404
10549
  children: [
10405
- /* @__PURE__ */ jsx16("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
10406
- /* @__PURE__ */ jsx16(
10550
+ /* @__PURE__ */ jsx17("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
10551
+ /* @__PURE__ */ jsx17(
10407
10552
  PanoBasicMaterial,
10408
10553
  {
10409
10554
  map: activeTexture,
@@ -10414,7 +10559,7 @@ function PanoVideo({
10414
10559
  ]
10415
10560
  }
10416
10561
  ) : null,
10417
- captionsEnabled ? /* @__PURE__ */ jsx16(PanoVideoCaptions, { appearance: typeof captions === "object" ? captions : void 0 }) : null
10562
+ captionsEnabled ? /* @__PURE__ */ jsx17(PanoVideoCaptions, { appearance: typeof captions === "object" ? captions : void 0 }) : null
10418
10563
  ] });
10419
10564
  }
10420
10565
 
@@ -10423,10 +10568,10 @@ import { useFrame as useFrame12, useThree as useThree19 } from "@react-three/fib
10423
10568
  import {
10424
10569
  Fragment as Fragment6,
10425
10570
  useCallback as useCallback10,
10426
- useContext as useContext22,
10427
- useEffect as useEffect26,
10571
+ useContext as useContext23,
10572
+ useEffect as useEffect27,
10428
10573
  useMemo as useMemo20,
10429
- useRef as useRef26,
10574
+ useRef as useRef27,
10430
10575
  useState as useState12
10431
10576
  } from "react";
10432
10577
  import {
@@ -10483,7 +10628,7 @@ function isSnapshotTransition(preset) {
10483
10628
 
10484
10629
  // src/scene-transitions/particle-overlay.tsx
10485
10630
  import { useFrame as useFrame9, useThree as useThree15 } from "@react-three/fiber";
10486
- import { useEffect as useEffect22, useMemo as useMemo16, useRef as useRef23 } from "react";
10631
+ import { useEffect as useEffect23, useMemo as useMemo16, useRef as useRef24 } from "react";
10487
10632
  import {
10488
10633
  DoubleSide as DoubleSide2,
10489
10634
  InstancedBufferAttribute,
@@ -10546,7 +10691,7 @@ function overlayProgress(elapsedTime, duration, startTime) {
10546
10691
  }
10547
10692
 
10548
10693
  // src/scene-transitions/particle-overlay.tsx
10549
- import { jsx as jsx17 } from "react/jsx-runtime";
10694
+ import { jsx as jsx18 } from "react/jsx-runtime";
10550
10695
  var PARTICLE_GRID = 48;
10551
10696
  var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
10552
10697
  var PARTICLE_VERTEX_SHADER = `
@@ -10623,10 +10768,10 @@ function ParticleOverlay({
10623
10768
  onFinish
10624
10769
  }) {
10625
10770
  const { camera } = useThree15();
10626
- const meshRef = useRef23(null);
10627
- const startRef = useRef23(null);
10628
- const finishedRef = useRef23(false);
10629
- const directionRef = useRef23(new Vector39());
10771
+ const meshRef = useRef24(null);
10772
+ const startRef = useRef24(null);
10773
+ const finishedRef = useRef24(false);
10774
+ const directionRef = useRef24(new Vector39());
10630
10775
  const geometry = useMemo16(() => createParticleGeometry(), []);
10631
10776
  const material = useMemo16(
10632
10777
  () => new ShaderMaterial2({
@@ -10644,9 +10789,9 @@ function ParticleOverlay({
10644
10789
  }),
10645
10790
  [snapshot.texture]
10646
10791
  );
10647
- useEffect22(() => () => geometry.dispose(), [geometry]);
10648
- useEffect22(() => () => material.dispose(), [material]);
10649
- useEffect22(() => {
10792
+ useEffect23(() => () => geometry.dispose(), [geometry]);
10793
+ useEffect23(() => () => material.dispose(), [material]);
10794
+ useEffect23(() => {
10650
10795
  startRef.current = null;
10651
10796
  finishedRef.current = false;
10652
10797
  material.uniforms.progress.value = 0;
@@ -10668,7 +10813,7 @@ function ParticleOverlay({
10668
10813
  onFinish();
10669
10814
  }
10670
10815
  });
10671
- return /* @__PURE__ */ jsx17(
10816
+ return /* @__PURE__ */ jsx18(
10672
10817
  "mesh",
10673
10818
  {
10674
10819
  ref: meshRef,
@@ -10682,7 +10827,7 @@ function ParticleOverlay({
10682
10827
 
10683
10828
  // src/scene-transitions/snapshot-overlay.tsx
10684
10829
  import { useFrame as useFrame10, useThree as useThree16 } from "@react-three/fiber";
10685
- import { useEffect as useEffect23, useMemo as useMemo17, useRef as useRef24 } from "react";
10830
+ import { useEffect as useEffect24, useMemo as useMemo17, useRef as useRef25 } from "react";
10686
10831
  import { Vector3 as Vector310 } from "three";
10687
10832
 
10688
10833
  // src/scene-transitions/snapshot-shaders.ts
@@ -10962,7 +11107,7 @@ function createSnapshotMaterial(preset, texture) {
10962
11107
  }
10963
11108
 
10964
11109
  // src/scene-transitions/snapshot-overlay.tsx
10965
- import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
11110
+ import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
10966
11111
  function SnapshotOverlay({
10967
11112
  snapshot,
10968
11113
  transition,
@@ -10971,18 +11116,18 @@ function SnapshotOverlay({
10971
11116
  onFinish
10972
11117
  }) {
10973
11118
  const { camera, gl } = useThree16();
10974
- const meshRef = useRef24(null);
10975
- const startRef = useRef24(null);
10976
- const finishedRef = useRef24(false);
10977
- const directionRef = useRef24(new Vector310());
11119
+ const meshRef = useRef25(null);
11120
+ const startRef = useRef25(null);
11121
+ const finishedRef = useRef25(false);
11122
+ const directionRef = useRef25(new Vector310());
10978
11123
  const material = useMemo17(() => {
10979
11124
  if (!isSnapshotTransition(transition.preset)) {
10980
11125
  return null;
10981
11126
  }
10982
11127
  return createSnapshotMaterial(transition.preset, snapshot.texture);
10983
11128
  }, [snapshot.texture, transition.preset]);
10984
- useEffect23(() => () => material?.dispose(), [material]);
10985
- useEffect23(() => {
11129
+ useEffect24(() => () => material?.dispose(), [material]);
11130
+ useEffect24(() => {
10986
11131
  startRef.current = null;
10987
11132
  finishedRef.current = false;
10988
11133
  if (material) {
@@ -11012,20 +11157,20 @@ function SnapshotOverlay({
11012
11157
  return null;
11013
11158
  }
11014
11159
  return /* @__PURE__ */ jsxs11("mesh", { ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, frustumCulled: false, children: [
11015
- /* @__PURE__ */ jsx18("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
11016
- /* @__PURE__ */ jsx18("primitive", { attach: "material", object: material })
11160
+ /* @__PURE__ */ jsx19("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
11161
+ /* @__PURE__ */ jsx19("primitive", { attach: "material", object: material })
11017
11162
  ] });
11018
11163
  }
11019
11164
 
11020
11165
  // src/scene-transitions/transition-overlay.tsx
11021
- import { jsx as jsx19 } from "react/jsx-runtime";
11166
+ import { jsx as jsx20 } from "react/jsx-runtime";
11022
11167
  function TransitionOverlay(props) {
11023
11168
  const { preset } = props.transition;
11024
11169
  switch (preset) {
11025
11170
  case "none":
11026
11171
  return null;
11027
11172
  case "particles":
11028
- return /* @__PURE__ */ jsx19(ParticleOverlay, { ...props });
11173
+ return /* @__PURE__ */ jsx20(ParticleOverlay, { ...props });
11029
11174
  case "crossfade":
11030
11175
  case "zoom":
11031
11176
  case "blackout":
@@ -11053,7 +11198,7 @@ function TransitionOverlay(props) {
11053
11198
  case "zoomBlur":
11054
11199
  case "hexDissolve":
11055
11200
  case "filmBurn":
11056
- return /* @__PURE__ */ jsx19(SnapshotOverlay, { ...props });
11201
+ return /* @__PURE__ */ jsx20(SnapshotOverlay, { ...props });
11057
11202
  default: {
11058
11203
  const exhaustive = preset;
11059
11204
  void exhaustive;
@@ -11065,9 +11210,9 @@ function TransitionOverlay(props) {
11065
11210
  // src/tile/texture-manager-context.tsx
11066
11211
  import { useThree as useThree17 } from "@react-three/fiber";
11067
11212
  import {
11068
- createContext as createContext13,
11069
- useContext as useContext21,
11070
- useEffect as useEffect24,
11213
+ createContext as createContext14,
11214
+ useContext as useContext22,
11215
+ useEffect as useEffect25,
11071
11216
  useMemo as useMemo18
11072
11217
  } from "react";
11073
11218
 
@@ -11298,8 +11443,8 @@ var TileTextureManager = class {
11298
11443
  };
11299
11444
 
11300
11445
  // src/tile/texture-manager-context.tsx
11301
- import { jsx as jsx20 } from "react/jsx-runtime";
11302
- var TileTextureManagerContext = createContext13(
11446
+ import { jsx as jsx21 } from "react/jsx-runtime";
11447
+ var TileTextureManagerContext = createContext14(
11303
11448
  null
11304
11449
  );
11305
11450
  function TileTextureManagerProvider({
@@ -11318,23 +11463,23 @@ function TileTextureManagerProvider({
11318
11463
  }),
11319
11464
  [anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
11320
11465
  );
11321
- useEffect24(() => {
11466
+ useEffect25(() => {
11322
11467
  manager.resume();
11323
11468
  return () => manager.dispose();
11324
11469
  }, [manager]);
11325
- return /* @__PURE__ */ jsx20(TileTextureManagerContext.Provider, { value: manager, children });
11470
+ return /* @__PURE__ */ jsx21(TileTextureManagerContext.Provider, { value: manager, children });
11326
11471
  }
11327
11472
  function useSharedTileTextureManager() {
11328
- return useContext21(TileTextureManagerContext);
11473
+ return useContext22(TileTextureManagerContext);
11329
11474
  }
11330
11475
 
11331
11476
  // src/tile/tile.tsx
11332
11477
  import { useFrame as useFrame11, useThree as useThree18 } from "@react-three/fiber";
11333
11478
  import {
11334
11479
  memo,
11335
- useEffect as useEffect25,
11480
+ useEffect as useEffect26,
11336
11481
  useMemo as useMemo19,
11337
- useRef as useRef25,
11482
+ useRef as useRef26,
11338
11483
  useState as useState11
11339
11484
  } from "react";
11340
11485
  import {
@@ -11531,7 +11676,7 @@ function resolveTemplateUrl(template, address) {
11531
11676
  }
11532
11677
 
11533
11678
  // src/tile/tile.tsx
11534
- import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
11679
+ import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
11535
11680
  var MAX_LOD_UPDATE_INTERVAL_MS = 100;
11536
11681
  var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
11537
11682
  var FAST_FOV_THRESHOLD_DEGREES = 0.5;
@@ -11541,9 +11686,9 @@ var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
11541
11686
  var SHARED_TILE_GEOMETRY = new PlaneGeometry4(1, 1);
11542
11687
  function usePreviewTexture(url, anisotropy, onError) {
11543
11688
  const [texture, setTexture] = useState11(null);
11544
- const onErrorRef = useRef25(onError);
11689
+ const onErrorRef = useRef26(onError);
11545
11690
  onErrorRef.current = onError;
11546
- useEffect25(() => {
11691
+ useEffect26(() => {
11547
11692
  if (!url) {
11548
11693
  setTexture(null);
11549
11694
  return;
@@ -11580,7 +11725,7 @@ function usePreviewTexture(url, anisotropy, onError) {
11580
11725
  active = false;
11581
11726
  };
11582
11727
  }, [anisotropy, url]);
11583
- useEffect25(
11728
+ useEffect26(
11584
11729
  () => () => {
11585
11730
  texture?.dispose();
11586
11731
  },
@@ -11611,21 +11756,21 @@ function PreviewFace({
11611
11756
  uv.needsUpdate = true;
11612
11757
  return nextGeometry;
11613
11758
  }, [face, faceOrder]);
11614
- useEffect25(
11759
+ useEffect26(
11615
11760
  () => () => {
11616
11761
  geometry.dispose();
11617
11762
  },
11618
11763
  [geometry]
11619
11764
  );
11620
11765
  const transform = getFaceTransform(face, PREVIEW_RADIUS);
11621
- return /* @__PURE__ */ jsx21(
11766
+ return /* @__PURE__ */ jsx22(
11622
11767
  "mesh",
11623
11768
  {
11624
11769
  geometry,
11625
11770
  position: transform.position,
11626
11771
  renderOrder: -100,
11627
11772
  rotation: transform.rotation,
11628
- children: /* @__PURE__ */ jsx21(
11773
+ children: /* @__PURE__ */ jsx22(
11629
11774
  PanoBasicMaterial,
11630
11775
  {
11631
11776
  depthTest: false,
@@ -11641,7 +11786,7 @@ function PreviewCube({
11641
11786
  texture,
11642
11787
  faceOrder
11643
11788
  }) {
11644
- return CUBE_FACES.map((face) => /* @__PURE__ */ jsx21(
11789
+ return CUBE_FACES.map((face) => /* @__PURE__ */ jsx22(
11645
11790
  PreviewFace,
11646
11791
  {
11647
11792
  face,
@@ -11659,7 +11804,7 @@ function useManagedTexture(manager, key, url, address) {
11659
11804
  snapshot: manager.getSnapshot(key)
11660
11805
  }));
11661
11806
  const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
11662
- useEffect25(
11807
+ useEffect26(
11663
11808
  () => manager.acquire(key, url, address, (nextSnapshot) => {
11664
11809
  setManagedState({
11665
11810
  manager,
@@ -11686,14 +11831,14 @@ var TileMesh = memo(function TileMesh2({
11686
11831
  if (!snapshot.texture) {
11687
11832
  return null;
11688
11833
  }
11689
- return /* @__PURE__ */ jsx21("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ jsx21(
11834
+ return /* @__PURE__ */ jsx22("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ jsx22(
11690
11835
  "mesh",
11691
11836
  {
11692
11837
  geometry: SHARED_TILE_GEOMETRY,
11693
11838
  position: [layout.x, layout.y, 0],
11694
11839
  renderOrder,
11695
11840
  scale: [layout.width, layout.height, 1],
11696
- children: /* @__PURE__ */ jsx21(
11841
+ children: /* @__PURE__ */ jsx22(
11697
11842
  PanoBasicMaterial,
11698
11843
  {
11699
11844
  depthTest: false,
@@ -11710,7 +11855,7 @@ var TileLayerMeshes = memo(function TileLayerMeshes2({
11710
11855
  manager,
11711
11856
  resolveUrl
11712
11857
  }) {
11713
- return layer.addresses.map((address) => /* @__PURE__ */ jsx21(
11858
+ return layer.addresses.map((address) => /* @__PURE__ */ jsx22(
11714
11859
  TileMesh,
11715
11860
  {
11716
11861
  address,
@@ -11894,9 +12039,9 @@ function Tile({
11894
12039
  onPreviewError
11895
12040
  );
11896
12041
  const sharedManager = useSharedTileTextureManager();
11897
- const progressRef = useRef25(onLoadProgress);
11898
- const errorRef = useRef25(onTileError);
11899
- const levelChangeRef = useRef25(onLevelChange);
12042
+ const progressRef = useRef26(onLoadProgress);
12043
+ const errorRef = useRef26(onTileError);
12044
+ const levelChangeRef = useRef26(onLevelChange);
11900
12045
  progressRef.current = onLoadProgress;
11901
12046
  errorRef.current = onTileError;
11902
12047
  levelChangeRef.current = onLevelChange;
@@ -11921,7 +12066,7 @@ function Tile({
11921
12066
  ]
11922
12067
  );
11923
12068
  const manager = sharedManager ?? ownedManager;
11924
- useEffect25(() => {
12069
+ useEffect26(() => {
11925
12070
  manager.resume();
11926
12071
  return () => {
11927
12072
  if (manager === ownedManager) {
@@ -11931,11 +12076,11 @@ function Tile({
11931
12076
  queueMicrotask(() => manager.releaseUnused());
11932
12077
  };
11933
12078
  }, [manager, ownedManager]);
11934
- const readyRef = useRef25(false);
11935
- useEffect25(() => {
12079
+ const readyRef = useRef26(false);
12080
+ useEffect26(() => {
11936
12081
  readyRef.current = false;
11937
12082
  }, [effectivePreviewUrl]);
11938
- useEffect25(() => {
12083
+ useEffect26(() => {
11939
12084
  if (!previewTexture || readyRef.current) {
11940
12085
  return;
11941
12086
  }
@@ -11951,23 +12096,23 @@ function Tile({
11951
12096
  [baseUrl, resolveTileUrl, template]
11952
12097
  );
11953
12098
  const [layers, setLayers] = useState11([]);
11954
- const layerTokenRef = useRef25("");
11955
- const currentLevelRef = useRef25(1);
11956
- const lastUpdateAtRef = useRef25(-Infinity);
11957
- const visibilityDirtyRef = useRef25(true);
11958
- const lastVisibilityQuaternionRef = useRef25(camera.quaternion.clone());
11959
- const lastVisibilityFovRef = useRef25(Number.NaN);
11960
- const lastViewportRef = useRef25({ width: 0, height: 0, dpr: 0 });
11961
- const frustumRef = useRef25(new Frustum());
11962
- const projectionMatrixRef = useRef25(new Matrix4());
11963
- const visibilityCameraRef = useRef25(new PerspectiveCamera4());
11964
- useEffect25(() => {
12099
+ const layerTokenRef = useRef26("");
12100
+ const currentLevelRef = useRef26(1);
12101
+ const lastUpdateAtRef = useRef26(-Infinity);
12102
+ const visibilityDirtyRef = useRef26(true);
12103
+ const lastVisibilityQuaternionRef = useRef26(camera.quaternion.clone());
12104
+ const lastVisibilityFovRef = useRef26(Number.NaN);
12105
+ const lastViewportRef = useRef26({ width: 0, height: 0, dpr: 0 });
12106
+ const frustumRef = useRef26(new Frustum());
12107
+ const projectionMatrixRef = useRef26(new Matrix4());
12108
+ const visibilityCameraRef = useRef26(new PerspectiveCamera4());
12109
+ useEffect26(() => {
11965
12110
  currentLevelRef.current = 1;
11966
12111
  layerTokenRef.current = "";
11967
12112
  visibilityDirtyRef.current = true;
11968
12113
  setLayers([]);
11969
12114
  }, [manager, multiresToken]);
11970
- useEffect25(() => {
12115
+ useEffect26(() => {
11971
12116
  if (loadMode !== "preview") {
11972
12117
  return;
11973
12118
  }
@@ -12048,14 +12193,14 @@ function Tile({
12048
12193
  commitLayers(nextLayers);
12049
12194
  });
12050
12195
  return /* @__PURE__ */ jsxs12("group", { visible, children: [
12051
- previewTexture ? /* @__PURE__ */ jsx21(
12196
+ previewTexture ? /* @__PURE__ */ jsx22(
12052
12197
  PreviewCube,
12053
12198
  {
12054
12199
  texture: previewTexture,
12055
12200
  faceOrder: previewFaceOrder
12056
12201
  }
12057
12202
  ) : null,
12058
- layers.map((layer) => /* @__PURE__ */ jsx21(
12203
+ layers.map((layer) => /* @__PURE__ */ jsx22(
12059
12204
  TileLayerMeshes,
12060
12205
  {
12061
12206
  layer,
@@ -12068,7 +12213,7 @@ function Tile({
12068
12213
  }
12069
12214
 
12070
12215
  // src/scenes.tsx
12071
- import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
12216
+ import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
12072
12217
  function SceneSource({
12073
12218
  scene,
12074
12219
  visible,
@@ -12081,7 +12226,7 @@ function SceneSource({
12081
12226
  }
12082
12227
  switch (scene.type) {
12083
12228
  case "sphere":
12084
- return /* @__PURE__ */ jsx22(
12229
+ return /* @__PURE__ */ jsx23(
12085
12230
  Sphere,
12086
12231
  {
12087
12232
  src: scene.src,
@@ -12094,7 +12239,7 @@ function SceneSource({
12094
12239
  );
12095
12240
  case "tile": {
12096
12241
  const { id: _id, type: _type, ...tileProps } = scene;
12097
- return /* @__PURE__ */ jsx22(
12242
+ return /* @__PURE__ */ jsx23(
12098
12243
  Tile,
12099
12244
  {
12100
12245
  ...tileProps,
@@ -12118,9 +12263,9 @@ function SnapshotCapture({
12118
12263
  onCaptured
12119
12264
  }) {
12120
12265
  const { camera, gl, scene, size } = useThree19();
12121
- const capturedRequestRef = useRef26(0);
12122
- const renderTargetRef = useRef26(null);
12123
- useEffect26(
12266
+ const capturedRequestRef = useRef27(0);
12267
+ const renderTargetRef = useRef27(null);
12268
+ useEffect27(
12124
12269
  () => () => {
12125
12270
  renderTargetRef.current?.dispose();
12126
12271
  renderTargetRef.current = null;
@@ -12176,7 +12321,7 @@ function ScenesController({
12176
12321
  snapshotMaxPixels = 3686400,
12177
12322
  phaseRef: externalPhaseRef
12178
12323
  }) {
12179
- const controlsRef = useContext22(PanoramaViewContext);
12324
+ const controlsRef = useContext23(PanoramaViewContext);
12180
12325
  const manager = useSharedTileTextureManager();
12181
12326
  const transition = useMemo20(
12182
12327
  () => resolveTransition(transitionInput),
@@ -12199,13 +12344,13 @@ function ScenesController({
12199
12344
  const [transitionRunId, setTransitionRunId] = useState12(0);
12200
12345
  const [snapshot, setSnapshot] = useState12(null);
12201
12346
  const [recoveryKey, setRecoveryKey] = useState12(0);
12202
- const requestedSceneIdRef = useRef26(activeSceneId);
12203
- const captureReasonRef = useRef26("start");
12204
- const interactionReleaseRef = useRef26(null);
12205
- const slotsRef = useRef26(slots);
12206
- const phaseRef = useRef26(phase);
12207
- const liveSlotRef = useRef26(liveSlot);
12208
- const transitionFromRef = useRef26(initialScene);
12347
+ const requestedSceneIdRef = useRef27(activeSceneId);
12348
+ const captureReasonRef = useRef27("start");
12349
+ const interactionReleaseRef = useRef27(null);
12350
+ const slotsRef = useRef27(slots);
12351
+ const phaseRef = useRef27(phase);
12352
+ const liveSlotRef = useRef27(liveSlot);
12353
+ const transitionFromRef = useRef27(initialScene);
12209
12354
  slotsRef.current = slots;
12210
12355
  phaseRef.current = phase;
12211
12356
  if (externalPhaseRef) {
@@ -12230,7 +12375,7 @@ function ScenesController({
12230
12375
  setPendingSlot(nextSlot);
12231
12376
  setPhase("preloading");
12232
12377
  }, []);
12233
- useEffect26(() => {
12378
+ useEffect27(() => {
12234
12379
  const requested = sceneMap.get(activeSceneId);
12235
12380
  if (!requested) {
12236
12381
  reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
@@ -12332,12 +12477,12 @@ function ScenesController({
12332
12477
  });
12333
12478
  }
12334
12479
  }, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
12335
- useEffect26(() => () => {
12480
+ useEffect27(() => () => {
12336
12481
  releaseInteraction();
12337
12482
  snapshot?.dispose();
12338
12483
  }, [releaseInteraction, snapshot]);
12339
12484
  const { gl } = useThree19();
12340
- useEffect26(() => {
12485
+ useEffect27(() => {
12341
12486
  const canvas = gl.domElement;
12342
12487
  const onContextLost = (event) => {
12343
12488
  event.preventDefault();
@@ -12362,7 +12507,7 @@ function ScenesController({
12362
12507
  const renderedScene = slots[liveSlot];
12363
12508
  const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
12364
12509
  return /* @__PURE__ */ jsxs13(Fragment6, { children: [
12365
- /* @__PURE__ */ jsx22(
12510
+ /* @__PURE__ */ jsx23(
12366
12511
  SnapshotCapture,
12367
12512
  {
12368
12513
  requestId: captureRequestId,
@@ -12374,7 +12519,7 @@ function ScenesController({
12374
12519
  const source = slots[slot];
12375
12520
  const isLive = slot === liveSlot;
12376
12521
  const isPending = slot === pendingSlot;
12377
- return /* @__PURE__ */ jsx22(
12522
+ return /* @__PURE__ */ jsx23(
12378
12523
  SceneSource,
12379
12524
  {
12380
12525
  scene: source,
@@ -12390,7 +12535,7 @@ function ScenesController({
12390
12535
  `${slot}:${source?.id ?? "empty"}:${recoveryKey}`
12391
12536
  );
12392
12537
  }),
12393
- snapshotVisible ? /* @__PURE__ */ jsx22(
12538
+ snapshotVisible ? /* @__PURE__ */ jsx23(
12394
12539
  TransitionOverlay,
12395
12540
  {
12396
12541
  snapshot,
@@ -12427,13 +12572,13 @@ function Scenes({
12427
12572
  },
12428
12573
  [isControlled, onActiveSceneIdChange]
12429
12574
  );
12430
- const scenesRef = useRef26(scenes);
12575
+ const scenesRef = useRef27(scenes);
12431
12576
  scenesRef.current = scenes;
12432
- const resolvedIdRef = useRef26(resolvedId);
12577
+ const resolvedIdRef = useRef27(resolvedId);
12433
12578
  resolvedIdRef.current = resolvedId;
12434
- const host = useContext22(ScenesHostContext);
12435
- const phaseRef = useRef26("idle");
12436
- useEffect26(() => {
12579
+ const host = useContext23(ScenesHostContext);
12580
+ const phaseRef = useRef27("idle");
12581
+ useEffect27(() => {
12437
12582
  if (!host) {
12438
12583
  return;
12439
12584
  }
@@ -12483,12 +12628,12 @@ function Scenes({
12483
12628
  }
12484
12629
  };
12485
12630
  }, [host, requestSceneChange]);
12486
- return /* @__PURE__ */ jsx22(
12631
+ return /* @__PURE__ */ jsx23(
12487
12632
  TileTextureManagerProvider,
12488
12633
  {
12489
12634
  maxTextureMemoryMb,
12490
12635
  maxConcurrentLoads: maxConcurrentTileLoads,
12491
- children: /* @__PURE__ */ jsx22(
12636
+ children: /* @__PURE__ */ jsx23(
12492
12637
  ScenesController,
12493
12638
  {
12494
12639
  ...rest,
@@ -12503,7 +12648,7 @@ function Scenes({
12503
12648
 
12504
12649
  // src/hotspot/image-hotspot.tsx
12505
12650
  import { useThree as useThree21 } from "@react-three/fiber";
12506
- import { useEffect as useEffect29, useRef as useRef28, useState as useState15 } from "react";
12651
+ import { useEffect as useEffect30, useRef as useRef29, useState as useState15 } from "react";
12507
12652
  import {
12508
12653
  ClampToEdgeWrapping as ClampToEdgeWrapping3,
12509
12654
  LinearFilter as LinearFilter6,
@@ -12515,11 +12660,11 @@ import {
12515
12660
  // src/hotspot/hotspot-anchor.tsx
12516
12661
  import { useFrame as useFrame13, useThree as useThree20 } from "@react-three/fiber";
12517
12662
  import {
12518
- useContext as useContext24,
12519
- useEffect as useEffect28,
12663
+ useContext as useContext25,
12664
+ useEffect as useEffect29,
12520
12665
  useLayoutEffect as useLayoutEffect4,
12521
12666
  useMemo as useMemo22,
12522
- useRef as useRef27,
12667
+ useRef as useRef28,
12523
12668
  useState as useState14
12524
12669
  } from "react";
12525
12670
  import {
@@ -12536,16 +12681,16 @@ import {
12536
12681
  } from "three";
12537
12682
 
12538
12683
  // src/hotspot/hotspot-tooltip.tsx
12539
- import { useEffect as useEffect27, useMemo as useMemo21, useState as useState13 } from "react";
12684
+ import { useEffect as useEffect28, useMemo as useMemo21, useState as useState13 } from "react";
12540
12685
 
12541
12686
  // src/webvr/stereo-html.tsx
12542
12687
  import { Html } from "@react-three/drei";
12543
- import { useContext as useContext23, useSyncExternalStore as useSyncExternalStore6 } from "react";
12544
- import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
12688
+ import { useContext as useContext24, useSyncExternalStore as useSyncExternalStore7 } from "react";
12689
+ import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
12545
12690
  function useFallbackStereoView() {
12546
- const runtime = useContext23(WebVRRuntimeContext);
12691
+ const runtime = useContext24(WebVRRuntimeContext);
12547
12692
  const host = runtime?.host ?? null;
12548
- const fallback = useSyncExternalStore6(
12693
+ const fallback = useSyncExternalStore7(
12549
12694
  (onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
12550
12695
  () => isFallbackStereoMode(host?.snapshot.mode ?? null),
12551
12696
  () => false
@@ -12566,10 +12711,10 @@ function stereoCalculatePosition(eye, stereoView) {
12566
12711
  function PanoHtml({ children, ...htmlProps }) {
12567
12712
  const stereoView = useFallbackStereoView();
12568
12713
  if (!stereoView) {
12569
- return /* @__PURE__ */ jsx23(Html, { ...htmlProps, children });
12714
+ return /* @__PURE__ */ jsx24(Html, { ...htmlProps, children });
12570
12715
  }
12571
12716
  return /* @__PURE__ */ jsxs14(Fragment7, { children: [
12572
- /* @__PURE__ */ jsx23(
12717
+ /* @__PURE__ */ jsx24(
12573
12718
  Html,
12574
12719
  {
12575
12720
  ...htmlProps,
@@ -12577,7 +12722,7 @@ function PanoHtml({ children, ...htmlProps }) {
12577
12722
  children
12578
12723
  }
12579
12724
  ),
12580
- /* @__PURE__ */ jsx23(
12725
+ /* @__PURE__ */ jsx24(
12581
12726
  Html,
12582
12727
  {
12583
12728
  ...htmlProps,
@@ -12590,7 +12735,7 @@ function PanoHtml({ children, ...htmlProps }) {
12590
12735
  }
12591
12736
 
12592
12737
  // src/hotspot/hotspot-tooltip.tsx
12593
- import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
12738
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
12594
12739
  var DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
12595
12740
  var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
12596
12741
  background: "rgba(22, 22, 22, 0.72)",
@@ -12660,7 +12805,7 @@ function HotspotTooltip({
12660
12805
  appearance
12661
12806
  }) {
12662
12807
  const [imageFailed, setImageFailed] = useState13(false);
12663
- useEffect27(() => {
12808
+ useEffect28(() => {
12664
12809
  setImageFailed(false);
12665
12810
  }, [content.image]);
12666
12811
  const showImage = Boolean(content.image) && !imageFailed;
@@ -12687,14 +12832,14 @@ function HotspotTooltip({
12687
12832
  if (!showImage && !content.text) {
12688
12833
  return null;
12689
12834
  }
12690
- return /* @__PURE__ */ jsx24(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ jsxs15(
12835
+ return /* @__PURE__ */ jsx25(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ jsxs15(
12691
12836
  "div",
12692
12837
  {
12693
12838
  className: "pano-hotspot-tooltip",
12694
12839
  role: "tooltip",
12695
12840
  style: bubbleStyle,
12696
12841
  children: [
12697
- showImage ? /* @__PURE__ */ jsx24(
12842
+ showImage ? /* @__PURE__ */ jsx25(
12698
12843
  "img",
12699
12844
  {
12700
12845
  alt: content.imageAlt ?? content.text ?? "",
@@ -12703,14 +12848,14 @@ function HotspotTooltip({
12703
12848
  src: content.image
12704
12849
  }
12705
12850
  ) : null,
12706
- content.text ? /* @__PURE__ */ jsx24("p", { className: "pano-hotspot-tooltip-text", children: content.text }) : null
12851
+ content.text ? /* @__PURE__ */ jsx25("p", { className: "pano-hotspot-tooltip-text", children: content.text }) : null
12707
12852
  ]
12708
12853
  }
12709
12854
  ) });
12710
12855
  }
12711
12856
 
12712
12857
  // src/hotspot/hotspot-anchor.tsx
12713
- import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
12858
+ import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
12714
12859
  var DEFAULT_FLOATING_DISTANCE = 10;
12715
12860
  var PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;
12716
12861
  var PANORAMA_SURFACE_INSET = 4;
@@ -13047,14 +13192,14 @@ function HotspotAnchor({
13047
13192
  onPositionChange,
13048
13193
  onDragEnd
13049
13194
  }) {
13050
- const controlsRef = useContext24(PanoramaViewContext);
13051
- const eventBus = useContext24(PanoEventBusContext);
13195
+ const controlsRef = useContext25(PanoramaViewContext);
13196
+ const eventBus = useContext25(PanoEventBusContext);
13052
13197
  const cursorApi = usePanoCursor();
13053
13198
  const { camera, size } = useThree20();
13054
- const groupRef = useRef27(null);
13055
- const tooltipAnchorRef = useRef27(null);
13056
- const dragStateRef = useRef27(null);
13057
- const suppressNextClickRef = useRef27(false);
13199
+ const groupRef = useRef28(null);
13200
+ const tooltipAnchorRef = useRef28(null);
13201
+ const dragStateRef = useRef28(null);
13202
+ const suppressNextClickRef = useRef28(false);
13058
13203
  const [hovered, setHovered] = useState14(false);
13059
13204
  const [dragging, setDragging] = useState14(false);
13060
13205
  const [pinned, setPinned] = useState14(false);
@@ -13111,14 +13256,14 @@ function HotspotAnchor({
13111
13256
  });
13112
13257
  const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
13113
13258
  const cursorClaimId = hotspotCursorClaimId(id);
13114
- useEffect28(
13259
+ useEffect29(
13115
13260
  () => () => {
13116
13261
  dragStateRef.current?.releaseInteractionLock();
13117
13262
  dragStateRef.current = null;
13118
13263
  },
13119
13264
  []
13120
13265
  );
13121
- useEffect28(() => {
13266
+ useEffect29(() => {
13122
13267
  if (!cursorApi) {
13123
13268
  return;
13124
13269
  }
@@ -13140,14 +13285,14 @@ function HotspotAnchor({
13140
13285
  hovered,
13141
13286
  visible
13142
13287
  ]);
13143
- useEffect28(
13288
+ useEffect29(
13144
13289
  () => () => {
13145
13290
  cursorApi?.release(cursorClaimId);
13146
13291
  },
13147
13292
  [cursorApi, cursorClaimId]
13148
13293
  );
13149
- useEffect28(() => () => focusGeometry.dispose(), [focusGeometry]);
13150
- useEffect28(() => {
13294
+ useEffect29(() => () => focusGeometry.dispose(), [focusGeometry]);
13295
+ useEffect29(() => {
13151
13296
  if (tooltipTrigger !== "click") {
13152
13297
  setPinned(false);
13153
13298
  return;
@@ -13156,12 +13301,12 @@ function HotspotAnchor({
13156
13301
  setPinned(false);
13157
13302
  });
13158
13303
  }, [eventBus, tooltipTrigger]);
13159
- useEffect28(() => {
13304
+ useEffect29(() => {
13160
13305
  if (tooltipTrigger !== "hover") {
13161
13306
  setHovered(false);
13162
13307
  }
13163
13308
  }, [tooltipTrigger]);
13164
- useEffect28(() => {
13309
+ useEffect29(() => {
13165
13310
  if (acceptsPointer) {
13166
13311
  return;
13167
13312
  }
@@ -13350,18 +13495,18 @@ function HotspotAnchor({
13350
13495
  } : void 0,
13351
13496
  onPointerUp: acceptsPointer ? (event) => releasePointer(event, true) : void 0,
13352
13497
  children: [
13353
- focused ? focusContent ?? /* @__PURE__ */ jsx25(
13498
+ focused ? focusContent ?? /* @__PURE__ */ jsx26(
13354
13499
  "lineSegments",
13355
13500
  {
13356
13501
  geometry: focusGeometry,
13357
13502
  position: [0, 0, 0.01],
13358
13503
  renderOrder: renderOrder + 1,
13359
13504
  scale: [1.12, 1.12, 1],
13360
- children: /* @__PURE__ */ jsx25("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
13505
+ children: /* @__PURE__ */ jsx26("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
13361
13506
  }
13362
13507
  ) : null,
13363
13508
  children,
13364
- tooltipOpen && tooltipContent ? /* @__PURE__ */ jsx25("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ jsx25(
13509
+ tooltipOpen && tooltipContent ? /* @__PURE__ */ jsx26("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ jsx26(
13365
13510
  HotspotTooltip,
13366
13511
  {
13367
13512
  appearance: tooltipAppearance,
@@ -13382,7 +13527,7 @@ import {
13382
13527
  MeshBasicMaterial,
13383
13528
  Vector2 as Vector26
13384
13529
  } from "three";
13385
- import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
13530
+ import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
13386
13531
  var HOTSPOT_ALPHA_CUTOFF = 0.05;
13387
13532
  var SAMPLE_UV = new Vector26();
13388
13533
  var RAYCAST_HITS = [];
@@ -13485,8 +13630,8 @@ function HotspotPlane({
13485
13630
  opacity
13486
13631
  }) {
13487
13632
  return /* @__PURE__ */ jsxs17("mesh", { raycast: hotspotPlaneRaycast, children: [
13488
- /* @__PURE__ */ jsx26("planeGeometry", { args: [1, 1] }),
13489
- /* @__PURE__ */ jsx26(
13633
+ /* @__PURE__ */ jsx27("planeGeometry", { args: [1, 1] }),
13634
+ /* @__PURE__ */ jsx27(
13490
13635
  "meshBasicMaterial",
13491
13636
  {
13492
13637
  alphaTest: HOTSPOT_ALPHA_CUTOFF,
@@ -13502,15 +13647,15 @@ function HotspotPlane({
13502
13647
  }
13503
13648
 
13504
13649
  // src/hotspot/image-hotspot.tsx
13505
- import { jsx as jsx27 } from "react/jsx-runtime";
13650
+ import { jsx as jsx28 } from "react/jsx-runtime";
13506
13651
  function useHotspotImageTexture(src, onLoad, onError) {
13507
13652
  const gl = useThree21((state) => state.gl);
13508
13653
  const [texture, setTexture] = useState15(null);
13509
- const onLoadRef = useRef28(onLoad);
13510
- const onErrorRef = useRef28(onError);
13654
+ const onLoadRef = useRef29(onLoad);
13655
+ const onErrorRef = useRef29(onError);
13511
13656
  onLoadRef.current = onLoad;
13512
13657
  onErrorRef.current = onError;
13513
- useEffect29(() => {
13658
+ useEffect30(() => {
13514
13659
  let active = true;
13515
13660
  setTexture(null);
13516
13661
  if (!src) {
@@ -13548,7 +13693,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
13548
13693
  active = false;
13549
13694
  };
13550
13695
  }, [gl, src]);
13551
- useEffect29(
13696
+ useEffect30(
13552
13697
  () => () => {
13553
13698
  texture?.dispose();
13554
13699
  },
@@ -13566,11 +13711,11 @@ function ImageHotspot({
13566
13711
  ...anchorProps
13567
13712
  }) {
13568
13713
  const texture = useHotspotImageTexture(src, onLoad, onError);
13569
- return /* @__PURE__ */ jsx27(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx27(HotspotPlane, { map: texture, opacity }) });
13714
+ return /* @__PURE__ */ jsx28(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx28(HotspotPlane, { map: texture, opacity }) });
13570
13715
  }
13571
13716
 
13572
13717
  // src/hotspot/polygon-hotspot.tsx
13573
- import { useEffect as useEffect30, useMemo as useMemo23, useRef as useRef30 } from "react";
13718
+ import { useEffect as useEffect31, useMemo as useMemo23, useRef as useRef31 } from "react";
13574
13719
  import {
13575
13720
  BufferGeometry,
13576
13721
  DoubleSide as DoubleSide5,
@@ -13585,13 +13730,13 @@ import {
13585
13730
  // src/hotspot/hotspot-stroke-line.tsx
13586
13731
  import { Line } from "@react-three/drei";
13587
13732
  import { useFrame as useFrame14, useThree as useThree22 } from "@react-three/fiber";
13588
- import { useLayoutEffect as useLayoutEffect5, useRef as useRef29 } from "react";
13733
+ import { useLayoutEffect as useLayoutEffect5, useRef as useRef30 } from "react";
13589
13734
  import {
13590
13735
  MathUtils as MathUtils8,
13591
13736
  PerspectiveCamera as PerspectiveCamera6,
13592
13737
  Vector3 as Vector314
13593
13738
  } from "three";
13594
- import { jsx as jsx28 } from "react/jsx-runtime";
13739
+ import { jsx as jsx29 } from "react/jsx-runtime";
13595
13740
  var LINE_WORLD_POSITION = new Vector314();
13596
13741
  function applyScreenSpaceDashScale(object, camera, viewportHeight) {
13597
13742
  const material = object?.material;
@@ -13622,7 +13767,7 @@ function HotspotStrokeLine({
13622
13767
  dashSize,
13623
13768
  gapSize
13624
13769
  }) {
13625
- const lineRef = useRef29(null);
13770
+ const lineRef = useRef30(null);
13626
13771
  const { camera, size } = useThree22();
13627
13772
  const dash = resolveDash(dashSize, gapSize);
13628
13773
  useLayoutEffect5(() => {
@@ -13637,7 +13782,7 @@ function HotspotStrokeLine({
13637
13782
  }
13638
13783
  applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
13639
13784
  });
13640
- return /* @__PURE__ */ jsx28(
13785
+ return /* @__PURE__ */ jsx29(
13641
13786
  Line,
13642
13787
  {
13643
13788
  ref: lineRef,
@@ -13659,7 +13804,7 @@ function HotspotStrokeLine({
13659
13804
  }
13660
13805
 
13661
13806
  // src/hotspot/polygon-hotspot.tsx
13662
- import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
13807
+ import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
13663
13808
  var POLYGON_RADIUS = 990;
13664
13809
  var MAX_FILL_SEGMENT_DEGREES = 7;
13665
13810
  function cloneVertices(vertices) {
@@ -13927,12 +14072,12 @@ function PolygonHotspot({
13927
14072
  [center, valid, vertices]
13928
14073
  );
13929
14074
  const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
13930
- const startVerticesRef = useRef30(null);
14075
+ const startVerticesRef = useRef31(null);
13931
14076
  const issuesKey = issues.map((issue) => issue.code).join(",");
13932
- useEffect30(() => {
14077
+ useEffect31(() => {
13933
14078
  if (!valid) onInvalid?.(issues);
13934
14079
  }, [issues, issuesKey, onInvalid, valid]);
13935
- useEffect30(() => () => fillGeometry?.dispose(), [fillGeometry]);
14080
+ useEffect31(() => () => fillGeometry?.dispose(), [fillGeometry]);
13936
14081
  if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
13937
14082
  return null;
13938
14083
  }
@@ -13962,7 +14107,7 @@ function PolygonHotspot({
13962
14107
  draggable,
13963
14108
  interactive,
13964
14109
  useAngularScale: false,
13965
- focusContent: /* @__PURE__ */ jsx29(
14110
+ focusContent: /* @__PURE__ */ jsx30(
13966
14111
  HotspotStrokeLine,
13967
14112
  {
13968
14113
  color: "#75cbd3",
@@ -13984,7 +14129,7 @@ function PolygonHotspot({
13984
14129
  startVerticesRef.current = null;
13985
14130
  },
13986
14131
  children: [
13987
- /* @__PURE__ */ jsx29("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ jsx29(
14132
+ /* @__PURE__ */ jsx30("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ jsx30(
13988
14133
  "meshBasicMaterial",
13989
14134
  {
13990
14135
  color: fill,
@@ -13994,7 +14139,7 @@ function PolygonHotspot({
13994
14139
  transparent: true
13995
14140
  }
13996
14141
  ) }),
13997
- /* @__PURE__ */ jsx29(
14142
+ /* @__PURE__ */ jsx30(
13998
14143
  HotspotStrokeLine,
13999
14144
  {
14000
14145
  color: stroke,
@@ -14012,14 +14157,14 @@ function PolygonHotspot({
14012
14157
  }
14013
14158
 
14014
14159
  // src/hotspot/polyline-hotspot.tsx
14015
- import { useEffect as useEffect31, useMemo as useMemo24, useRef as useRef31 } from "react";
14160
+ import { useEffect as useEffect32, useMemo as useMemo24, useRef as useRef32 } from "react";
14016
14161
  import {
14017
14162
  MathUtils as MathUtils9,
14018
14163
  Matrix4 as Matrix44,
14019
14164
  Quaternion as Quaternion5,
14020
14165
  Vector3 as Vector316
14021
14166
  } from "three";
14022
- import { jsx as jsx30 } from "react/jsx-runtime";
14167
+ import { jsx as jsx31 } from "react/jsx-runtime";
14023
14168
  var POLYLINE_RADIUS = 990;
14024
14169
  var MAX_SEGMENT_DEGREES = 7;
14025
14170
  function cloneVertices2(vertices) {
@@ -14144,8 +14289,8 @@ function PolylineHotspot({
14144
14289
  [center, valid, vertices]
14145
14290
  );
14146
14291
  const opacity = Math.max(0, Math.min(strokeOpacity, 1));
14147
- const startVerticesRef = useRef31(null);
14148
- useEffect31(() => {
14292
+ const startVerticesRef = useRef32(null);
14293
+ useEffect32(() => {
14149
14294
  if (!valid) onInvalid?.(issues);
14150
14295
  }, [issues, onInvalid, valid]);
14151
14296
  if (!valid || !center || !linePoints || linePoints.length < 2) return null;
@@ -14159,7 +14304,7 @@ function PolylineHotspot({
14159
14304
  startPosition: event.startPosition
14160
14305
  });
14161
14306
  };
14162
- return /* @__PURE__ */ jsx30(
14307
+ return /* @__PURE__ */ jsx31(
14163
14308
  HotspotAnchor,
14164
14309
  {
14165
14310
  ...anchorProps,
@@ -14173,7 +14318,7 @@ function PolylineHotspot({
14173
14318
  renderOrder,
14174
14319
  draggable,
14175
14320
  useAngularScale: false,
14176
- focusContent: /* @__PURE__ */ jsx30(
14321
+ focusContent: /* @__PURE__ */ jsx31(
14177
14322
  HotspotStrokeLine,
14178
14323
  {
14179
14324
  color: "#75cbd3",
@@ -14194,7 +14339,7 @@ function PolylineHotspot({
14194
14339
  emitVerticesChange(event, onDragEnd);
14195
14340
  startVerticesRef.current = null;
14196
14341
  },
14197
- children: /* @__PURE__ */ jsx30(
14342
+ children: /* @__PURE__ */ jsx31(
14198
14343
  HotspotStrokeLine,
14199
14344
  {
14200
14345
  color: stroke,
@@ -14211,7 +14356,7 @@ function PolylineHotspot({
14211
14356
  }
14212
14357
 
14213
14358
  // src/hotspot/graphic-hotspot.tsx
14214
- import { useEffect as useEffect32, useRef as useRef32, useState as useState16 } from "react";
14359
+ import { useEffect as useEffect33, useRef as useRef33, useState as useState16 } from "react";
14215
14360
  import {
14216
14361
  CanvasTexture,
14217
14362
  ClampToEdgeWrapping as ClampToEdgeWrapping4,
@@ -14219,7 +14364,7 @@ import {
14219
14364
  LinearMipmapLinearFilter as LinearMipmapLinearFilter4,
14220
14365
  SRGBColorSpace as SRGBColorSpace6
14221
14366
  } from "three";
14222
- import { jsx as jsx31 } from "react/jsx-runtime";
14367
+ import { jsx as jsx32 } from "react/jsx-runtime";
14223
14368
  var GRAPHIC_TEXTURE_SIZE = 512;
14224
14369
  function resolveStrokeWidth(value) {
14225
14370
  return Number.isFinite(value) ? Math.max(value, 0) : 8;
@@ -14409,11 +14554,11 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
14409
14554
  }
14410
14555
  function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
14411
14556
  const [texture, setTexture] = useState16(null);
14412
- const onLoadRef = useRef32(onLoad);
14413
- const onErrorRef = useRef32(onError);
14557
+ const onLoadRef = useRef33(onLoad);
14558
+ const onErrorRef = useRef33(onError);
14414
14559
  onLoadRef.current = onLoad;
14415
14560
  onErrorRef.current = onError;
14416
- useEffect32(() => {
14561
+ useEffect33(() => {
14417
14562
  let nextTexture = null;
14418
14563
  try {
14419
14564
  nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
@@ -14439,20 +14584,20 @@ function CanvasGraphicHotspot({
14439
14584
  ...anchorProps
14440
14585
  }) {
14441
14586
  const texture = useGraphicTexture(graphic, width, height, onLoad, onError);
14442
- return /* @__PURE__ */ jsx31(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx31(HotspotPlane, { map: texture, opacity }) });
14587
+ return /* @__PURE__ */ jsx32(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx32(HotspotPlane, { map: texture, opacity }) });
14443
14588
  }
14444
14589
  function GraphicHotspot(props) {
14445
14590
  const { graphic, ...restProps } = props;
14446
14591
  if (graphic.kind === "svg") {
14447
14592
  const imageProps = restProps;
14448
- return /* @__PURE__ */ jsx31(ImageHotspot, { ...imageProps, src: graphic.src });
14593
+ return /* @__PURE__ */ jsx32(ImageHotspot, { ...imageProps, src: graphic.src });
14449
14594
  }
14450
- return /* @__PURE__ */ jsx31(CanvasGraphicHotspot, { ...restProps, graphic });
14595
+ return /* @__PURE__ */ jsx32(CanvasGraphicHotspot, { ...restProps, graphic });
14451
14596
  }
14452
14597
 
14453
14598
  // src/hotspot/sequence-hotspot.tsx
14454
14599
  import { useFrame as useFrame15, useThree as useThree23 } from "@react-three/fiber";
14455
- import { useEffect as useEffect33, useRef as useRef33, useState as useState17 } from "react";
14600
+ import { useEffect as useEffect34, useRef as useRef34, useState as useState17 } from "react";
14456
14601
  import {
14457
14602
  ClampToEdgeWrapping as ClampToEdgeWrapping5,
14458
14603
  LinearFilter as LinearFilter8,
@@ -14460,7 +14605,7 @@ import {
14460
14605
  SRGBColorSpace as SRGBColorSpace7,
14461
14606
  TextureLoader as TextureLoader6
14462
14607
  } from "three";
14463
- import { jsx as jsx32 } from "react/jsx-runtime";
14608
+ import { jsx as jsx33 } from "react/jsx-runtime";
14464
14609
  var DEFAULT_SEQUENCE_FPS = 12;
14465
14610
  function resolveFps(value) {
14466
14611
  return Number.isFinite(value) && value > 0 ? value : DEFAULT_SEQUENCE_FPS;
@@ -14476,11 +14621,11 @@ function useSpriteTexture({
14476
14621
  }) {
14477
14622
  const gl = useThree23((state) => state.gl);
14478
14623
  const [texture, setTexture] = useState17(null);
14479
- const onErrorRef = useRef33(onError);
14480
- const onLoadProgressRef = useRef33(onLoadProgress);
14624
+ const onErrorRef = useRef34(onError);
14625
+ const onLoadProgressRef = useRef34(onLoadProgress);
14481
14626
  onErrorRef.current = onError;
14482
14627
  onLoadProgressRef.current = onLoadProgress;
14483
- useEffect33(() => {
14628
+ useEffect34(() => {
14484
14629
  let active = true;
14485
14630
  setTexture(null);
14486
14631
  if (!src) {
@@ -14521,7 +14666,7 @@ function useSpriteTexture({
14521
14666
  active = false;
14522
14667
  };
14523
14668
  }, [gl, id, src]);
14524
- useEffect33(
14669
+ useEffect34(
14525
14670
  () => () => {
14526
14671
  texture?.dispose();
14527
14672
  },
@@ -14551,23 +14696,23 @@ function SequenceHotspot({
14551
14696
  const frameCount = resolveFrameCount(requestedFrameCount);
14552
14697
  const safeFps = resolveFps(fps);
14553
14698
  const [frameIndex, setFrameIndex] = useState17(0);
14554
- const elapsedRef = useRef33(0);
14555
- const frameIndexRef = useRef33(0);
14556
- const endedRef = useRef33(false);
14557
- const lastPlaybackStateRef = useRef33(null);
14558
- const onFrameChangeRef = useRef33(onFrameChange);
14559
- const onPlaybackStateChangeRef = useRef33(onPlaybackStateChange);
14560
- const onEndedRef = useRef33(onEnded);
14699
+ const elapsedRef = useRef34(0);
14700
+ const frameIndexRef = useRef34(0);
14701
+ const endedRef = useRef34(false);
14702
+ const lastPlaybackStateRef = useRef34(null);
14703
+ const onFrameChangeRef = useRef34(onFrameChange);
14704
+ const onPlaybackStateChangeRef = useRef34(onPlaybackStateChange);
14705
+ const onEndedRef = useRef34(onEnded);
14561
14706
  onFrameChangeRef.current = onFrameChange;
14562
14707
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14563
14708
  onEndedRef.current = onEnded;
14564
- useEffect33(() => {
14709
+ useEffect34(() => {
14565
14710
  elapsedRef.current = 0;
14566
14711
  frameIndexRef.current = 0;
14567
14712
  endedRef.current = false;
14568
14713
  setFrameIndex(0);
14569
14714
  }, [frameCount, frameDirection, src]);
14570
- useEffect33(() => {
14715
+ useEffect34(() => {
14571
14716
  if (!texture) {
14572
14717
  return;
14573
14718
  }
@@ -14581,13 +14726,13 @@ function SequenceHotspot({
14581
14726
  );
14582
14727
  texture.needsUpdate = true;
14583
14728
  }, [frameCount, frameDirection, frameIndex, texture]);
14584
- useEffect33(() => {
14729
+ useEffect34(() => {
14585
14730
  if (!texture) {
14586
14731
  return;
14587
14732
  }
14588
14733
  onFrameChangeRef.current?.({ id, index: 0, src });
14589
14734
  }, [id, src, texture]);
14590
- useEffect33(() => {
14735
+ useEffect34(() => {
14591
14736
  if (!texture) {
14592
14737
  return;
14593
14738
  }
@@ -14636,12 +14781,12 @@ function SequenceHotspot({
14636
14781
  onFrameChangeRef.current?.({ id, index: nextIndex, src });
14637
14782
  }
14638
14783
  });
14639
- return /* @__PURE__ */ jsx32(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx32(HotspotPlane, { map: texture, opacity }) });
14784
+ return /* @__PURE__ */ jsx33(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx33(HotspotPlane, { map: texture, opacity }) });
14640
14785
  }
14641
14786
 
14642
14787
  // src/hotspot/video-hotspot.tsx
14643
14788
  import { useThree as useThree24 } from "@react-three/fiber";
14644
- import { useEffect as useEffect34, useRef as useRef34, useState as useState18 } from "react";
14789
+ import { useEffect as useEffect35, useRef as useRef35, useState as useState18 } from "react";
14645
14790
  import {
14646
14791
  ClampToEdgeWrapping as ClampToEdgeWrapping6,
14647
14792
  LinearFilter as LinearFilter9,
@@ -14650,7 +14795,7 @@ import {
14650
14795
  TextureLoader as TextureLoader7,
14651
14796
  VideoTexture as VideoTexture2
14652
14797
  } from "three";
14653
- import { jsx as jsx33 } from "react/jsx-runtime";
14798
+ import { jsx as jsx34 } from "react/jsx-runtime";
14654
14799
  function clampVolume2(volume) {
14655
14800
  if (!Number.isFinite(volume)) {
14656
14801
  return 1;
@@ -14660,9 +14805,9 @@ function clampVolume2(volume) {
14660
14805
  function usePosterTexture2(id, poster, onError) {
14661
14806
  const gl = useThree24((state) => state.gl);
14662
14807
  const [texture, setTexture] = useState18(null);
14663
- const onErrorRef = useRef34(onError);
14808
+ const onErrorRef = useRef35(onError);
14664
14809
  onErrorRef.current = onError;
14665
- useEffect34(() => {
14810
+ useEffect35(() => {
14666
14811
  let active = true;
14667
14812
  setTexture(null);
14668
14813
  if (!poster) {
@@ -14699,7 +14844,7 @@ function usePosterTexture2(id, poster, onError) {
14699
14844
  active = false;
14700
14845
  };
14701
14846
  }, [gl, id, poster]);
14702
- useEffect34(
14847
+ useEffect35(
14703
14848
  () => () => {
14704
14849
  texture?.dispose();
14705
14850
  },
@@ -14718,13 +14863,13 @@ function useVideoResource({
14718
14863
  src
14719
14864
  }) {
14720
14865
  const [resource, setResource] = useState18(null);
14721
- const onEndedRef = useRef34(onEnded);
14722
- const onErrorRef = useRef34(onError);
14723
- const onPlaybackStateChangeRef = useRef34(onPlaybackStateChange);
14866
+ const onEndedRef = useRef35(onEnded);
14867
+ const onErrorRef = useRef35(onError);
14868
+ const onPlaybackStateChangeRef = useRef35(onPlaybackStateChange);
14724
14869
  onEndedRef.current = onEnded;
14725
14870
  onErrorRef.current = onError;
14726
14871
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14727
- useEffect34(() => {
14872
+ useEffect35(() => {
14728
14873
  if (!src) {
14729
14874
  setResource(null);
14730
14875
  return;
@@ -14734,7 +14879,12 @@ function useVideoResource({
14734
14879
  if (crossOrigin !== void 0) {
14735
14880
  video.crossOrigin = crossOrigin;
14736
14881
  }
14737
- video.playsInline = playsInline ?? true;
14882
+ const inline = playsInline ?? true;
14883
+ video.playsInline = inline;
14884
+ if (inline) {
14885
+ video.setAttribute("playsinline", "true");
14886
+ video.setAttribute("webkit-playsinline", "true");
14887
+ }
14738
14888
  video.poster = poster ?? "";
14739
14889
  const texture = new VideoTexture2(video);
14740
14890
  texture.colorSpace = SRGBColorSpace8;
@@ -14814,6 +14964,7 @@ function VideoHotspot({
14814
14964
  onError,
14815
14965
  ...anchorProps
14816
14966
  }) {
14967
+ usePanoMediaActivationIntent(playing);
14817
14968
  const resource = useVideoResource({
14818
14969
  crossOrigin,
14819
14970
  id,
@@ -14825,11 +14976,11 @@ function VideoHotspot({
14825
14976
  src
14826
14977
  });
14827
14978
  const posterTexture = usePosterTexture2(id, poster, onError);
14828
- const onPlaybackErrorRef = useRef34(onPlaybackError);
14829
- const onPlaybackStateChangeRef = useRef34(onPlaybackStateChange);
14979
+ const onPlaybackErrorRef = useRef35(onPlaybackError);
14980
+ const onPlaybackStateChangeRef = useRef35(onPlaybackStateChange);
14830
14981
  onPlaybackErrorRef.current = onPlaybackError;
14831
14982
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
14832
- useEffect34(() => {
14983
+ useEffect35(() => {
14833
14984
  if (!resource) {
14834
14985
  return;
14835
14986
  }
@@ -14837,9 +14988,16 @@ function VideoHotspot({
14837
14988
  resource.video.muted = muted;
14838
14989
  resource.video.volume = clampVolume2(volume);
14839
14990
  resource.video.playsInline = playsInline;
14991
+ if (playsInline) {
14992
+ resource.video.setAttribute("playsinline", "true");
14993
+ resource.video.setAttribute("webkit-playsinline", "true");
14994
+ } else {
14995
+ resource.video.removeAttribute("playsinline");
14996
+ resource.video.removeAttribute("webkit-playsinline");
14997
+ }
14840
14998
  resource.video.preload = preload;
14841
14999
  }, [loop, muted, playsInline, preload, resource, volume]);
14842
- useEffect34(() => {
15000
+ useEffect35(() => {
14843
15001
  if (!resource) {
14844
15002
  return;
14845
15003
  }
@@ -14862,12 +15020,12 @@ function VideoHotspot({
14862
15020
  };
14863
15021
  }, [playing, resource]);
14864
15022
  const activeTexture = resource?.ready ? resource.texture : posterTexture;
14865
- return /* @__PURE__ */ jsx33(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx33(HotspotPlane, { map: activeTexture, opacity }) });
15023
+ return /* @__PURE__ */ jsx34(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx34(HotspotPlane, { map: activeTexture, opacity }) });
14866
15024
  }
14867
15025
 
14868
15026
  // src/hotspot/audio-hotspot.tsx
14869
15027
  import { useFrame as useFrame16, useThree as useThree25 } from "@react-three/fiber";
14870
- import { useEffect as useEffect35, useRef as useRef35, useState as useState19 } from "react";
15028
+ import { useEffect as useEffect36, useRef as useRef36, useState as useState19 } from "react";
14871
15029
  import {
14872
15030
  CanvasTexture as CanvasTexture2,
14873
15031
  ClampToEdgeWrapping as ClampToEdgeWrapping7,
@@ -14876,7 +15034,7 @@ import {
14876
15034
  SRGBColorSpace as SRGBColorSpace9,
14877
15035
  TextureLoader as TextureLoader8
14878
15036
  } from "three";
14879
- import { jsx as jsx34 } from "react/jsx-runtime";
15037
+ import { jsx as jsx35 } from "react/jsx-runtime";
14880
15038
  var SPEAKER_TEXTURE_SIZE = 512;
14881
15039
  function paintSpeakerBody(context, center) {
14882
15040
  context.fillStyle = "#f5fbfc";
@@ -14941,7 +15099,7 @@ function createSpeakerTexture(state) {
14941
15099
  }
14942
15100
  function useSpeakerTextures(enabled) {
14943
15101
  const [textures, setTextures] = useState19({ playing: null, stopped: null });
14944
- useEffect35(() => {
15102
+ useEffect36(() => {
14945
15103
  if (!enabled) {
14946
15104
  setTextures({ playing: null, stopped: null });
14947
15105
  return;
@@ -14959,9 +15117,9 @@ function useSpeakerTextures(enabled) {
14959
15117
  function useIconTexture(icon, enabled, onError, id) {
14960
15118
  const gl = useThree25((state) => state.gl);
14961
15119
  const [texture, setTexture] = useState19(null);
14962
- const onErrorRef = useRef35(onError);
15120
+ const onErrorRef = useRef36(onError);
14963
15121
  onErrorRef.current = onError;
14964
- useEffect35(() => {
15122
+ useEffect36(() => {
14965
15123
  let active = true;
14966
15124
  setTexture(null);
14967
15125
  if (!enabled || !icon) {
@@ -14998,7 +15156,7 @@ function useIconTexture(icon, enabled, onError, id) {
14998
15156
  active = false;
14999
15157
  };
15000
15158
  }, [enabled, gl, icon, id]);
15001
- useEffect35(
15159
+ useEffect36(
15002
15160
  () => () => {
15003
15161
  texture?.dispose();
15004
15162
  },
@@ -15018,12 +15176,12 @@ function useAudioHowl({
15018
15176
  src
15019
15177
  }) {
15020
15178
  const [howl, setHowl] = useState19(null);
15021
- const playingRef = useRef35(playing);
15022
- const loopRef = useRef35(loop ?? false);
15023
- const onEndedRef = useRef35(onEnded);
15024
- const onErrorRef = useRef35(onError);
15025
- const onPlaybackErrorRef = useRef35(onPlaybackError);
15026
- const onPlaybackStateChangeRef = useRef35(onPlaybackStateChange);
15179
+ const playingRef = useRef36(playing);
15180
+ const loopRef = useRef36(loop ?? false);
15181
+ const onEndedRef = useRef36(onEnded);
15182
+ const onErrorRef = useRef36(onError);
15183
+ const onPlaybackErrorRef = useRef36(onPlaybackError);
15184
+ const onPlaybackStateChangeRef = useRef36(onPlaybackStateChange);
15027
15185
  playingRef.current = playing;
15028
15186
  loopRef.current = loop ?? false;
15029
15187
  onEndedRef.current = onEnded;
@@ -15031,7 +15189,7 @@ function useAudioHowl({
15031
15189
  onPlaybackErrorRef.current = onPlaybackError;
15032
15190
  onPlaybackStateChangeRef.current = onPlaybackStateChange;
15033
15191
  const sourcesKey = sourceList(src).join("\0");
15034
- useEffect35(() => {
15192
+ useEffect36(() => {
15035
15193
  const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
15036
15194
  if (sources.length === 0) {
15037
15195
  setHowl(null);
@@ -15068,7 +15226,7 @@ function useAudioHowl({
15068
15226
  handle.dispose();
15069
15227
  };
15070
15228
  }, [crossOrigin, id, sourcesKey]);
15071
- useEffect35(() => {
15229
+ useEffect36(() => {
15072
15230
  howl?.loop(loop ?? false);
15073
15231
  }, [howl, loop]);
15074
15232
  return howl;
@@ -15095,6 +15253,7 @@ function AudioHotspot({
15095
15253
  onError,
15096
15254
  ...anchorProps
15097
15255
  }) {
15256
+ usePanoMediaActivationIntent(playing);
15098
15257
  const camera = useThree25((state) => state.camera);
15099
15258
  const howl = useAudioHowl({
15100
15259
  crossOrigin,
@@ -15111,15 +15270,15 @@ function AudioHotspot({
15111
15270
  const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
15112
15271
  const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
15113
15272
  const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
15114
- const playingRef = useRef35(playing);
15273
+ const playingRef = useRef36(playing);
15115
15274
  playingRef.current = playing;
15116
- const mutedRef = useRef35(muted);
15117
- const volumeRef = useRef35(volume);
15118
- const rangeRef = useRef35(range);
15275
+ const mutedRef = useRef36(muted);
15276
+ const volumeRef = useRef36(volume);
15277
+ const rangeRef = useRef36(range);
15119
15278
  mutedRef.current = muted;
15120
15279
  volumeRef.current = volume;
15121
15280
  rangeRef.current = range;
15122
- useEffect35(() => {
15281
+ useEffect36(() => {
15123
15282
  if (!howl) {
15124
15283
  return;
15125
15284
  }
@@ -15129,7 +15288,7 @@ function AudioHotspot({
15129
15288
  }
15130
15289
  howl.play();
15131
15290
  }, [howl, playing]);
15132
- useEffect35(() => {
15291
+ useEffect36(() => {
15133
15292
  if (!howl || !pauseWhenHidden) {
15134
15293
  return;
15135
15294
  }
@@ -15160,11 +15319,11 @@ function AudioHotspot({
15160
15319
  howl.mute(mutedRef.current);
15161
15320
  howl.volume(clampAudioVolume(volumeRef.current) * spatial.gain);
15162
15321
  });
15163
- return /* @__PURE__ */ jsx34(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ jsx34(HotspotPlane, { map: markerTexture, opacity }) : null });
15322
+ return /* @__PURE__ */ jsx35(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ jsx35(HotspotPlane, { map: markerTexture, opacity }) : null });
15164
15323
  }
15165
15324
 
15166
15325
  // src/hotspot/text-hotspot.tsx
15167
- import { useEffect as useEffect36, useRef as useRef36, useState as useState20 } from "react";
15326
+ import { useEffect as useEffect37, useRef as useRef37, useState as useState20 } from "react";
15168
15327
  import {
15169
15328
  CanvasTexture as CanvasTexture3,
15170
15329
  ClampToEdgeWrapping as ClampToEdgeWrapping8,
@@ -15172,7 +15331,7 @@ import {
15172
15331
  LinearMipmapLinearFilter as LinearMipmapLinearFilter8,
15173
15332
  SRGBColorSpace as SRGBColorSpace10
15174
15333
  } from "three";
15175
- import { jsx as jsx35 } from "react/jsx-runtime";
15334
+ import { jsx as jsx36 } from "react/jsx-runtime";
15176
15335
  var TEXT_TEXTURE_LONG_SIDE = 1024;
15177
15336
  var DEFAULT_FONT_FAMILY = "system-ui, sans-serif";
15178
15337
  var DEFAULT_FONT_SIZE = 96;
@@ -15393,11 +15552,11 @@ function createTextTexture(text, width, height, style) {
15393
15552
  }
15394
15553
  function useTextTexture(text, width, height, style, onLoad, onError) {
15395
15554
  const [texture, setTexture] = useState20(null);
15396
- const onLoadRef = useRef36(onLoad);
15397
- const onErrorRef = useRef36(onError);
15555
+ const onLoadRef = useRef37(onLoad);
15556
+ const onErrorRef = useRef37(onError);
15398
15557
  onLoadRef.current = onLoad;
15399
15558
  onErrorRef.current = onError;
15400
- useEffect36(() => {
15559
+ useEffect37(() => {
15401
15560
  let cancelled = false;
15402
15561
  let nextTexture = null;
15403
15562
  const run = async () => {
@@ -15490,13 +15649,13 @@ function TextHotspot({
15490
15649
  whiteSpace
15491
15650
  };
15492
15651
  const texture = useTextTexture(text, width, height, style, onLoad, onError);
15493
- return /* @__PURE__ */ jsx35(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx35(HotspotPlane, { map: texture, opacity }) });
15652
+ return /* @__PURE__ */ jsx36(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx36(HotspotPlane, { map: texture, opacity }) });
15494
15653
  }
15495
15654
 
15496
15655
  // src/hotspot/iframe-hotspot.tsx
15497
15656
  import { Html as Html2 } from "@react-three/drei";
15498
15657
  import { DoubleSide as DoubleSide6 } from "three";
15499
- import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
15658
+ import { jsx as jsx37, jsxs as jsxs19 } from "react/jsx-runtime";
15500
15659
  var IFRAME_LONG_SIDE = 800;
15501
15660
  var CSS3D_DISTANCE_FACTOR = 400;
15502
15661
  var DEFAULT_SANDBOX = "allow-scripts allow-popups allow-forms";
@@ -15563,8 +15722,8 @@ function IframeHotspot({
15563
15722
  width,
15564
15723
  children: [
15565
15724
  /* @__PURE__ */ jsxs19("mesh", { children: [
15566
- /* @__PURE__ */ jsx36("planeGeometry", { args: [1, 1] }),
15567
- /* @__PURE__ */ jsx36(
15725
+ /* @__PURE__ */ jsx37("planeGeometry", { args: [1, 1] }),
15726
+ /* @__PURE__ */ jsx37(
15568
15727
  "meshBasicMaterial",
15569
15728
  {
15570
15729
  depthWrite: false,
@@ -15575,7 +15734,7 @@ function IframeHotspot({
15575
15734
  }
15576
15735
  )
15577
15736
  ] }),
15578
- /* @__PURE__ */ jsx36(
15737
+ /* @__PURE__ */ jsx37(
15579
15738
  Html2,
15580
15739
  {
15581
15740
  distanceFactor: CSS3D_DISTANCE_FACTOR,
@@ -15590,7 +15749,7 @@ function IframeHotspot({
15590
15749
  },
15591
15750
  transform: true,
15592
15751
  zIndexRange: [10, 0],
15593
- children: /* @__PURE__ */ jsx36(
15752
+ children: /* @__PURE__ */ jsx37(
15594
15753
  "iframe",
15595
15754
  {
15596
15755
  allow,