@displayxr/inline3d 1.33.0 → 1.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/call.js +2 -2
- package/index.d.ts +8 -0
- package/js/inline3d-model-playcanvas.js +1 -0
- package/js/inline3d-model.js +1 -0
- package/js/inline3d-splat-playcanvas.js +1 -0
- package/js/inline3d-splat.js +1 -0
- package/js/inline3d.js +12 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
|
|
|
5
5
|
`./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
|
|
6
6
|
which tier they touch, because that is what tells you whether an upgrade can move your pixels.
|
|
7
7
|
|
|
8
|
+
## 1.33.1 — 2026-10-06
|
|
9
|
+
|
|
10
|
+
### Fixed — woven `addModel` tiles drew nothing (1.28.0–1.32.0)
|
|
11
|
+
|
|
12
|
+
- On every DisplayXR Browser, an `addModel` tile (PlayCanvas, the default) loaded its glTF and then
|
|
13
|
+
drew nothing in 3D, logging `GL_INVALID_OPERATION: glBlitFramebuffer: Invalid operation on
|
|
14
|
+
multisampled framebuffer` every frame. **Cause:** the core's scene-buffer check (1.28.0) called
|
|
15
|
+
`canvas.getContext('webgl2')` after the first stereo frame, before PlayCanvas had booted, so it
|
|
16
|
+
CREATED the tile's context with the default attributes (`antialias: true`). PlayCanvas then got
|
|
17
|
+
that context back, its own attributes ignored, and its MSAA resolve could not blit into the
|
|
18
|
+
multisampled default framebuffer. `addSplat` tiles drew, but on a context they never asked for
|
|
19
|
+
(MSAA on, `preserveDrawingBuffer` ignored).
|
|
20
|
+
- New `addScene` option **`bufferClamped`**. With it the core never inspects or creates the
|
|
21
|
+
canvas's context. Every SDK renderer passes it (they clamp their own buffers). A page running an
|
|
22
|
+
engine that creates its context after `addScene` should create the context first, or pass the
|
|
23
|
+
option.
|
|
24
|
+
|
|
8
25
|
## 1.33.0 — 2026-10-06
|
|
9
26
|
|
|
10
27
|
Touches the **preview tier** (`./call`) only: one default value. No export is added, removed or
|
package/dist/call.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/* @displayxr/inline3d 1.33.
|
|
2
|
-
var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),Cn=["high","normal","low","paused"],Rn=.02,Dn=1e3/20,Ln=3e3,An=1e3/28;function ye(n){return typeof n=="function"?n:n===!1||n==="off"?"off":"auto"}function it(n=import.meta.url){return ge?typeof ge=="function"?ge():ge:new URL("../lift/index.js",n).href}var ge=null;function ii(n){ge=n||null}function In(){return import(it())}async function nt(n,{importer:e=In,nav:t=globalThis.navigator,log:i=null,capsOpts:r={webFallback:!0}}={}){let s=(h,d)=>i&&i(h,d),o=(h,d={})=>(s("lift-unavailable",{reason:h,...d}),{lift:null,capabilities:null,caps:null,source:"none",reason:h}),a=ye(n);if(a==="off")return{lift:null,capabilities:null,caps:null,source:"none",reason:"off"};if(typeof a=="function"){let h=typeof a.liftCapabilities=="function"?a.liftCapabilities:null;return{lift:a,capabilities:h,caps:null,source:"injected",reason:null}}let l;try{l=await e()}catch(h){return o("import-failed",{message:String(h&&h.message||h).slice(0,200)})}let c=l&&typeof l.lift=="function"?l.lift:null;if(!c)return o("no-lift-export");let p=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,f=null;if(p){try{f=await p(r)}catch{f=null}let h=!!(f&&f.webFallback&&f.webFallback.webgpu);if(f&&!f.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(f&&f.native),provider:f&&f.provider||null}),{lift:c,capabilities:p,caps:f,source:"module",reason:null}}function ve(n){let e=Number.isFinite(+n)&&n!==null?Math.max(-1,Math.min(1,+n)):0;return Math.abs(e)<Rn?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Le({id:n,speakerId:e,visible:t=!0}){return t?n!=null&&n===e?_e.speaker:_e.other:_e.hidden}function rt(n,e){if(!n||!Cn.includes(e)||typeof n.setPriority!="function")return!1;try{return n.setPriority(e)!==!1}catch{return!1}}function st({degradedMs:n=Dn,recoveredMs:e=An,holdMs:t=Ln,alpha:i=.1}={}){let r=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(r=r===null?a:r+i*(a-r),o){if(r<e)return o=!1,s=0,"recovered"}else if(s=r>n?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){r=null,s=0,o=!1},get frameMs(){return r},get degraded(){return o}}}function ot({lift:n,max:e=4,log:t=null,options:i=null}={}){let r=i&&typeof i=="object"?i:{},s=new Map,o=null,a=0,l=0,c=(h,d)=>t&&t(h,d),p=(h,d)=>{if(!d.handle)return;let m=Le({id:h,speakerId:o,visible:d.visible});if(m===d.priority)return;d.priority=m;let u=rt(d.handle,m);c("lift-priority",{peer:h,priority:m,applied:u})},f={get size(){return s.size},get max(){return e},set max(h){e=Math.max(0,h|0)},has:h=>s.has(h),handle:h=>s.get(h)&&s.get(h).handle||null,priority:h=>s.get(h)&&s.get(h).priority||null,canAcquire:h=>s.has(h)||s.size<e,acquire(h,d,{wall:m,visible:u=!0,onError:v}={}){let y=s.get(h);if(y)return y.pending||Promise.resolve(y.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,C=Le({id:h,speakerId:o,visible:u}),x={gen:b,handle:null,visible:u,priority:C,pending:null};s.set(h,x);let O={quality:"auto",...r,mode:"live",wall:m,ui:"none",convergence:ve(a),priority:C};return c("lift-acquire",{peer:h,priority:C,convergence:O.convergence}),x.pending=Promise.resolve().then(()=>n(d,O)).then(T=>{if(s.get(h)!==x||x.gen!==b){try{T&&T.remove&&T.remove()}catch{}return null}return x.pending=null,x.handle=T||null,x.priority=null,p(h,x),T&&typeof T.setConvergence=="function"&&T.setConvergence(ve(a)),x.handle},T=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(T&&T.message||T).slice(0,200)}),v&&v(T),null)),x.pending},release(h){let d=s.get(h);if(d){if(s.delete(h),d.handle)try{d.handle.remove()}catch{}c("lift-release",{peer:h})}},releaseAll(){for(let h of[...s.keys()])f.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,m]of s)p(d,m)},setVisible(h,d){let m=s.get(h);!m||m.visible===!!d||(m.visible=!!d,p(h,m))},setDepth(h){a=h;let d=ve(h);for(let m of s.values())m.handle&&typeof m.handle.setConvergence=="function"&&m.handle.setConvergence(d);return d},get anyWeb(){for(let h of s.values())if(h.handle&&!h.handle.native)return!0;return!1},list(){return[...s].map(([h,d])=>({id:h,priority:d.priority,pending:!!d.pending,native:!!(d.handle&&d.handle.native)}))}};return f}var Pn=null;function ni(n){Pn=typeof n=="function"?n:null}var Fn=new WeakMap;function ri(n,e){n&&(typeof n=="object"||typeof n=="function")&&Fn.set(n,e)}var jn=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063});function si(n,e,t=1){let i=jn,r=!!n&&n.displayWidthMeters>0&&n.displayHeightMeters>0&&n.displayPixelWidth>0&&n.displayPixelHeight>0,s=r?[n.displayWidthMeters,n.displayHeightMeters]:[...i.displaySizeM],o=r?[n.displayPixelWidth,n.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=r?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),p=n?.nominalViewerPosition?.z,f=Number.isFinite(p)&&p>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:f?p:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:r?"display":"default",viewer:f?"display":"default",eyeSeparation:"default"}}}var oi=new WeakMap,J;function ai(n){let e=null;for(let[t,i]of n)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function Wn(n){if(!n||typeof n.getParameter!="function")return null;let e=oi.get(n);if(e)return e;let t,i,r;try{t=n.getParameter(n.MAX_TEXTURE_SIZE??3379),i=n.getParameter(n.MAX_RENDERBUFFER_SIZE??34024),r=n.getParameter(n.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=r&&r.length>=2?r[0]:0,o=r&&r.length>=2?r[1]:0,a=ai([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=ai([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",o]]);if(!a||!l)return null;let c={maxW:a[1],maxH:l[1],nameW:a[0],nameH:l[0],valueW:a[1],valueH:l[1]};return oi.set(n,c),c}function li(){if(J!==void 0)return J;J=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return J;let n=document.createElement("canvas"),e=n.getContext("webgl2")||n.getContext("webgl");if(!e)return J;J=Wn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function ci(n,e,t,{cols:i=2,rows:r=1}={}){let s=n*i,o=e*r,a={eyeW:n,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(n>0)||!(e>0))return a;let l=t.maxW/s,c=t.maxH/o,p=Math.min(l,c);if(!(p<1))return a;let f=l<=c,h=Math.max(1,Math.min(Math.floor(n*p+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*p+1e-9),Math.floor(t.maxH/r)));return{eyeW:h,eyeH:d,cols:i,scale:p,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*r,limitName:f?t.nameW:t.nameH,limitValue:f?t.valueW:t.valueH}}function at(n){return Math.round(n*1e3)/1e3}function di(n,e,t){let i=typeof t=="number"?` (renderScale ${at(t)} \u2192 ${at(t*e.scale)})`:` (scale ${at(e.scale)})`;return`${n} ${e.cols===1?"buffer":"SBS buffer"} ${e.reqW}\xD7${e.reqH} exceeds ${e.limitName} ${e.limitValue} on this device; rendering at ${e.bufW}\xD7${e.bufH}${i}.`}function hi(n,e){let t=n?.width||0,i=n?.height||0,r=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?r/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:r,h:s,mismatch:o!==1||a!==1}}function fi(n,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${n} the browser clamped this canvas's drawing buffer to ${t.w}\xD7${t.h} (canvas.width/height say ${e.width}\xD7${e.height}); ${i}`}var ie="smoothstep",ct=["linear","smoothstep","easeoutcubic"];function dt(n){if(typeof n!="string")return null;let e=n.toLowerCase().replace(/[-_\s]/g,"");return ct.includes(e)?e:null}function Nn(n,e){if(e<=0)return 0;if(e>=1)return 1;if(n==="linear")return e;if(n==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var te="idle",ui="rampDownThenFire",lt="fireThenRampUp",Ae=class{constructor(e,t){this._phase=te,this._targetMode=null,this._firePending=!1,this._fireAtEnd=!1,this._from=0,this._to=0,this._cur=0,this._t=1,this._dur=180/1e3,this._easing=ie,(e!==void 0||t!==void 0)&&this.configure(e,t)}configure(e,t){if(e!==void 0){let i=Number(e);this._dur=Number.isFinite(i)&&i>0?i:0}return t!==void 0&&(this._easing=dt(t)||ie),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:r,current:s,steady:o=1}={}){let a=!(t>1),l=!(r>1),c=Number.isFinite(o)?o:1,p=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=p,a&&!l?(this._phase=ui,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=lt,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=lt,this._to=a?p:c,this._firePending=!(e!==null&&e===i),this._fireAtEnd=!1),this._t=this._dur>0?0:1,this._cur=this._from,this}update(e){let t=!1;if(this._phase!==te){let i=Number.isFinite(e)&&e>0?e:0;this._t<1&&this._dur>0?(this._t+=i/this._dur,this._t>1&&(this._t=1)):this._t=1,this._cur=this._from+(this._to-this._from)*Nn(this._easing,this._t),this._phase===lt?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=te)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=te)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==te}value(){return this._cur}firePending(){return this._phase===ui?this._fireAtEnd:this._firePending}cancel(){return this._phase=te,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var U=null;ni(n=>{let e=U;if(!e||!e._running||!n)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===n&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof n.contains=="function"&&n.contains(i.canvas))return t(i);for(let i of e._windows.values()){let r=i.canvas.parentElement;if(i.layer&&r&&typeof r.contains=="function"&&r.contains(n))return t(i)}return null});var zn=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Ie=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,ht=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Hn=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Si=["renderingmodechange","hardwaredisplaystatechange"],gt="trackingstatechange",Mi=["unknown","tracking","searching"],mi=[...Si,gt];function Oe(n){try{let e=n?n.trackingState:void 0;return Mi.includes(e)?e:null}catch{return null}}var ft=()=>{if(!Q())return!1;try{let n=window.XRDisplayLayer.prototype;return Hn.every(e=>typeof n[e]=="function")}catch{return!1}},ut=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},re=null;function ne(){if(re!==null)return re;if(!Q())return!1;try{let n=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof n=="boolean")return re=n}catch{}return!1}function Vn(n){if(re!==null)return re;if(!n||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return re=!!n.occlusionByDrawOrder}catch{return null}}var gi=!1;function pt(){gi||(gi=!0,console.info("[inline3d] This browser composites 2D over woven 3D automatically, per-pixel by draw order \u2014 overlay exclusion is obsolete here, so exclude()/addGlobalOverlay()/data-inline3d-overlay/autoChrome are accepted and ignored. Your 2D chrome already occludes the tiles correctly. The calls are harmless (keep them if you also ship to older DisplayXR Browsers); gate on inline3dOcclusionByDrawOrder() to drop them."))}function Ei(){return zn()&&Q()}function mt(n){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:n.virtualDisplayHeight>0?n.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function $n(n,e){let t=Number.isFinite(n.ipdFactor)?n.ipdFactor:1,i=Number.isFinite(n.parallaxFactor)?n.parallaxFactor:1;return{...n,ipdFactor:t*e,parallaxFactor:i*e}}var Un=16;function V(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Bn=1200,_i=!1;function qn(n){if(n==null)return ie;let e=dt(n);return e||(_i||(_i=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(n)} } }) is not a curve this SDK knows (${ct.join(" / ")}); using '${ie}'.`)),ie)}var vi=!1;function Xn(){vi||(vi=!0,console.info("[inline3d] The active rendering mode is 1-view, so this SDK has zeroed every window rig (ipdFactor/parallaxFactor -> 0) \u2014 both eyes now render from one place. The runtime keeps weaving the same two-view atlas whatever the page submits, so leaving stereo in it would put two slightly different images on a flat panel, i.e. a blurry double image instead of 2D. Your rendering is unchanged; the flattening is a copy applied on the way to the layer and it is undone the moment a 2-view mode goes active again."))}function _t(n){return n&&n.detail!==void 0&&n.detail!==null?n.detail:void 0}function ki(n){let e=_t(n);return e!==void 0?[e,n]:[n]}function Gn(n){for(let e of ki(n)){if(typeof e=="number"&&Number.isFinite(e))return e;if(e&&typeof e=="object"){let t=e.modeIndex!==void 0?e.modeIndex:e.mode;if(typeof t=="number"&&Number.isFinite(t))return t}}return-1}function Jn(n){for(let e of ki(n)){if(e==="2d"||e==="3d")return e;if(e&&typeof e=="object"){let t=e.state!==void 0?e.state:e.hardwareDisplayState;if(t==="2d"||t==="3d")return t}}return null}var yi=!1;function Kn(){yi||(yi=!0,console.warn("[inline3d] This browser has no XRDisplayLayer.setViewRig, so the view rig was ignored (the window still weaves \u2014 the runtime keeps the default display rig, scaled by virtualDisplayHeight). Gate on inline3dViewRigSupported() if your page's framing depends on the rig; further calls are silent."))}var wi=!1;function Yn(){wi||(wi=!0,console.warn("[inline3d] addScene got BOTH viewRig and virtualDisplayHeight; on a browser with rig support the rig wins and the height is dropped. They describe the same slot \u2014 virtualDisplayHeight is shorthand for exactly one rig (display, identity pose, all factors 1) \u2014 so there is no merge. This is only worth passing as a PAIR deliberately: the height is what a browser without setViewRig will use, so a camera-rig scene can name its own fallback framing. Otherwise say it once, inside the rig."))}async function Ti(n={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:r=!0,modeSwitch:s=null,untrackedFallback:o="none",viewerEase:a}=n;if(!Ei())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(p){return{supported:!1,trackingState:"unknown",error:p}}a!==void 0&&ri(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new vt(l,c,{lazy:t,rootMargin:i,autoChrome:r,modeSwitch:s,untrackedFallback:o})}var we=null;function Fe(n={}){return U&&U._running?Promise.resolve(U):we||(we=Ti(n).finally(()=>{we=null}),we)}var bi=.7,Zn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Qn(n){let e=[],t=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(Zn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let r of i.childNodes)if(r.nodeType===Node.TEXT_NODE&&r.nodeValue.trim()){e.push(i);break}}return e}var er=4;function xi(n){let e=typeof window<"u"&&window.devicePixelRatio||1;return`${n.clientWidth}x${n.clientHeight}@${e}`}var vt=class{constructor(e,t,{lazy:i,rootMargin:r,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._globalOverlays=new Set,this._isolatedBy=new WeakMap,this._autoChrome=s,this._autoChromeEls=new Set,this._lastChromeScan=0,this._fullTileWarned=new WeakSet,this._stoodDown=!1,this._activeModeIndex=-1,this._activeViewCount=0,this._hardwareDisplayState=null,this._modes=null,this._stereoCollapsed=!1,this._displayListeners=new Map,this._primedDisplayState=!1;let l=o&&typeof o=="object"?o:{};this._msEnabled=l.enabled!==!1,this._modeSwitch=new Ae((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,qn(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Oe(e)!==null,this._trackingState=this._trackingSupported?Oe(e):"unknown",this._untrackedFallback=a==="mono"?"mono":"none",this._bakedStereo=1,this._bakedTarget=1,this._bakedAt=null,this._bakedEaseS=(Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,this._applyUntrackedTarget(),this.undock=ut()?{model:!1,splat:!1}:null,this._undockRead=!1,this._running=!0,this._lazy=i,this._observer=i&&typeof IntersectionObserver=="function"?new IntersectionObserver(c=>this._onIntersect(c),{rootMargin:r}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,U&&U._running&&U!==this&&console.warn("[inline3d] A second inline-3D session is live in this document. The browser's element-rect channel is a whole-widget setter, so both managers clobber each other's rect list every frame \u2014 tiles may flicker, ghost, or weave at a stale rect. Use ONE createInline3D() per document and add every window to it; if you are switching views, close() the previous manager first."),U=this,e.addEventListener("end",()=>this._teardown()),this._bindDisplayEvents(),this._bindTrackingEvents(),this._scanChrome(),this._bindLifecycle(),this._armDprWatch(),this._requestFrame()}get liveCount(){let e=0;for(let t of this._windows.values())t.layer&&e++;return e}addGlobalOverlay(e){if(!(!e||this._globalOverlays.has(e))){ne()&&pt(),this._globalOverlays.add(e);for(let t of this._windows.values())t.layer&&this._applyExclusion(t,e)}}removeGlobalOverlay(e){if(!(!e||!this._globalOverlays.delete(e)))for(let t of this._windows.values())t.layer&&this._dropExclusion(t,e)}_scanChrome(){if(ne()||!this._autoChrome||!Ie()||typeof document>"u")return;let e=Date.now();if(e-this._lastChromeScan<1e3)return;this._lastChromeScan=e;let t=document.body;if(!t)return;let i=new Set,r=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of r){if(s.closest("[data-inline3d-no-overlay]"))continue;let o=getComputedStyle(s).position;if(o!=="fixed"&&o!=="sticky")continue;let a=!1;for(let l of this._windows.keys())if(s===l||s.contains(l)){a=!0;break}if(!a){i.add(s);for(let l of Qn(s))i.add(l)}}for(let s of this._autoChromeEls){let o=!1;if(s.isConnected){for(let a of this._windows.keys())if(s===a||s.contains(a)){o=!0;break}}(!s.isConnected||o)&&(this._autoChromeEls.delete(s),this.removeGlobalOverlay(s))}for(let s of i)this._globalOverlays.has(s)||(this._autoChromeEls.add(s),this.addGlobalOverlay(s))}addImage(e,t,i={}){let r=this._register(e,"image",i);return r.ready=ir(t).then(s=>{r.img=s,r.repaint()}),this._handle(e,r)}addVideo(e,t,i={}){let r=this._register(e,"video",i);return r.video=t,this._handle(e,r)}addScene(e,t,i={}){i.viewRig&&i.virtualDisplayHeight!==void 0&&Yn();let r=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return r.onFrame=t,r.ownsBuffer=!1,this._handle(e,r)}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:r=>{r&&(ne()&&pt(),t.excluded.add(r),this._applyExclusion(t,r))},unexclude:r=>{!r||!t.excluded.delete(r)||this._dropExclusion(t,r)},get trackingState(){return i._trackingState},setViewRig:r=>(t.viewRig=r||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let r=null;try{r=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return si(r,e.getBoundingClientRect(),globalThis.devicePixelRatio||1)},getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:r=>this._requestRenderingModeEased(r,t),setStereoEnabled:r=>this._setStereoEnabled(r,t),on:(r,s)=>this.on(r,s),off:(r,s)=>this.off(r,s),onDisplayModeChange:r=>this._onDisplayModeChange(r),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get firstWoven(){return t.fwPromise},onFirstWoven:r=>{if(typeof r!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{r(o)}catch(a){console.error("[inline3d] onFirstWoven callback threw",a)}}),()=>{s=!1}},rewoven:()=>this._rewoven(t)}}getDisplayInfo(){return this._layerCall(this._liveWindow(null),"getDisplayInfo","getDisplayInfo()")}getRenderingModes(){return this._getRenderingModes(null)}requestRenderingMode(e){return this._requestRenderingModeEased(e,null)}setStereoEnabled(e){return this._setStereoEnabled(e,null)}get trackingState(){return this._trackingState}get hardwareDisplayState(){return this._hardwareDisplayState}get activeMode(){return{modeIndex:this._activeModeIndex,viewCount:this._activeViewCount}}get stereoCollapsed(){return this._stereoCollapsed}get modeSwitch(){return{active:this._msTransitionActive(),factor:this._stereoFactor}}close(){try{this.session.end()}catch{}this._teardown()}_effectiveViewRig(e){return this._stereoFactor>=1?e.viewRig||(e.stereoSynthRig?mt(e):null):(e.viewRig||(e.stereoSynthRig=!0),$n(e.viewRig||mt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&Xn(),!t&&this._msArmedUp?(this._msArmedUp=!1,this._startUpRamp()):this._modeSwitch.active()||(this._stereoFactor=t?0:1);for(let i of this._windows.values()){if(t){let r=i.viewRig||mt(i);i.stereoSaved={ipdFactor:r.ipdFactor,parallaxFactor:r.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!ht())return Kn(),!1;if(!e.layer)return!1;let t=this._effectiveViewRig(e);try{return e.layer.setViewRig(t),!0}catch{return!1}}_layerCall(e,t,i,r=[]){if(!ft())return Promise.reject(new Error(`[inline3d] ${i} needs a DisplayXR Browser with the display-mode API (XRDisplayLayer.getDisplayInfo/getRenderingModes/requestRenderingMode). Gate on inline3dDisplayModesSupported().`));if(!e||!e.layer)return Promise.reject(new Error(`[inline3d] ${i} needs a live weave layer, and this window has none right now (lazy mode closes the layer while the tile is off screen). Call it once the tile is visible, or create the manager with { lazy: false }.`));try{return Promise.resolve(e.layer[t](...r))}catch(s){return Promise.reject(s)}}_liveWindow(e){if(e&&e.layer)return e;for(let t of this._windows.values())if(t.layer)return t;return e||null}async _getRenderingModes(e){let t=await this._layerCall(this._liveWindow(e),"getRenderingModes","getRenderingModes()"),i=Array.isArray(t)?t:[];this._modes=i;let r=i.find(s=>s.isActive);return r&&(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount,(r.viewCount===1||r.viewCount===2)&&this._setStereoCollapsed(r.viewCount===1)),this._primedDisplayState=!0,t}_requestRenderingMode(e,t){return this._layerCall(this._liveWindow(t),"requestRenderingMode","requestRenderingMode()",[e])}_msTransitionActive(){return this._modeSwitch.active()||this._msArmedUp||this._msFire!==null}async _requestRenderingModeEased(e,t){if(!this._msEnabled||!ht())return this._requestRenderingMode(e,t);let i=this._modes;if(!Array.isArray(i)||i.length===0)try{i=await this._getRenderingModes(t)}catch{i=null}let r=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=r&&Number.isFinite(r.viewCount)?r.viewCount:0,o=this._activeViewCount;return s<1||s>2||o<1?this._requestRenderingMode(e,t):s===1?o===1?this._requestRenderingMode(e,t):this._rampDownThenRequest(e,t):this._requestThenRampUp(e,t)}_rampDownThenRequest(e,t){if(this._msFire&&this._msFire.modeIndex===e)return this._msFire.promise;this._settlePendingDown("superseded",`a request for mode ${e} replaced it`);let i={modeIndex:e,win:t,resolve:null,reject:null,promise:null};return i.promise=new Promise((r,s)=>{i.resolve=r,i.reject=s}),this._msFire=i,this._modeSwitch.request({targetMode:e,targetViewCount:1,currentMode:this._activeModeIndex,currentViewCount:this._activeViewCount,current:this._stereoFactor,steady:1}),this._msLastMs=V(),this._armModeSwitchTick(),i.promise}_requestThenRampUp(e,t){let r=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=r?Promise.resolve(void 0):this._requestRenderingMode(e,t);return this._stereoFactor<1&&(this._stereoCollapsed?(this._msArmedUp=!0,this._modeSwitch.cancel(),this._stereoFactor=0):this._startUpRamp()),s.catch(o=>{throw this._msArmedUp&&(this._msArmedUp=!1,this._modeSwitch.active()||(this._stereoFactor=this._stereoCollapsed?0:1)),o})}_startUpRamp(){this._settlePendingDown("superseded","the display returned to 3D"),this._modeSwitch.request({targetMode:this._activeModeIndex,targetViewCount:2,currentMode:this._activeModeIndex,currentViewCount:2,current:this._stereoFactor,steady:1}),this._msLastMs=V(),this._armModeSwitchTick()}_settlePendingDown(e,t){let i=this._msFire;if(!i)return;this._msFire=null;let r=new Error(`[inline3d] the request for rendering mode ${i.modeIndex} was never forwarded: ${t}. A ->2D switch is held until the disparity has ramped out, so a request that is reversed or replaced in that window is dropped rather than fired late.`);r.name=e,i.reject(r)}_advanceModeSwitch(){if(!this._modeSwitch.active()){this._msLastMs=null,this._disarmModeSwitchTick();return}let e=V(),t=typeof this._msLastMs=="number"?Math.max(0,(e-this._msLastMs)/1e3):0;this._msLastMs=e;let i=this._modeSwitch.update(t);if(i.factor!==this._stereoFactor){this._stereoFactor=i.factor;for(let r of this._windows.values())this._pushViewRig(r)}if(i.fire&&this._msFire){let r=this._msFire;this._msFire=null,this._requestRenderingMode(r.modeIndex,r.win).then(s=>r.resolve(s),s=>{this._startUpRamp(),r.reject(s)})}this._modeSwitch.active()||(this._msLastMs=null,this._disarmModeSwitchTick())}_armModeSwitchTick(){this._msTick!==null||typeof setTimeout!="function"||(this._msTick=setTimeout(()=>{this._msTick=null,this._running&&(this._advanceModeSwitch(),this._modeSwitch.active()&&this._armModeSwitchTick())},Un))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,r=await this._getRenderingModes(t),s=Array.isArray(r)?r:[],o=s.find(a=>a.viewCount===i&&a.isRequestable);if(!o)throw new Error(`[inline3d] setStereoEnabled(${!!e}) found no requestable ${i}-view mode on this display (${s.length} mode(s) listed). It is sugar over requestRenderingMode() and cannot invent one \u2014 read getRenderingModes() and drive the list yourself.`);return o.isActive&&!this._msTransitionActive()||await this._requestRenderingModeEased(o.modeIndex,t),!!e}_bindDisplayEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||ft()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=Jn(e),i=_t(e),r=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&r(t);let s=this._activeModeIndex,o=this._activeViewCount;return this._getRenderingModes(null).then(a=>{let l=(Array.isArray(a)?a:[]).find(c=>c.isActive)||null;if(l&&(l.modeIndex!==s||l.viewCount!==o)&&this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:l,detail:null}),!t){let c=l&&typeof l.hardwareDisplay3D=="boolean"?l.hardwareDisplay3D?"3d":"2d":null;r(c)}}).catch(()=>{t||r(null)})}async _onRenderingModeChange(e){let t=_t(e),i=Gn(e),r=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];r=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}r?(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount):i>=0&&(this._activeModeIndex=i),(this._activeViewCount===1||this._activeViewCount===2)&&this._setStereoCollapsed(this._activeViewCount===1),this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:r,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let r=t||[e];for(let s of[...i])try{s(...r)}catch(o){console.error(`[inline3d] ${e.type} listener threw`,o)}}on(e,t){if(typeof t!="function")throw new TypeError("[inline3d] on() takes (type, function).");if(!mi.includes(e))throw new TypeError(`[inline3d] on() knows ${mi.join(" / ")}, got ${JSON.stringify(e)}.`);let i=this._displayListeners.get(e);return i||this._displayListeners.set(e,i=new Set),i.add(t),()=>this.off(e,t)}off(e,t){let i=this._displayListeners.get(e);i&&i.delete(t)}_onDisplayModeChange(e){if(typeof e!="function")throw new TypeError("[inline3d] onDisplayModeChange() takes a function.");let t=Si.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!ut())return this.undock=null;let e=this._liveWindow(null);if(!e||!e.layer||typeof e.layer.getUndockCapabilities!="function")return this.undock;try{let t=await e.layer.getUndockCapabilities();this.undock={model:!!(t&&t.model),splat:!!(t&&t.splat)}}catch{}return this.undock}_register(e,t,i){this._windows.has(e)&&this._remove(e),e.style.willChange="transform",e.style.transform="translateZ(0)";let r={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,ready:null,ownsBuffer:t!=="scene",cornerRadius:i.cornerRadius||0,feather:i.feather||0,reqW:i.width||0,reqH:i.height||0,virtualDisplayHeight:i.virtualDisplayHeight||0,viewRig:i.viewRig||null,stereoSaved:null,stereoSynthRig:!1,observeEl:i.observe||e,ctx:t==="scene"?null:e.getContext("2d"),repaint:()=>this._paint(r,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:tr(i.firstWovenHoldMs),fwRegAt:V(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null};return r.fwPromise=new Promise(s=>{r.fwResolve=s}),this._windows.set(e,r),this._lazy&&this._observer?this._observer.observe(r.observeEl):this._activate(r),r}_remove(e){let t=this._windows.get(e);t&&(this._observer&&this._observer.unobserve(t.observeEl),this._deactivate(t),this._windows.delete(e),this._settleFirstWoven(t,!1,"removed"))}_onIntersect(e){for(let t of e){let i=null;for(let r of this._windows.values())if(r.observeEl===t.target){i=r;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=ht()?this._effectiveViewRig(e):null,i=t?{viewRig:t}:e.virtualDisplayHeight>0?{virtualDisplayHeight:e.virtualDisplayHeight}:{};e.layer=new XRDisplayLayer(this.session,e.canvas,i)}catch(t){e.layer=null,e.layerFailWarned||(e.layerFailWarned=!0,console.warn("[inline3d] new XRDisplayLayer() failed for this window \u2014 it will show FLAT 2D instead of woven 3D, and the SDK will not retry. The canvas has been repainted mono so it cannot be left holding a raw side-by-side pair.",t)),this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"layer-failed");return}e.fwResult||(e.fwLayerAt=V(),e.fwStereo=!1),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&ft()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),ut()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),Vn(e.layer)===!0&&this._standDownLegacyOcclusion();for(let t of e.excluded)this._applyExclusion(e,t);for(let t of this._globalOverlays)this._applyExclusion(e,t);this._startOverlayScan(e),e.ownsBuffer&&(this._sizeBuffer(e,!0),this._paint(e,null)),this._startSizeWatch(e)}}_deactivate(e){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e)}_paintMono(e){!e.ownsBuffer||e.kind==="scene"||(this._sizeBuffer(e,!1),this._paint(e,null))}_notifyLayerLost(e){if(!(e.kind!=="scene"||typeof e.onLayerLost!="function"||e.layerLostSent)){e.layerLostSent=!0;try{e.onLayerLost()}catch(t){console.warn("[inline3d] a scene window's onLayerLost callback threw",t)}}}_isFullTileOverlay(e,t){if(!t||typeof t.getBoundingClientRect!="function")return!1;let i=t.getBoundingClientRect(),r=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=r.width*r.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,r.right)-Math.max(i.left,r.left),l=Math.min(i.bottom,r.bottom)-Math.max(i.top,r.top);if(a<=0||l<=0)return!1;let c=a*l;return c/s<bi||c/o<bi?!1:(this._fullTileWarned.has(t)||(this._fullTileWarned.add(t),console.warn("[inline3d] Refusing a full-tile overlay: this element covers its own woven canvas, and the browser's geometric matcher cannot tell the two apart \u2014 it would stage the CANVAS as the overlay and the tile would show its raw side-by-side buffer instead of 3D. Make the overlay a PARTIAL region of the tile (a caption band, a badge, a corner plate), or move it outside the tile and register it with addGlobalOverlay().",t)),!0)}_applyExclusion(e,t){if(ne()||!e.layer||!Ie()||this._isFullTileOverlay(e,t))return;let i=this._isolatedBy.get(t);if(i||(i=new Set,this._isolatedBy.set(t,i)),i.add(e),!t.dataset.inline3dIsolated){t.dataset.inline3dPriorWillChange=t.style.willChange||"";let r=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=r,t.dataset.inline3dIsolated="1"}try{e.layer.excludeElement(t)}catch{}}_dropExclusion(e,t){if(ne())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Ie()))try{e.layer.unexcludeElement(t)}catch{}}_unpromote(e){return!e||!e.dataset||!e.dataset.inline3dIsolated?!1:(e.style.willChange=e.dataset.inline3dPriorWillChange||"",delete e.dataset.inline3dPriorWillChange,delete e.dataset.inline3dIsolated,!0)}_standDownLegacyOcclusion(){if(this._stoodDown)return;this._stoodDown=!0;let e=!1;for(let t of this._windows.values()){t.overlayObserver&&(this._stopOverlayScan(t),e=!0);for(let i of t.excluded)this._unpromote(i)&&(e=!0)}for(let t of this._autoChromeEls)this._globalOverlays.delete(t),this._unpromote(t),e=!0;this._autoChromeEls.clear();for(let t of this._globalOverlays)this._unpromote(t)&&(e=!0);this._isolatedBy=new WeakMap,e&&pt()}_startOverlayScan(e){if(ne()||!Ie()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let r=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)r.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of r)e.autoExcluded.has(s)||(e.autoExcluded.add(s),this._applyExclusion(e,s))};i(),e.overlayObserver=new MutationObserver(i),e.overlayObserver.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-inline3d-overlay"]})}_stopOverlayScan(e){e.overlayObserver&&(e.overlayObserver.disconnect(),e.overlayObserver=null),e.autoExcluded.clear()}_eyeSize(e,t=!0){let i=Math.min(window.devicePixelRatio||1,2),r=e.reqW||Math.round((e.canvas.clientWidth||256)*i),s=e.reqH||Math.round((e.canvas.clientHeight||256)*i),o=1,a=!e.reqW&&!e.reqH&&this._sourceEyeSize(e);if(a){let c=Math.max(a.w/r,a.h/s);c<1&&(o=c,r=Math.max(1,Math.round(r*c)),s=Math.max(1,Math.round(s*c)))}let l=ci(r,s,li(),{cols:t?2:1});return l.clamped&&(o*=l.scale,r=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(di("[inline3d]",l)))),e.bufScale=o,{w:r,h:s}}_sourceEyeSize(e){if(e.kind!=="video"&&e.kind!=="image")return null;let t=e.kind==="video"?e.video:e.img;if(!t)return null;let i=t.videoWidth||t.naturalWidth||t.width,r=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(r>0)?null:{w:i/2,h:r}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let r=null;try{r=t.getContext("webgl2")||t.getContext("webgl")}catch{r=null}e.sceneGl=r&&typeof r.drawingBufferWidth=="number"?r:null}if(!e.sceneGl)return;let i=hi(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(fi("[inline3d]",t,i,"getViewport() splits canvas.width, so the eyes are off-centre in the woven buffer. This scene canvas is sized by the page: keep 2 \xD7 eye width and the height within MAX_TEXTURE_SIZE / MAX_RENDERBUFFER_SIZE / MAX_VIEWPORT_DIMS, or map getViewport() onto gl.drawingBufferWidth/Height.")))}_sizeBuffer(e,t){let{w:i,h:r}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=r,e.canvas.width=t?i*2:i,e.canvas.height=r,e.sbs=t}_startSizeWatch(e){typeof ResizeObserver=="function"&&(e.sizeObserver||!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas)))}_stopSizeWatch(e){e.sizeObserver&&(e.sizeObserver.disconnect(),e.sizeObserver=null),e.resizePending=!1}_onBoxChange(e){if(!e.layer||!e.ownsBuffer||e.resizePending)return;e.resizePending=!0;let t=()=>{if(!e.resizePending||(e.resizePending=!1,!e.layer||!e.ownsBuffer))return;this._noteRewovenBox(e);let{w:i,h:r}=this._eyeSize(e);i===e.eyeW&&r===e.eyeH||(this._sizeBuffer(e,!0),this._paint(e,null))};typeof requestAnimationFrame=="function"?requestAnimationFrame(t):t()}_armDprWatch(){if(typeof window>"u"||typeof window.matchMedia!="function")return;this._disarmDprWatch();let e;try{e=window.matchMedia(`(resolution: ${window.devicePixelRatio||1}dppx)`)}catch{return}let t=()=>{if(this._running){this._armDprWatch();for(let i of this._windows.values())i.layer&&this._onBoxChange(i)}};try{e.addEventListener("change",t)}catch{return}this._dprWatch={q:e,onChange:t}}_disarmDprWatch(){if(this._dprWatch){try{this._dprWatch.q.removeEventListener("change",this._dprWatch.onChange)}catch{}this._dprWatch=null}}_paint(e,t){if(e.kind==="scene"||!e.ctx)return;let i=this._running&&!!e.layer;!i&&e.sbs&&this._sizeBuffer(e,!1);let r=e.kind==="video"?e.video:e.img;if(!r)return;if(e.kind==="video"&&(r.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=r.videoWidth||r.naturalWidth||r.width,l=r.videoHeight||r.naturalHeight||r.height;if(!a||!l)return;let c=a+"x"+l;if(e.srcKey!==c&&(e.srcKey=c,e.ownsBuffer&&!(e.reqW&&e.reqH))){let{w:u,h:v}=this._eyeSize(e,e.sbs);(u!==e.eyeW||v!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let p=e.bufScale||1,f=e.cornerRadius*p,h=e.feather*p;if(o.clearRect(0,0,s.width,s.height),!e.sbs){Pe(o,r,0,0,a/2,l,0,0,s.width,s.height,f,h);return}let d=s.width/2,m=Math.min(this._stereoFactor,this._bakedStereo);if(m<1){Pe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),nr(o,r,a/2,l,d,s.height,m,f,h);return}f>0||h>0?(Pe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),Pe(o,r,a/2,0,a/2,l,d,0,d,s.height,f,h)):o.drawImage(r,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(gt,()=>{this._setTrackingState(Oe(e)||"unknown")})}_setTrackingState(e){let t=Mi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:gt,state:t};this._emitDisplay(i,[t,i])}_applyUntrackedTarget(){if(this._untrackedFallback!=="mono"){this._bakedTarget=1;return}this._trackingState==="searching"?this._bakedTarget=0:this._trackingState==="tracking"&&(this._bakedTarget=1)}_trackBakedStereo(e){this._trackingSupported&&this._setTrackingState(Oe(this.session)||"unknown");let t=this._bakedAt===null||!Number.isFinite(e)?0:Math.max(0,(e-this._bakedAt)/1e3);this._bakedAt=Number.isFinite(e)?e:this._bakedAt;let i=this._bakedStereo,r=this._bakedTarget;if(i===r)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=r>i?Math.min(r,i+s):Math.max(r,i-s)}_recommitLastFrame(e){let t=e.canvas;if(!t.width||!t.height)return;let i=e.ctx;try{i.save(),i.globalCompositeOperation="copy",i.drawImage(t,0,0),i.restore()}catch{}}_requestFrame(e){if(!this._running||this._framePending&&!e)return;let t=e?++this._loopId:this._loopId;this._framePending=!0;try{this.session.requestAnimationFrame((i,r)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,r))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,r=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.kind==="scene"){if(r&&s.onFrame){if(s.frames++,r.length<2&&(s.monoFrames++,s.monoFrames%300===1&&typeof console<"u"&&console.debug)){let o=(100*s.monoFrames/Math.max(1,s.frames)).toFixed(1);console.debug(`[inline3d] scene window: ${s.monoFrames} non-stereo view lists in ${s.frames} frames (${o}%). The viewer replays its last good stereo frame for these; a rising rate means the session is falling back under load.`)}try{s.onFrame(r,s.layer,t),r.length>=2&&(s.fwStereo=!0,s.warnedBufMismatch||this._checkSceneBuffer(s),s.rw&&(s.rw.stereo=!0))}catch(o){s.frameThrewWarned||(s.frameThrewWarned=!0,console.warn("[inline3d] a scene window's onFrame threw; this window will keep whatever it last drew, and the other windows carry on. Further throws from it are silent.",o))}}}else this._paint(s,r),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.rw&&(s.rw.stereo=!0));this._tickFirstWoven(s)}}_tickFirstWoven(e){if(e.rw){this._noteRewovenBox(e);let t=e.rw,i=V();t.stereo&&i-t.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):t.at>t.calledAt&&i-t.calledAt>=er*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||V()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_settleFirstWoven(e,t,i){t||(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(V()-e.fwRegAt)}),e.fwResolve(e.fwResult),e.fwResolve=null)}_rewoven(e){if(!e.fwResult)return e.fwPromise;if(!e.fwResult.woven)return Promise.resolve(e.fwResult);if(e.rwGone)return Promise.resolve(Object.freeze({woven:!1,confirmed:!1,reason:e.rwGone,ms:0}));if(e.rw)return this._restartRewoven(e),e.rw.promise;let t,i=new Promise(s=>{t=s}),r=V();return e.rw={promise:i,resolve:t,calledAt:r,at:r,stereo:!1,box:xi(e.canvas)},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=xi(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=V(),e.rw.stereo=!1)}_settleRewoven(e,t,i){let r=e.rw;r&&(e.rw=null,r.resolve(Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(V()-r.calledAt)})))}_bindLifecycle(){typeof window>"u"||(this._onPageHide=()=>this._suspend(),this._onPageShow=e=>this._resume(!!(e&&e.persisted)),window.addEventListener("pagehide",this._onPageHide),window.addEventListener("pageshow",this._onPageShow),typeof document<"u"&&"onfreeze"in document&&(this._onFreeze=()=>this._suspend(),this._onResume=()=>this._resume(!0),document.addEventListener("freeze",this._onFreeze),document.addEventListener("resume",this._onResume)))}_unbindLifecycle(){typeof window>"u"||(this._onPageHide&&window.removeEventListener("pagehide",this._onPageHide),this._onPageShow&&window.removeEventListener("pageshow",this._onPageShow),this._onFreeze&&typeof document<"u"&&(document.removeEventListener("freeze",this._onFreeze),document.removeEventListener("resume",this._onResume)),this._onPageHide=this._onPageShow=this._onFreeze=this._onResume=null,this._frameWatchdog&&(clearTimeout(this._frameWatchdog),this._frameWatchdog=null))}_suspend(){if(!this._running||this._suspended)return;let e=[];for(let t of this._windows.values())t.layer&&(e.push(t),this._deactivate(t));this._suspended=e}_resume(e){if(!this._running)return;let t=this._suspended;if(this._suspended=null,t)for(let i of t)this._windows.has(i.canvas)&&(this._lazy&&this._observer?(this._observer.unobserve(i.observeEl),this._observer.observe(i.observeEl)):this._activate(i));this._lastChromeScan=0,this._scanChrome(),this._armDprWatch(),e&&this._watchForStalledFrames()}_watchForStalledFrames(){if(this._frameWatchdog||typeof setTimeout!="function")return;let e=this._frameCount;this._frameWatchdog=setTimeout(()=>{this._frameWatchdog=null,!(!this._running||this._frameCount!==e)&&this._requestFrame(!0)},1e3)}_teardown(){if(this._running){this._running=!1,U===this&&(U=null),this._unbindLifecycle(),this._disarmDprWatch(),this._disarmModeSwitchTick(),this._modeSwitch.cancel(),this._msArmedUp=!1,this._settlePendingDown("closed","the inline-3D session closed first"),this._observer&&this._observer.disconnect();for(let e of this._windows.values()){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"session-ended")}this._windows.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function tr(n){return typeof n=="number"&&Number.isFinite(n)&&n>=0?n:Bn}function ir(n){return typeof n!="string"?Promise.resolve(n):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=n})}function Pe(n,e,t,i,r,s,o,a,l,c,p,f){p>0&&n.roundRect?(n.save(),n.beginPath(),n.roundRect(o,a,l,c,p),n.clip(),n.drawImage(e,t,i,r,s,o,a,l,c),n.restore()):n.drawImage(e,t,i,r,s,o,a,l,c),f>0&&Ci(n,o,a,l,c,f)}function nr(n,e,t,i,r,s,o,a,l){n.save(),a>0&&n.roundRect&&(n.beginPath(),n.roundRect(r,0,r,s,a),n.clip()),n.drawImage(e,0,0,t,i,r,0,r,s),o>0&&(n.globalAlpha=o,n.drawImage(e,t,0,t,i,r,0,r,s)),n.restore(),l>0&&Ci(n,r,0,r,s,l)}function Ci(n,e,t,i,r,s){let o=Math.min(s,Math.floor(Math.min(i,r)/2));if(o<=0)return;n.save(),n.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+r-o,i,o,[e,t+r],[e,t+r-o]],[e,t,o,r,[e,t],[e+o,t]],[e+i-o,t,o,r,[e+i,t],[e+i-o,t]]];for(let[l,c,p,f,h,d]of a){let m=n.createLinearGradient(h[0],h[1],d[0],d[1]);m.addColorStop(0,"rgba(0,0,0,1)"),m.addColorStop(1,"rgba(0,0,0,0)"),n.fillStyle=m,n.fillRect(l,c,p,f)}n.restore()}function se(n,e){return n>0&&e>0&&n/e>2.5}function X(n,e,t,i,r){let s=Math.abs(i||0),o=Math.min(n-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(n-o)/2+(r===0?i:-i);return{sx:Math.max(0,Math.min(n-o,l)),sy:(e-a)/2,sw:o,sh:a}}function be(n,e,t){let i=Math.min(n,e*t),r=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(r/2)*2)}}function oe(n,e){let t=n/2;return[{src:"R",sx:t,sw:t,sy:0,sh:e,dx:0,dw:t,mirror:!0},{src:"L",sx:0,sw:t,sy:0,sh:e,dx:t,dw:t,mirror:!0}]}function yt(n,e,t){let i=new n.constructor(n.length);for(let r of oe(e,t))for(let s=0;s<t;s++)for(let o=0;o<r.dw;o++){let a=r.sx+(r.sw-1-o);i[s*e+r.dx+o]=n[s*e+a]}return i}function Ri(n,e){return!(n>0)||!(e>0)||e>=180?null:n/2/Math.tan(e/2*Math.PI/180)}function je({eyeWidthPx:n,hfovDeg:e,baselineMm:t,subjectZmm:i}){let r=Ri(n,e);return r===null||!(t>0)||!(i>0)?0:r*t/(2*i)}function We(n,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,n||0))}function Ne(n,e,t=.2){let i=n+t*(e-n);return Math.abs(e-i)<.05?e:i}function xe(){let n={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=n.measuredPx!==null?n.measuredPx/2:n.hello&&n.subjectZmm?je({eyeWidthPx:e,hfovDeg:n.hello.hfovDeg,baselineMm:n.hello.baselineMm,subjectZmm:n.subjectZmm}):0;return We(t+n.depth*.05*e,e)},step(e){return n.current=Ne(n.current,n.target(e)),n.current}};return n}var ze=1,wt="inline3d-call/1",Di=Object.freeze(["sbs","mono"]),ae=4,Li=4,bt=5,rr=150,sr=5e3,or=/^[A-Za-z0-9_-]{16,64}$/,ar=16;function xt(n){let e=new Uint8Array(ar);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ii(e)}function Ai(n){let e=new Uint8Array(8);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ii(e)}function Ii(n){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<n.length;i+=3){let s=n[i]<<16|n[i+1]<<8|n[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let r=n.length-i;if(r===1){let s=n[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(r===2){let s=n[i]<<16|n[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function le(n){return typeof n=="string"&&or.test(n)}function Se(n){if(!n)return null;let e="";if(typeof n=="object")e=n.hash||n.href&&String(n.href).split("#")[1]||"";else{let t=String(n),i=t.indexOf("#");e=i>=0?t.slice(i+1):t.includes("=")&&!t.includes("://")?t:""}e=e.replace(/^#/,"");for(let t of e.split("&")){let i=t.indexOf("=");if(i<0||decodeURIComponent(t.slice(0,i))!=="room")continue;let r=decodeURIComponent(t.slice(i+1));return le(r)?r:null}return null}function He(n,e){if(!le(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(n||"").split("#")[0]}#room=${e}`}function St(n){if(!n||typeof n!="object"||n.type!=="hello")return null;let e=(t,i,r)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=r?t:null;return{type:"hello",v:typeof n.v=="number"?n.v:ze,format:Di.includes(n.format)?n.format:"mono",width:e(n.width,1,16384),height:e(n.height,1,16384),baselineMm:e(n.baselineMm,1,1e3),hfovDeg:e(n.hfovDeg,5,170),rectified:n.rectified===!0,sdk:typeof n.sdk=="string"?n.sdk.slice(0,64):null}}function Mt({format:n,width:e,height:t,baselineMm:i,hfovDeg:r,rectified:s}={}){let o={type:"hello",v:ze,format:Di.includes(n)?n:"mono",width:e||0,height:t||0,rectified:!!s,sdk:wt};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(r)&&(o.hfovDeg=r),o}function Et(n){if(!n||n.type!=="hint")return null;let e=n.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=rr&&e<=sr?{type:"hint",subjectZmm:e}:null}function Oi(n){return!n||n.type!=="state"?null:{type:"state",muted:n.muted===!0,cameraOff:n.cameraOff===!0,speaking:n.speaking===!0}}function kt(n){let e=1e3/n,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function Tt({format:n,woven:e,mono3D:t="auto",lift:i=!1,overBudget:r=!1,failed:s=!1}){return(n==="sbs"?"sbs":"mono")==="sbs"?{route:e?"woven-sbs":"flat-left"}:e?t==="off"||t===!1?{route:"flat",mono3d:"off"}:i?s?{route:"flat",mono3d:"failed"}:r?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function Ct(n){return n==="woven-sbs"?"3D":n==="lifted"?"2D\u21923D":"2D"}function Rt({need:n=10,needNoPose:e=30}={}){let t=0,i=0,r=!1;return{feed(s){return r?!0:(i++,s===null?r=i>=e:(t=s>=1?t+1:0,r=t>=n),r)},get live(){return r}}}function Ve(n,e){let t=Math.max(1,e|0),r=n==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return r[Math.min(t,r.length)-1]}function B(n,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let r=Math.min(t,e*Math.pow(2,Math.max(0,n)));return Math.round(r*(.8+.4*i()))}var Me=Object.freeze(["VP9","VP8","AV1"]);function cr(n,e=Me){let t=e.indexOf(String(n||"").toUpperCase());return t<0?e.length:t}function $e(n,e=Me){let t=i=>cr(String(i.mimeType||"").split("/")[1],e);return n.map((i,r)=>({c:i,i:r,r:t(i)})).sort((i,r)=>i.r-r.r||i.i-r.i).map(i=>i.c)}function Ee(n,e=Me){if(!n)return n;let t=n.includes(`\r
|
|
1
|
+
/* @displayxr/inline3d 1.33.1 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
|
|
2
|
+
var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),Cn=["high","normal","low","paused"],Rn=.02,Dn=1e3/20,Ln=3e3,An=1e3/28;function ye(n){return typeof n=="function"?n:n===!1||n==="off"?"off":"auto"}function it(n=import.meta.url){return ge?typeof ge=="function"?ge():ge:new URL("../lift/index.js",n).href}var ge=null;function ii(n){ge=n||null}function In(){return import(it())}async function nt(n,{importer:e=In,nav:t=globalThis.navigator,log:i=null,capsOpts:r={webFallback:!0}}={}){let s=(h,d)=>i&&i(h,d),o=(h,d={})=>(s("lift-unavailable",{reason:h,...d}),{lift:null,capabilities:null,caps:null,source:"none",reason:h}),a=ye(n);if(a==="off")return{lift:null,capabilities:null,caps:null,source:"none",reason:"off"};if(typeof a=="function"){let h=typeof a.liftCapabilities=="function"?a.liftCapabilities:null;return{lift:a,capabilities:h,caps:null,source:"injected",reason:null}}let l;try{l=await e()}catch(h){return o("import-failed",{message:String(h&&h.message||h).slice(0,200)})}let c=l&&typeof l.lift=="function"?l.lift:null;if(!c)return o("no-lift-export");let p=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,f=null;if(p){try{f=await p(r)}catch{f=null}let h=!!(f&&f.webFallback&&f.webFallback.webgpu);if(f&&!f.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(f&&f.native),provider:f&&f.provider||null}),{lift:c,capabilities:p,caps:f,source:"module",reason:null}}function ve(n){let e=Number.isFinite(+n)&&n!==null?Math.max(-1,Math.min(1,+n)):0;return Math.abs(e)<Rn?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Le({id:n,speakerId:e,visible:t=!0}){return t?n!=null&&n===e?_e.speaker:_e.other:_e.hidden}function rt(n,e){if(!n||!Cn.includes(e)||typeof n.setPriority!="function")return!1;try{return n.setPriority(e)!==!1}catch{return!1}}function st({degradedMs:n=Dn,recoveredMs:e=An,holdMs:t=Ln,alpha:i=.1}={}){let r=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(r=r===null?a:r+i*(a-r),o){if(r<e)return o=!1,s=0,"recovered"}else if(s=r>n?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){r=null,s=0,o=!1},get frameMs(){return r},get degraded(){return o}}}function ot({lift:n,max:e=4,log:t=null,options:i=null}={}){let r=i&&typeof i=="object"?i:{},s=new Map,o=null,a=0,l=0,c=(h,d)=>t&&t(h,d),p=(h,d)=>{if(!d.handle)return;let m=Le({id:h,speakerId:o,visible:d.visible});if(m===d.priority)return;d.priority=m;let u=rt(d.handle,m);c("lift-priority",{peer:h,priority:m,applied:u})},f={get size(){return s.size},get max(){return e},set max(h){e=Math.max(0,h|0)},has:h=>s.has(h),handle:h=>s.get(h)&&s.get(h).handle||null,priority:h=>s.get(h)&&s.get(h).priority||null,canAcquire:h=>s.has(h)||s.size<e,acquire(h,d,{wall:m,visible:u=!0,onError:v}={}){let y=s.get(h);if(y)return y.pending||Promise.resolve(y.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,C=Le({id:h,speakerId:o,visible:u}),x={gen:b,handle:null,visible:u,priority:C,pending:null};s.set(h,x);let O={quality:"auto",...r,mode:"live",wall:m,ui:"none",convergence:ve(a),priority:C};return c("lift-acquire",{peer:h,priority:C,convergence:O.convergence}),x.pending=Promise.resolve().then(()=>n(d,O)).then(T=>{if(s.get(h)!==x||x.gen!==b){try{T&&T.remove&&T.remove()}catch{}return null}return x.pending=null,x.handle=T||null,x.priority=null,p(h,x),T&&typeof T.setConvergence=="function"&&T.setConvergence(ve(a)),x.handle},T=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(T&&T.message||T).slice(0,200)}),v&&v(T),null)),x.pending},release(h){let d=s.get(h);if(d){if(s.delete(h),d.handle)try{d.handle.remove()}catch{}c("lift-release",{peer:h})}},releaseAll(){for(let h of[...s.keys()])f.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,m]of s)p(d,m)},setVisible(h,d){let m=s.get(h);!m||m.visible===!!d||(m.visible=!!d,p(h,m))},setDepth(h){a=h;let d=ve(h);for(let m of s.values())m.handle&&typeof m.handle.setConvergence=="function"&&m.handle.setConvergence(d);return d},get anyWeb(){for(let h of s.values())if(h.handle&&!h.handle.native)return!0;return!1},list(){return[...s].map(([h,d])=>({id:h,priority:d.priority,pending:!!d.pending,native:!!(d.handle&&d.handle.native)}))}};return f}var Pn=null;function ni(n){Pn=typeof n=="function"?n:null}var Fn=new WeakMap;function ri(n,e){n&&(typeof n=="object"||typeof n=="function")&&Fn.set(n,e)}var jn=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063});function si(n,e,t=1){let i=jn,r=!!n&&n.displayWidthMeters>0&&n.displayHeightMeters>0&&n.displayPixelWidth>0&&n.displayPixelHeight>0,s=r?[n.displayWidthMeters,n.displayHeightMeters]:[...i.displaySizeM],o=r?[n.displayPixelWidth,n.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=r?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),p=n?.nominalViewerPosition?.z,f=Number.isFinite(p)&&p>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:f?p:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:r?"display":"default",viewer:f?"display":"default",eyeSeparation:"default"}}}var oi=new WeakMap,J;function ai(n){let e=null;for(let[t,i]of n)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function Wn(n){if(!n||typeof n.getParameter!="function")return null;let e=oi.get(n);if(e)return e;let t,i,r;try{t=n.getParameter(n.MAX_TEXTURE_SIZE??3379),i=n.getParameter(n.MAX_RENDERBUFFER_SIZE??34024),r=n.getParameter(n.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=r&&r.length>=2?r[0]:0,o=r&&r.length>=2?r[1]:0,a=ai([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=ai([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",o]]);if(!a||!l)return null;let c={maxW:a[1],maxH:l[1],nameW:a[0],nameH:l[0],valueW:a[1],valueH:l[1]};return oi.set(n,c),c}function li(){if(J!==void 0)return J;J=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return J;let n=document.createElement("canvas"),e=n.getContext("webgl2")||n.getContext("webgl");if(!e)return J;J=Wn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function ci(n,e,t,{cols:i=2,rows:r=1}={}){let s=n*i,o=e*r,a={eyeW:n,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(n>0)||!(e>0))return a;let l=t.maxW/s,c=t.maxH/o,p=Math.min(l,c);if(!(p<1))return a;let f=l<=c,h=Math.max(1,Math.min(Math.floor(n*p+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*p+1e-9),Math.floor(t.maxH/r)));return{eyeW:h,eyeH:d,cols:i,scale:p,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*r,limitName:f?t.nameW:t.nameH,limitValue:f?t.valueW:t.valueH}}function at(n){return Math.round(n*1e3)/1e3}function di(n,e,t){let i=typeof t=="number"?` (renderScale ${at(t)} \u2192 ${at(t*e.scale)})`:` (scale ${at(e.scale)})`;return`${n} ${e.cols===1?"buffer":"SBS buffer"} ${e.reqW}\xD7${e.reqH} exceeds ${e.limitName} ${e.limitValue} on this device; rendering at ${e.bufW}\xD7${e.bufH}${i}.`}function hi(n,e){let t=n?.width||0,i=n?.height||0,r=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?r/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:r,h:s,mismatch:o!==1||a!==1}}function fi(n,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${n} the browser clamped this canvas's drawing buffer to ${t.w}\xD7${t.h} (canvas.width/height say ${e.width}\xD7${e.height}); ${i}`}var ie="smoothstep",ct=["linear","smoothstep","easeoutcubic"];function dt(n){if(typeof n!="string")return null;let e=n.toLowerCase().replace(/[-_\s]/g,"");return ct.includes(e)?e:null}function Nn(n,e){if(e<=0)return 0;if(e>=1)return 1;if(n==="linear")return e;if(n==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var te="idle",ui="rampDownThenFire",lt="fireThenRampUp",Ae=class{constructor(e,t){this._phase=te,this._targetMode=null,this._firePending=!1,this._fireAtEnd=!1,this._from=0,this._to=0,this._cur=0,this._t=1,this._dur=180/1e3,this._easing=ie,(e!==void 0||t!==void 0)&&this.configure(e,t)}configure(e,t){if(e!==void 0){let i=Number(e);this._dur=Number.isFinite(i)&&i>0?i:0}return t!==void 0&&(this._easing=dt(t)||ie),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:r,current:s,steady:o=1}={}){let a=!(t>1),l=!(r>1),c=Number.isFinite(o)?o:1,p=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=p,a&&!l?(this._phase=ui,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=lt,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=lt,this._to=a?p:c,this._firePending=!(e!==null&&e===i),this._fireAtEnd=!1),this._t=this._dur>0?0:1,this._cur=this._from,this}update(e){let t=!1;if(this._phase!==te){let i=Number.isFinite(e)&&e>0?e:0;this._t<1&&this._dur>0?(this._t+=i/this._dur,this._t>1&&(this._t=1)):this._t=1,this._cur=this._from+(this._to-this._from)*Nn(this._easing,this._t),this._phase===lt?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=te)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=te)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==te}value(){return this._cur}firePending(){return this._phase===ui?this._fireAtEnd:this._firePending}cancel(){return this._phase=te,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var U=null;ni(n=>{let e=U;if(!e||!e._running||!n)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===n&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof n.contains=="function"&&n.contains(i.canvas))return t(i);for(let i of e._windows.values()){let r=i.canvas.parentElement;if(i.layer&&r&&typeof r.contains=="function"&&r.contains(n))return t(i)}return null});var zn=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Ie=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,ht=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Hn=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Si=["renderingmodechange","hardwaredisplaystatechange"],gt="trackingstatechange",Mi=["unknown","tracking","searching"],mi=[...Si,gt];function Oe(n){try{let e=n?n.trackingState:void 0;return Mi.includes(e)?e:null}catch{return null}}var ft=()=>{if(!Q())return!1;try{let n=window.XRDisplayLayer.prototype;return Hn.every(e=>typeof n[e]=="function")}catch{return!1}},ut=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},re=null;function ne(){if(re!==null)return re;if(!Q())return!1;try{let n=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof n=="boolean")return re=n}catch{}return!1}function Vn(n){if(re!==null)return re;if(!n||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return re=!!n.occlusionByDrawOrder}catch{return null}}var gi=!1;function pt(){gi||(gi=!0,console.info("[inline3d] This browser composites 2D over woven 3D automatically, per-pixel by draw order \u2014 overlay exclusion is obsolete here, so exclude()/addGlobalOverlay()/data-inline3d-overlay/autoChrome are accepted and ignored. Your 2D chrome already occludes the tiles correctly. The calls are harmless (keep them if you also ship to older DisplayXR Browsers); gate on inline3dOcclusionByDrawOrder() to drop them."))}function Ei(){return zn()&&Q()}function mt(n){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:n.virtualDisplayHeight>0?n.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function $n(n,e){let t=Number.isFinite(n.ipdFactor)?n.ipdFactor:1,i=Number.isFinite(n.parallaxFactor)?n.parallaxFactor:1;return{...n,ipdFactor:t*e,parallaxFactor:i*e}}var Un=16;function V(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Bn=1200,_i=!1;function qn(n){if(n==null)return ie;let e=dt(n);return e||(_i||(_i=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(n)} } }) is not a curve this SDK knows (${ct.join(" / ")}); using '${ie}'.`)),ie)}var vi=!1;function Xn(){vi||(vi=!0,console.info("[inline3d] The active rendering mode is 1-view, so this SDK has zeroed every window rig (ipdFactor/parallaxFactor -> 0) \u2014 both eyes now render from one place. The runtime keeps weaving the same two-view atlas whatever the page submits, so leaving stereo in it would put two slightly different images on a flat panel, i.e. a blurry double image instead of 2D. Your rendering is unchanged; the flattening is a copy applied on the way to the layer and it is undone the moment a 2-view mode goes active again."))}function _t(n){return n&&n.detail!==void 0&&n.detail!==null?n.detail:void 0}function ki(n){let e=_t(n);return e!==void 0?[e,n]:[n]}function Gn(n){for(let e of ki(n)){if(typeof e=="number"&&Number.isFinite(e))return e;if(e&&typeof e=="object"){let t=e.modeIndex!==void 0?e.modeIndex:e.mode;if(typeof t=="number"&&Number.isFinite(t))return t}}return-1}function Jn(n){for(let e of ki(n)){if(e==="2d"||e==="3d")return e;if(e&&typeof e=="object"){let t=e.state!==void 0?e.state:e.hardwareDisplayState;if(t==="2d"||t==="3d")return t}}return null}var yi=!1;function Kn(){yi||(yi=!0,console.warn("[inline3d] This browser has no XRDisplayLayer.setViewRig, so the view rig was ignored (the window still weaves \u2014 the runtime keeps the default display rig, scaled by virtualDisplayHeight). Gate on inline3dViewRigSupported() if your page's framing depends on the rig; further calls are silent."))}var wi=!1;function Yn(){wi||(wi=!0,console.warn("[inline3d] addScene got BOTH viewRig and virtualDisplayHeight; on a browser with rig support the rig wins and the height is dropped. They describe the same slot \u2014 virtualDisplayHeight is shorthand for exactly one rig (display, identity pose, all factors 1) \u2014 so there is no merge. This is only worth passing as a PAIR deliberately: the height is what a browser without setViewRig will use, so a camera-rig scene can name its own fallback framing. Otherwise say it once, inside the rig."))}async function Ti(n={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:r=!0,modeSwitch:s=null,untrackedFallback:o="none",viewerEase:a}=n;if(!Ei())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(p){return{supported:!1,trackingState:"unknown",error:p}}a!==void 0&&ri(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new vt(l,c,{lazy:t,rootMargin:i,autoChrome:r,modeSwitch:s,untrackedFallback:o})}var we=null;function Fe(n={}){return U&&U._running?Promise.resolve(U):we||(we=Ti(n).finally(()=>{we=null}),we)}var bi=.7,Zn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Qn(n){let e=[],t=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(Zn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let r of i.childNodes)if(r.nodeType===Node.TEXT_NODE&&r.nodeValue.trim()){e.push(i);break}}return e}var er=4;function xi(n){let e=typeof window<"u"&&window.devicePixelRatio||1;return`${n.clientWidth}x${n.clientHeight}@${e}`}var vt=class{constructor(e,t,{lazy:i,rootMargin:r,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._globalOverlays=new Set,this._isolatedBy=new WeakMap,this._autoChrome=s,this._autoChromeEls=new Set,this._lastChromeScan=0,this._fullTileWarned=new WeakSet,this._stoodDown=!1,this._activeModeIndex=-1,this._activeViewCount=0,this._hardwareDisplayState=null,this._modes=null,this._stereoCollapsed=!1,this._displayListeners=new Map,this._primedDisplayState=!1;let l=o&&typeof o=="object"?o:{};this._msEnabled=l.enabled!==!1,this._modeSwitch=new Ae((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,qn(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Oe(e)!==null,this._trackingState=this._trackingSupported?Oe(e):"unknown",this._untrackedFallback=a==="mono"?"mono":"none",this._bakedStereo=1,this._bakedTarget=1,this._bakedAt=null,this._bakedEaseS=(Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,this._applyUntrackedTarget(),this.undock=ut()?{model:!1,splat:!1}:null,this._undockRead=!1,this._running=!0,this._lazy=i,this._observer=i&&typeof IntersectionObserver=="function"?new IntersectionObserver(c=>this._onIntersect(c),{rootMargin:r}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,U&&U._running&&U!==this&&console.warn("[inline3d] A second inline-3D session is live in this document. The browser's element-rect channel is a whole-widget setter, so both managers clobber each other's rect list every frame \u2014 tiles may flicker, ghost, or weave at a stale rect. Use ONE createInline3D() per document and add every window to it; if you are switching views, close() the previous manager first."),U=this,e.addEventListener("end",()=>this._teardown()),this._bindDisplayEvents(),this._bindTrackingEvents(),this._scanChrome(),this._bindLifecycle(),this._armDprWatch(),this._requestFrame()}get liveCount(){let e=0;for(let t of this._windows.values())t.layer&&e++;return e}addGlobalOverlay(e){if(!(!e||this._globalOverlays.has(e))){ne()&&pt(),this._globalOverlays.add(e);for(let t of this._windows.values())t.layer&&this._applyExclusion(t,e)}}removeGlobalOverlay(e){if(!(!e||!this._globalOverlays.delete(e)))for(let t of this._windows.values())t.layer&&this._dropExclusion(t,e)}_scanChrome(){if(ne()||!this._autoChrome||!Ie()||typeof document>"u")return;let e=Date.now();if(e-this._lastChromeScan<1e3)return;this._lastChromeScan=e;let t=document.body;if(!t)return;let i=new Set,r=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of r){if(s.closest("[data-inline3d-no-overlay]"))continue;let o=getComputedStyle(s).position;if(o!=="fixed"&&o!=="sticky")continue;let a=!1;for(let l of this._windows.keys())if(s===l||s.contains(l)){a=!0;break}if(!a){i.add(s);for(let l of Qn(s))i.add(l)}}for(let s of this._autoChromeEls){let o=!1;if(s.isConnected){for(let a of this._windows.keys())if(s===a||s.contains(a)){o=!0;break}}(!s.isConnected||o)&&(this._autoChromeEls.delete(s),this.removeGlobalOverlay(s))}for(let s of i)this._globalOverlays.has(s)||(this._autoChromeEls.add(s),this.addGlobalOverlay(s))}addImage(e,t,i={}){let r=this._register(e,"image",i);return r.ready=ir(t).then(s=>{r.img=s,r.repaint()}),this._handle(e,r)}addVideo(e,t,i={}){let r=this._register(e,"video",i);return r.video=t,this._handle(e,r)}addScene(e,t,i={}){i.viewRig&&i.virtualDisplayHeight!==void 0&&Yn();let r=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return r.onFrame=t,r.ownsBuffer=!1,i.bufferClamped===!0&&(r.warnedBufMismatch=!0),this._handle(e,r)}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:r=>{r&&(ne()&&pt(),t.excluded.add(r),this._applyExclusion(t,r))},unexclude:r=>{!r||!t.excluded.delete(r)||this._dropExclusion(t,r)},get trackingState(){return i._trackingState},setViewRig:r=>(t.viewRig=r||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let r=null;try{r=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return si(r,e.getBoundingClientRect(),globalThis.devicePixelRatio||1)},getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:r=>this._requestRenderingModeEased(r,t),setStereoEnabled:r=>this._setStereoEnabled(r,t),on:(r,s)=>this.on(r,s),off:(r,s)=>this.off(r,s),onDisplayModeChange:r=>this._onDisplayModeChange(r),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get firstWoven(){return t.fwPromise},onFirstWoven:r=>{if(typeof r!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{r(o)}catch(a){console.error("[inline3d] onFirstWoven callback threw",a)}}),()=>{s=!1}},rewoven:()=>this._rewoven(t)}}getDisplayInfo(){return this._layerCall(this._liveWindow(null),"getDisplayInfo","getDisplayInfo()")}getRenderingModes(){return this._getRenderingModes(null)}requestRenderingMode(e){return this._requestRenderingModeEased(e,null)}setStereoEnabled(e){return this._setStereoEnabled(e,null)}get trackingState(){return this._trackingState}get hardwareDisplayState(){return this._hardwareDisplayState}get activeMode(){return{modeIndex:this._activeModeIndex,viewCount:this._activeViewCount}}get stereoCollapsed(){return this._stereoCollapsed}get modeSwitch(){return{active:this._msTransitionActive(),factor:this._stereoFactor}}close(){try{this.session.end()}catch{}this._teardown()}_effectiveViewRig(e){return this._stereoFactor>=1?e.viewRig||(e.stereoSynthRig?mt(e):null):(e.viewRig||(e.stereoSynthRig=!0),$n(e.viewRig||mt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&Xn(),!t&&this._msArmedUp?(this._msArmedUp=!1,this._startUpRamp()):this._modeSwitch.active()||(this._stereoFactor=t?0:1);for(let i of this._windows.values()){if(t){let r=i.viewRig||mt(i);i.stereoSaved={ipdFactor:r.ipdFactor,parallaxFactor:r.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!ht())return Kn(),!1;if(!e.layer)return!1;let t=this._effectiveViewRig(e);try{return e.layer.setViewRig(t),!0}catch{return!1}}_layerCall(e,t,i,r=[]){if(!ft())return Promise.reject(new Error(`[inline3d] ${i} needs a DisplayXR Browser with the display-mode API (XRDisplayLayer.getDisplayInfo/getRenderingModes/requestRenderingMode). Gate on inline3dDisplayModesSupported().`));if(!e||!e.layer)return Promise.reject(new Error(`[inline3d] ${i} needs a live weave layer, and this window has none right now (lazy mode closes the layer while the tile is off screen). Call it once the tile is visible, or create the manager with { lazy: false }.`));try{return Promise.resolve(e.layer[t](...r))}catch(s){return Promise.reject(s)}}_liveWindow(e){if(e&&e.layer)return e;for(let t of this._windows.values())if(t.layer)return t;return e||null}async _getRenderingModes(e){let t=await this._layerCall(this._liveWindow(e),"getRenderingModes","getRenderingModes()"),i=Array.isArray(t)?t:[];this._modes=i;let r=i.find(s=>s.isActive);return r&&(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount,(r.viewCount===1||r.viewCount===2)&&this._setStereoCollapsed(r.viewCount===1)),this._primedDisplayState=!0,t}_requestRenderingMode(e,t){return this._layerCall(this._liveWindow(t),"requestRenderingMode","requestRenderingMode()",[e])}_msTransitionActive(){return this._modeSwitch.active()||this._msArmedUp||this._msFire!==null}async _requestRenderingModeEased(e,t){if(!this._msEnabled||!ht())return this._requestRenderingMode(e,t);let i=this._modes;if(!Array.isArray(i)||i.length===0)try{i=await this._getRenderingModes(t)}catch{i=null}let r=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=r&&Number.isFinite(r.viewCount)?r.viewCount:0,o=this._activeViewCount;return s<1||s>2||o<1?this._requestRenderingMode(e,t):s===1?o===1?this._requestRenderingMode(e,t):this._rampDownThenRequest(e,t):this._requestThenRampUp(e,t)}_rampDownThenRequest(e,t){if(this._msFire&&this._msFire.modeIndex===e)return this._msFire.promise;this._settlePendingDown("superseded",`a request for mode ${e} replaced it`);let i={modeIndex:e,win:t,resolve:null,reject:null,promise:null};return i.promise=new Promise((r,s)=>{i.resolve=r,i.reject=s}),this._msFire=i,this._modeSwitch.request({targetMode:e,targetViewCount:1,currentMode:this._activeModeIndex,currentViewCount:this._activeViewCount,current:this._stereoFactor,steady:1}),this._msLastMs=V(),this._armModeSwitchTick(),i.promise}_requestThenRampUp(e,t){let r=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=r?Promise.resolve(void 0):this._requestRenderingMode(e,t);return this._stereoFactor<1&&(this._stereoCollapsed?(this._msArmedUp=!0,this._modeSwitch.cancel(),this._stereoFactor=0):this._startUpRamp()),s.catch(o=>{throw this._msArmedUp&&(this._msArmedUp=!1,this._modeSwitch.active()||(this._stereoFactor=this._stereoCollapsed?0:1)),o})}_startUpRamp(){this._settlePendingDown("superseded","the display returned to 3D"),this._modeSwitch.request({targetMode:this._activeModeIndex,targetViewCount:2,currentMode:this._activeModeIndex,currentViewCount:2,current:this._stereoFactor,steady:1}),this._msLastMs=V(),this._armModeSwitchTick()}_settlePendingDown(e,t){let i=this._msFire;if(!i)return;this._msFire=null;let r=new Error(`[inline3d] the request for rendering mode ${i.modeIndex} was never forwarded: ${t}. A ->2D switch is held until the disparity has ramped out, so a request that is reversed or replaced in that window is dropped rather than fired late.`);r.name=e,i.reject(r)}_advanceModeSwitch(){if(!this._modeSwitch.active()){this._msLastMs=null,this._disarmModeSwitchTick();return}let e=V(),t=typeof this._msLastMs=="number"?Math.max(0,(e-this._msLastMs)/1e3):0;this._msLastMs=e;let i=this._modeSwitch.update(t);if(i.factor!==this._stereoFactor){this._stereoFactor=i.factor;for(let r of this._windows.values())this._pushViewRig(r)}if(i.fire&&this._msFire){let r=this._msFire;this._msFire=null,this._requestRenderingMode(r.modeIndex,r.win).then(s=>r.resolve(s),s=>{this._startUpRamp(),r.reject(s)})}this._modeSwitch.active()||(this._msLastMs=null,this._disarmModeSwitchTick())}_armModeSwitchTick(){this._msTick!==null||typeof setTimeout!="function"||(this._msTick=setTimeout(()=>{this._msTick=null,this._running&&(this._advanceModeSwitch(),this._modeSwitch.active()&&this._armModeSwitchTick())},Un))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,r=await this._getRenderingModes(t),s=Array.isArray(r)?r:[],o=s.find(a=>a.viewCount===i&&a.isRequestable);if(!o)throw new Error(`[inline3d] setStereoEnabled(${!!e}) found no requestable ${i}-view mode on this display (${s.length} mode(s) listed). It is sugar over requestRenderingMode() and cannot invent one \u2014 read getRenderingModes() and drive the list yourself.`);return o.isActive&&!this._msTransitionActive()||await this._requestRenderingModeEased(o.modeIndex,t),!!e}_bindDisplayEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||ft()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=Jn(e),i=_t(e),r=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&r(t);let s=this._activeModeIndex,o=this._activeViewCount;return this._getRenderingModes(null).then(a=>{let l=(Array.isArray(a)?a:[]).find(c=>c.isActive)||null;if(l&&(l.modeIndex!==s||l.viewCount!==o)&&this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:l,detail:null}),!t){let c=l&&typeof l.hardwareDisplay3D=="boolean"?l.hardwareDisplay3D?"3d":"2d":null;r(c)}}).catch(()=>{t||r(null)})}async _onRenderingModeChange(e){let t=_t(e),i=Gn(e),r=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];r=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}r?(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount):i>=0&&(this._activeModeIndex=i),(this._activeViewCount===1||this._activeViewCount===2)&&this._setStereoCollapsed(this._activeViewCount===1),this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:r,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let r=t||[e];for(let s of[...i])try{s(...r)}catch(o){console.error(`[inline3d] ${e.type} listener threw`,o)}}on(e,t){if(typeof t!="function")throw new TypeError("[inline3d] on() takes (type, function).");if(!mi.includes(e))throw new TypeError(`[inline3d] on() knows ${mi.join(" / ")}, got ${JSON.stringify(e)}.`);let i=this._displayListeners.get(e);return i||this._displayListeners.set(e,i=new Set),i.add(t),()=>this.off(e,t)}off(e,t){let i=this._displayListeners.get(e);i&&i.delete(t)}_onDisplayModeChange(e){if(typeof e!="function")throw new TypeError("[inline3d] onDisplayModeChange() takes a function.");let t=Si.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!ut())return this.undock=null;let e=this._liveWindow(null);if(!e||!e.layer||typeof e.layer.getUndockCapabilities!="function")return this.undock;try{let t=await e.layer.getUndockCapabilities();this.undock={model:!!(t&&t.model),splat:!!(t&&t.splat)}}catch{}return this.undock}_register(e,t,i){this._windows.has(e)&&this._remove(e),e.style.willChange="transform",e.style.transform="translateZ(0)";let r={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,ready:null,ownsBuffer:t!=="scene",cornerRadius:i.cornerRadius||0,feather:i.feather||0,reqW:i.width||0,reqH:i.height||0,virtualDisplayHeight:i.virtualDisplayHeight||0,viewRig:i.viewRig||null,stereoSaved:null,stereoSynthRig:!1,observeEl:i.observe||e,ctx:t==="scene"?null:e.getContext("2d"),repaint:()=>this._paint(r,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:tr(i.firstWovenHoldMs),fwRegAt:V(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null};return r.fwPromise=new Promise(s=>{r.fwResolve=s}),this._windows.set(e,r),this._lazy&&this._observer?this._observer.observe(r.observeEl):this._activate(r),r}_remove(e){let t=this._windows.get(e);t&&(this._observer&&this._observer.unobserve(t.observeEl),this._deactivate(t),this._windows.delete(e),this._settleFirstWoven(t,!1,"removed"))}_onIntersect(e){for(let t of e){let i=null;for(let r of this._windows.values())if(r.observeEl===t.target){i=r;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=ht()?this._effectiveViewRig(e):null,i=t?{viewRig:t}:e.virtualDisplayHeight>0?{virtualDisplayHeight:e.virtualDisplayHeight}:{};e.layer=new XRDisplayLayer(this.session,e.canvas,i)}catch(t){e.layer=null,e.layerFailWarned||(e.layerFailWarned=!0,console.warn("[inline3d] new XRDisplayLayer() failed for this window \u2014 it will show FLAT 2D instead of woven 3D, and the SDK will not retry. The canvas has been repainted mono so it cannot be left holding a raw side-by-side pair.",t)),this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"layer-failed");return}e.fwResult||(e.fwLayerAt=V(),e.fwStereo=!1),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&ft()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),ut()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),Vn(e.layer)===!0&&this._standDownLegacyOcclusion();for(let t of e.excluded)this._applyExclusion(e,t);for(let t of this._globalOverlays)this._applyExclusion(e,t);this._startOverlayScan(e),e.ownsBuffer&&(this._sizeBuffer(e,!0),this._paint(e,null)),this._startSizeWatch(e)}}_deactivate(e){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e)}_paintMono(e){!e.ownsBuffer||e.kind==="scene"||(this._sizeBuffer(e,!1),this._paint(e,null))}_notifyLayerLost(e){if(!(e.kind!=="scene"||typeof e.onLayerLost!="function"||e.layerLostSent)){e.layerLostSent=!0;try{e.onLayerLost()}catch(t){console.warn("[inline3d] a scene window's onLayerLost callback threw",t)}}}_isFullTileOverlay(e,t){if(!t||typeof t.getBoundingClientRect!="function")return!1;let i=t.getBoundingClientRect(),r=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=r.width*r.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,r.right)-Math.max(i.left,r.left),l=Math.min(i.bottom,r.bottom)-Math.max(i.top,r.top);if(a<=0||l<=0)return!1;let c=a*l;return c/s<bi||c/o<bi?!1:(this._fullTileWarned.has(t)||(this._fullTileWarned.add(t),console.warn("[inline3d] Refusing a full-tile overlay: this element covers its own woven canvas, and the browser's geometric matcher cannot tell the two apart \u2014 it would stage the CANVAS as the overlay and the tile would show its raw side-by-side buffer instead of 3D. Make the overlay a PARTIAL region of the tile (a caption band, a badge, a corner plate), or move it outside the tile and register it with addGlobalOverlay().",t)),!0)}_applyExclusion(e,t){if(ne()||!e.layer||!Ie()||this._isFullTileOverlay(e,t))return;let i=this._isolatedBy.get(t);if(i||(i=new Set,this._isolatedBy.set(t,i)),i.add(e),!t.dataset.inline3dIsolated){t.dataset.inline3dPriorWillChange=t.style.willChange||"";let r=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=r,t.dataset.inline3dIsolated="1"}try{e.layer.excludeElement(t)}catch{}}_dropExclusion(e,t){if(ne())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Ie()))try{e.layer.unexcludeElement(t)}catch{}}_unpromote(e){return!e||!e.dataset||!e.dataset.inline3dIsolated?!1:(e.style.willChange=e.dataset.inline3dPriorWillChange||"",delete e.dataset.inline3dPriorWillChange,delete e.dataset.inline3dIsolated,!0)}_standDownLegacyOcclusion(){if(this._stoodDown)return;this._stoodDown=!0;let e=!1;for(let t of this._windows.values()){t.overlayObserver&&(this._stopOverlayScan(t),e=!0);for(let i of t.excluded)this._unpromote(i)&&(e=!0)}for(let t of this._autoChromeEls)this._globalOverlays.delete(t),this._unpromote(t),e=!0;this._autoChromeEls.clear();for(let t of this._globalOverlays)this._unpromote(t)&&(e=!0);this._isolatedBy=new WeakMap,e&&pt()}_startOverlayScan(e){if(ne()||!Ie()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let r=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)r.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of r)e.autoExcluded.has(s)||(e.autoExcluded.add(s),this._applyExclusion(e,s))};i(),e.overlayObserver=new MutationObserver(i),e.overlayObserver.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-inline3d-overlay"]})}_stopOverlayScan(e){e.overlayObserver&&(e.overlayObserver.disconnect(),e.overlayObserver=null),e.autoExcluded.clear()}_eyeSize(e,t=!0){let i=Math.min(window.devicePixelRatio||1,2),r=e.reqW||Math.round((e.canvas.clientWidth||256)*i),s=e.reqH||Math.round((e.canvas.clientHeight||256)*i),o=1,a=!e.reqW&&!e.reqH&&this._sourceEyeSize(e);if(a){let c=Math.max(a.w/r,a.h/s);c<1&&(o=c,r=Math.max(1,Math.round(r*c)),s=Math.max(1,Math.round(s*c)))}let l=ci(r,s,li(),{cols:t?2:1});return l.clamped&&(o*=l.scale,r=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(di("[inline3d]",l)))),e.bufScale=o,{w:r,h:s}}_sourceEyeSize(e){if(e.kind!=="video"&&e.kind!=="image")return null;let t=e.kind==="video"?e.video:e.img;if(!t)return null;let i=t.videoWidth||t.naturalWidth||t.width,r=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(r>0)?null:{w:i/2,h:r}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let r=null;try{r=t.getContext("webgl2")||t.getContext("webgl")}catch{r=null}e.sceneGl=r&&typeof r.drawingBufferWidth=="number"?r:null}if(!e.sceneGl)return;let i=hi(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(fi("[inline3d]",t,i,"getViewport() splits canvas.width, so the eyes are off-centre in the woven buffer. This scene canvas is sized by the page: keep 2 \xD7 eye width and the height within MAX_TEXTURE_SIZE / MAX_RENDERBUFFER_SIZE / MAX_VIEWPORT_DIMS, or map getViewport() onto gl.drawingBufferWidth/Height.")))}_sizeBuffer(e,t){let{w:i,h:r}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=r,e.canvas.width=t?i*2:i,e.canvas.height=r,e.sbs=t}_startSizeWatch(e){typeof ResizeObserver=="function"&&(e.sizeObserver||!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas)))}_stopSizeWatch(e){e.sizeObserver&&(e.sizeObserver.disconnect(),e.sizeObserver=null),e.resizePending=!1}_onBoxChange(e){if(!e.layer||!e.ownsBuffer||e.resizePending)return;e.resizePending=!0;let t=()=>{if(!e.resizePending||(e.resizePending=!1,!e.layer||!e.ownsBuffer))return;this._noteRewovenBox(e);let{w:i,h:r}=this._eyeSize(e);i===e.eyeW&&r===e.eyeH||(this._sizeBuffer(e,!0),this._paint(e,null))};typeof requestAnimationFrame=="function"?requestAnimationFrame(t):t()}_armDprWatch(){if(typeof window>"u"||typeof window.matchMedia!="function")return;this._disarmDprWatch();let e;try{e=window.matchMedia(`(resolution: ${window.devicePixelRatio||1}dppx)`)}catch{return}let t=()=>{if(this._running){this._armDprWatch();for(let i of this._windows.values())i.layer&&this._onBoxChange(i)}};try{e.addEventListener("change",t)}catch{return}this._dprWatch={q:e,onChange:t}}_disarmDprWatch(){if(this._dprWatch){try{this._dprWatch.q.removeEventListener("change",this._dprWatch.onChange)}catch{}this._dprWatch=null}}_paint(e,t){if(e.kind==="scene"||!e.ctx)return;let i=this._running&&!!e.layer;!i&&e.sbs&&this._sizeBuffer(e,!1);let r=e.kind==="video"?e.video:e.img;if(!r)return;if(e.kind==="video"&&(r.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=r.videoWidth||r.naturalWidth||r.width,l=r.videoHeight||r.naturalHeight||r.height;if(!a||!l)return;let c=a+"x"+l;if(e.srcKey!==c&&(e.srcKey=c,e.ownsBuffer&&!(e.reqW&&e.reqH))){let{w:u,h:v}=this._eyeSize(e,e.sbs);(u!==e.eyeW||v!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let p=e.bufScale||1,f=e.cornerRadius*p,h=e.feather*p;if(o.clearRect(0,0,s.width,s.height),!e.sbs){Pe(o,r,0,0,a/2,l,0,0,s.width,s.height,f,h);return}let d=s.width/2,m=Math.min(this._stereoFactor,this._bakedStereo);if(m<1){Pe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),nr(o,r,a/2,l,d,s.height,m,f,h);return}f>0||h>0?(Pe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),Pe(o,r,a/2,0,a/2,l,d,0,d,s.height,f,h)):o.drawImage(r,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(gt,()=>{this._setTrackingState(Oe(e)||"unknown")})}_setTrackingState(e){let t=Mi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:gt,state:t};this._emitDisplay(i,[t,i])}_applyUntrackedTarget(){if(this._untrackedFallback!=="mono"){this._bakedTarget=1;return}this._trackingState==="searching"?this._bakedTarget=0:this._trackingState==="tracking"&&(this._bakedTarget=1)}_trackBakedStereo(e){this._trackingSupported&&this._setTrackingState(Oe(this.session)||"unknown");let t=this._bakedAt===null||!Number.isFinite(e)?0:Math.max(0,(e-this._bakedAt)/1e3);this._bakedAt=Number.isFinite(e)?e:this._bakedAt;let i=this._bakedStereo,r=this._bakedTarget;if(i===r)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=r>i?Math.min(r,i+s):Math.max(r,i-s)}_recommitLastFrame(e){let t=e.canvas;if(!t.width||!t.height)return;let i=e.ctx;try{i.save(),i.globalCompositeOperation="copy",i.drawImage(t,0,0),i.restore()}catch{}}_requestFrame(e){if(!this._running||this._framePending&&!e)return;let t=e?++this._loopId:this._loopId;this._framePending=!0;try{this.session.requestAnimationFrame((i,r)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,r))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,r=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.kind==="scene"){if(r&&s.onFrame){if(s.frames++,r.length<2&&(s.monoFrames++,s.monoFrames%300===1&&typeof console<"u"&&console.debug)){let o=(100*s.monoFrames/Math.max(1,s.frames)).toFixed(1);console.debug(`[inline3d] scene window: ${s.monoFrames} non-stereo view lists in ${s.frames} frames (${o}%). The viewer replays its last good stereo frame for these; a rising rate means the session is falling back under load.`)}try{s.onFrame(r,s.layer,t),r.length>=2&&(s.fwStereo=!0,s.warnedBufMismatch||this._checkSceneBuffer(s),s.rw&&(s.rw.stereo=!0))}catch(o){s.frameThrewWarned||(s.frameThrewWarned=!0,console.warn("[inline3d] a scene window's onFrame threw; this window will keep whatever it last drew, and the other windows carry on. Further throws from it are silent.",o))}}}else this._paint(s,r),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.rw&&(s.rw.stereo=!0));this._tickFirstWoven(s)}}_tickFirstWoven(e){if(e.rw){this._noteRewovenBox(e);let t=e.rw,i=V();t.stereo&&i-t.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):t.at>t.calledAt&&i-t.calledAt>=er*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||V()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_settleFirstWoven(e,t,i){t||(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(V()-e.fwRegAt)}),e.fwResolve(e.fwResult),e.fwResolve=null)}_rewoven(e){if(!e.fwResult)return e.fwPromise;if(!e.fwResult.woven)return Promise.resolve(e.fwResult);if(e.rwGone)return Promise.resolve(Object.freeze({woven:!1,confirmed:!1,reason:e.rwGone,ms:0}));if(e.rw)return this._restartRewoven(e),e.rw.promise;let t,i=new Promise(s=>{t=s}),r=V();return e.rw={promise:i,resolve:t,calledAt:r,at:r,stereo:!1,box:xi(e.canvas)},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=xi(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=V(),e.rw.stereo=!1)}_settleRewoven(e,t,i){let r=e.rw;r&&(e.rw=null,r.resolve(Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(V()-r.calledAt)})))}_bindLifecycle(){typeof window>"u"||(this._onPageHide=()=>this._suspend(),this._onPageShow=e=>this._resume(!!(e&&e.persisted)),window.addEventListener("pagehide",this._onPageHide),window.addEventListener("pageshow",this._onPageShow),typeof document<"u"&&"onfreeze"in document&&(this._onFreeze=()=>this._suspend(),this._onResume=()=>this._resume(!0),document.addEventListener("freeze",this._onFreeze),document.addEventListener("resume",this._onResume)))}_unbindLifecycle(){typeof window>"u"||(this._onPageHide&&window.removeEventListener("pagehide",this._onPageHide),this._onPageShow&&window.removeEventListener("pageshow",this._onPageShow),this._onFreeze&&typeof document<"u"&&(document.removeEventListener("freeze",this._onFreeze),document.removeEventListener("resume",this._onResume)),this._onPageHide=this._onPageShow=this._onFreeze=this._onResume=null,this._frameWatchdog&&(clearTimeout(this._frameWatchdog),this._frameWatchdog=null))}_suspend(){if(!this._running||this._suspended)return;let e=[];for(let t of this._windows.values())t.layer&&(e.push(t),this._deactivate(t));this._suspended=e}_resume(e){if(!this._running)return;let t=this._suspended;if(this._suspended=null,t)for(let i of t)this._windows.has(i.canvas)&&(this._lazy&&this._observer?(this._observer.unobserve(i.observeEl),this._observer.observe(i.observeEl)):this._activate(i));this._lastChromeScan=0,this._scanChrome(),this._armDprWatch(),e&&this._watchForStalledFrames()}_watchForStalledFrames(){if(this._frameWatchdog||typeof setTimeout!="function")return;let e=this._frameCount;this._frameWatchdog=setTimeout(()=>{this._frameWatchdog=null,!(!this._running||this._frameCount!==e)&&this._requestFrame(!0)},1e3)}_teardown(){if(this._running){this._running=!1,U===this&&(U=null),this._unbindLifecycle(),this._disarmDprWatch(),this._disarmModeSwitchTick(),this._modeSwitch.cancel(),this._msArmedUp=!1,this._settlePendingDown("closed","the inline-3D session closed first"),this._observer&&this._observer.disconnect();for(let e of this._windows.values()){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"session-ended")}this._windows.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function tr(n){return typeof n=="number"&&Number.isFinite(n)&&n>=0?n:Bn}function ir(n){return typeof n!="string"?Promise.resolve(n):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=n})}function Pe(n,e,t,i,r,s,o,a,l,c,p,f){p>0&&n.roundRect?(n.save(),n.beginPath(),n.roundRect(o,a,l,c,p),n.clip(),n.drawImage(e,t,i,r,s,o,a,l,c),n.restore()):n.drawImage(e,t,i,r,s,o,a,l,c),f>0&&Ci(n,o,a,l,c,f)}function nr(n,e,t,i,r,s,o,a,l){n.save(),a>0&&n.roundRect&&(n.beginPath(),n.roundRect(r,0,r,s,a),n.clip()),n.drawImage(e,0,0,t,i,r,0,r,s),o>0&&(n.globalAlpha=o,n.drawImage(e,t,0,t,i,r,0,r,s)),n.restore(),l>0&&Ci(n,r,0,r,s,l)}function Ci(n,e,t,i,r,s){let o=Math.min(s,Math.floor(Math.min(i,r)/2));if(o<=0)return;n.save(),n.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+r-o,i,o,[e,t+r],[e,t+r-o]],[e,t,o,r,[e,t],[e+o,t]],[e+i-o,t,o,r,[e+i,t],[e+i-o,t]]];for(let[l,c,p,f,h,d]of a){let m=n.createLinearGradient(h[0],h[1],d[0],d[1]);m.addColorStop(0,"rgba(0,0,0,1)"),m.addColorStop(1,"rgba(0,0,0,0)"),n.fillStyle=m,n.fillRect(l,c,p,f)}n.restore()}function se(n,e){return n>0&&e>0&&n/e>2.5}function X(n,e,t,i,r){let s=Math.abs(i||0),o=Math.min(n-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(n-o)/2+(r===0?i:-i);return{sx:Math.max(0,Math.min(n-o,l)),sy:(e-a)/2,sw:o,sh:a}}function be(n,e,t){let i=Math.min(n,e*t),r=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(r/2)*2)}}function oe(n,e){let t=n/2;return[{src:"R",sx:t,sw:t,sy:0,sh:e,dx:0,dw:t,mirror:!0},{src:"L",sx:0,sw:t,sy:0,sh:e,dx:t,dw:t,mirror:!0}]}function yt(n,e,t){let i=new n.constructor(n.length);for(let r of oe(e,t))for(let s=0;s<t;s++)for(let o=0;o<r.dw;o++){let a=r.sx+(r.sw-1-o);i[s*e+r.dx+o]=n[s*e+a]}return i}function Ri(n,e){return!(n>0)||!(e>0)||e>=180?null:n/2/Math.tan(e/2*Math.PI/180)}function je({eyeWidthPx:n,hfovDeg:e,baselineMm:t,subjectZmm:i}){let r=Ri(n,e);return r===null||!(t>0)||!(i>0)?0:r*t/(2*i)}function We(n,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,n||0))}function Ne(n,e,t=.2){let i=n+t*(e-n);return Math.abs(e-i)<.05?e:i}function xe(){let n={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=n.measuredPx!==null?n.measuredPx/2:n.hello&&n.subjectZmm?je({eyeWidthPx:e,hfovDeg:n.hello.hfovDeg,baselineMm:n.hello.baselineMm,subjectZmm:n.subjectZmm}):0;return We(t+n.depth*.05*e,e)},step(e){return n.current=Ne(n.current,n.target(e)),n.current}};return n}var ze=1,wt="inline3d-call/1",Di=Object.freeze(["sbs","mono"]),ae=4,Li=4,bt=5,rr=150,sr=5e3,or=/^[A-Za-z0-9_-]{16,64}$/,ar=16;function xt(n){let e=new Uint8Array(ar);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ii(e)}function Ai(n){let e=new Uint8Array(8);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ii(e)}function Ii(n){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<n.length;i+=3){let s=n[i]<<16|n[i+1]<<8|n[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let r=n.length-i;if(r===1){let s=n[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(r===2){let s=n[i]<<16|n[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function le(n){return typeof n=="string"&&or.test(n)}function Se(n){if(!n)return null;let e="";if(typeof n=="object")e=n.hash||n.href&&String(n.href).split("#")[1]||"";else{let t=String(n),i=t.indexOf("#");e=i>=0?t.slice(i+1):t.includes("=")&&!t.includes("://")?t:""}e=e.replace(/^#/,"");for(let t of e.split("&")){let i=t.indexOf("=");if(i<0||decodeURIComponent(t.slice(0,i))!=="room")continue;let r=decodeURIComponent(t.slice(i+1));return le(r)?r:null}return null}function He(n,e){if(!le(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(n||"").split("#")[0]}#room=${e}`}function St(n){if(!n||typeof n!="object"||n.type!=="hello")return null;let e=(t,i,r)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=r?t:null;return{type:"hello",v:typeof n.v=="number"?n.v:ze,format:Di.includes(n.format)?n.format:"mono",width:e(n.width,1,16384),height:e(n.height,1,16384),baselineMm:e(n.baselineMm,1,1e3),hfovDeg:e(n.hfovDeg,5,170),rectified:n.rectified===!0,sdk:typeof n.sdk=="string"?n.sdk.slice(0,64):null}}function Mt({format:n,width:e,height:t,baselineMm:i,hfovDeg:r,rectified:s}={}){let o={type:"hello",v:ze,format:Di.includes(n)?n:"mono",width:e||0,height:t||0,rectified:!!s,sdk:wt};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(r)&&(o.hfovDeg=r),o}function Et(n){if(!n||n.type!=="hint")return null;let e=n.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=rr&&e<=sr?{type:"hint",subjectZmm:e}:null}function Oi(n){return!n||n.type!=="state"?null:{type:"state",muted:n.muted===!0,cameraOff:n.cameraOff===!0,speaking:n.speaking===!0}}function kt(n){let e=1e3/n,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function Tt({format:n,woven:e,mono3D:t="auto",lift:i=!1,overBudget:r=!1,failed:s=!1}){return(n==="sbs"?"sbs":"mono")==="sbs"?{route:e?"woven-sbs":"flat-left"}:e?t==="off"||t===!1?{route:"flat",mono3d:"off"}:i?s?{route:"flat",mono3d:"failed"}:r?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function Ct(n){return n==="woven-sbs"?"3D":n==="lifted"?"2D\u21923D":"2D"}function Rt({need:n=10,needNoPose:e=30}={}){let t=0,i=0,r=!1;return{feed(s){return r?!0:(i++,s===null?r=i>=e:(t=s>=1?t+1:0,r=t>=n),r)},get live(){return r}}}function Ve(n,e){let t=Math.max(1,e|0),r=n==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return r[Math.min(t,r.length)-1]}function B(n,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let r=Math.min(t,e*Math.pow(2,Math.max(0,n)));return Math.round(r*(.8+.4*i()))}var Me=Object.freeze(["VP9","VP8","AV1"]);function cr(n,e=Me){let t=e.indexOf(String(n||"").toUpperCase());return t<0?e.length:t}function $e(n,e=Me){let t=i=>cr(String(i.mimeType||"").split("/")[1],e);return n.map((i,r)=>({c:i,i:r,r:t(i)})).sort((i,r)=>i.r-r.r||i.i-r.i).map(i=>i.c)}function Ee(n,e=Me){if(!n)return n;let t=n.includes(`\r
|
|
3
3
|
`)?`\r
|
|
4
4
|
`:`
|
|
5
5
|
`,i=n.split(t),r=i.findIndex(d=>d.startsWith("m=video"));if(r<0)return n;let s=i.findIndex((d,m)=>m>r&&d.startsWith("m="));s<0&&(s=i.length);let o=i.slice(r,s),a=new Map,l=new Map;for(let d of o){let m=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);m&&a.set(m[1],m[2].toUpperCase());let u=d.match(/^a=fmtp:(\d+) apt=(\d+)/);u&&(l.has(u[2])||l.set(u[2],[]),l.get(u[2]).push(u[1]))}let c=i[r].split(" "),p=c.slice(3),f=[];for(let d of e)for(let m of p)if(a.get(m)===d&&!f.includes(m)){f.push(m);for(let u of l.get(m)||[])p.includes(u)&&!f.includes(u)&&f.push(u)}if(!f.length)return n;let h=p.filter(d=>!f.includes(d));return i[r]=[...c.slice(0,3),...f,...h].join(" "),i.join(t)}var Pi=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),hr=4e3,fr=1e4,ur=2e4,pr=8e3,mr=1e4;function Te(n){let e=Number.isInteger(n)?n:ae;return Math.max(2,Math.min(Li,e))}function Fi(n,e){return n<e}var ke=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:r,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:mr,this.signaling=e,this.id=t,this.maxPeers=Te(i),this.pageIce=r||null,this.iceServers=r||Pi,this.PC=s||globalThis.RTCPeerConnection,this.log=o||(()=>{}),this.peers=new Map,this.session=null,this.ready=!1,this._pending=[],this.stopped=!1,this.sendFormat="mono",this.localStream=null}get size(){return this.peers.size}async start({room:e,localStream:t,sendFormat:i,onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:f}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:f};let h=u=>(...v)=>this.ready?u(...v):this._pending.push(()=>u(...v));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(u=>this._onPeerJoined(u)),onPeerLeft:h(u=>this._onPeerLeftSignaling(u)),onSignal:h((u,v)=>this._onSignal(u,v)),onDisconnect:u=>p?.(u?"closed":"reconnecting",u),onPeerUnreachable:h(u=>f?.(u,!0)),onPeerReachable:h(u=>f?.(u,!1)),onReconnect:h(u=>{p?.("connected");for(let v of u)this._onPeerJoined(v)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Pi,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let u=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw u.code="room-full",u}this.ready=!0;for(let u of d)this._onPeerJoined(u);let m=this._pending;this._pending=[];for(let u of m)u();return this.session}_onPeerJoined(e){if(this.stopped||e===this.id)return;let t=this.peers.get(e);if(t){t.absent=!1,t.state!=="connected"&&Fi(this.id,e)&&this._rebuild(t,"rejoined");return}if(this.peers.size>=this.maxPeers-1){this.log("refused",{peer:e,reason:"maxPeers",maxPeers:this.maxPeers}),this.cb.onRefused?.(e);return}let i=this._newRecord(e);this.cb.onPeer?.(e),i.offerer?this._build(i,1):i.waitTimer=setTimeout(()=>this._askRestart(i),pr)}_onPeerLeftSignaling(e){let t=this.peers.get(e);t&&(t.absent=!0,t.state!=="connected"&&this._drop(t,"left"))}_newRecord(e){let t={id:e,offerer:Fi(this.id,e),pc:null,builtAt:0,offerAt:0,dc:null,gen:0,state:"new",stream:null,attempts:0,iceRestarted:!1,absent:!1,pendingCandidates:[],timers:new Set,waitTimer:null,unreachable:!1,unreachTimer:null};return this.peers.set(e,t),this._armUnreachable(t),t}_build(e,t){this._closePc(e),e.gen=t,e.builtAt=Date.now(),e.iceRestarted=!1,e.pendingCandidates=[],e.stream=null;let i=new this.PC({iceServers:this.iceServers});e.pc=i;let r=i.createDataChannel("dxr-call",{negotiated:!0,id:0,ordered:!0});if(this._wireDc(e,r),e.offerer){let s=this.localStream?this.localStream.getTracks():[],o=s.find(p=>p.kind==="audio"),a=s.find(p=>p.kind==="video"),l=this.localStream?[this.localStream]:[];i.addTransceiver(o||"audio",{direction:"sendrecv",streams:l});let c=i.addTransceiver(a||"video",{direction:"sendrecv",streams:l});this._preferCodecs(c)}return i.onicecandidate=s=>{s.candidate&&this._signal(e,{kind:"candidate",candidate:s.candidate.toJSON?s.candidate.toJSON():s.candidate})},i.ontrack=s=>{if(e.stream||(e.stream=new MediaStream),!e.stream.getTracks().includes(s.track)){for(let o of e.stream.getTracks())o.kind===s.track.kind&&e.stream.removeTrack(o);e.stream.addTrack(s.track)}this.cb.onStream?.(e.id,e.stream)},i.onconnectionstatechange=()=>this._onConnState(e,i),this._arm(e,ur,()=>{e.pc===i&&i.connectionState!=="connected"&&this._fail(e,"connect-timeout")}),e.offerer&&this._offer(e).catch(s=>this.log("offer-error",{peer:e.id,err:String(s)})),this._setState(e,e.attempts>0?"reconnecting":"connecting"),i}async _offer(e,{iceRestart:t=!1}={}){let i=e.pc,r=await i.createOffer(t?{iceRestart:!0}:void 0);this._canPreferCodecs||(r.sdp=Ee(r.sdp)),await i.setLocalDescription(r),this._signal(e,{kind:"offer",sdp:i.localDescription.sdp})}async _onSignal(e,t){if(this.stopped||!t||typeof t!="object")return;let i=this.peers.get(e);if(!i&&(t.kind!=="offer"||(this._onPeerJoined(e),i=this.peers.get(e),!i)))return;let r=t.gen|0;try{switch(t.kind){case"offer":{if(i.offerer||(clearTimeout(i.waitTimer),r<i.gen))return;i.offerAt=Date.now(),(r>i.gen||!i.pc)&&this._build(i,r);let s=i.pc;await s.setRemoteDescription({type:"offer",sdp:t.sdp}),this._attachAnswererTracks(i);let o=await s.createAnswer();this._canPreferCodecs||(o.sdp=Ee(o.sdp)),await s.setLocalDescription(o),this._signal(i,{kind:"answer",sdp:s.localDescription.sdp}),this._flushCandidates(i);break}case"answer":if(!i.offerer||r!==i.gen||!i.pc||i.pc.signalingState!=="have-local-offer")return;await i.pc.setRemoteDescription({type:"answer",sdp:t.sdp}),this._flushCandidates(i);break;case"candidate":if(r!==i.gen||!i.pc)return;i.pc.remoteDescription?await i.pc.addIceCandidate(t.candidate).catch(()=>{}):i.pendingCandidates.push(t.candidate);break;case"restart":if(!i.offerer||i.pc&&i.state!=="connected"&&Date.now()-i.builtAt<5e3)return;this._rebuild(i,"peer-asked");break;case"bye":this._drop(i,"left");break}}catch(s){this.log("signal-error",{peer:e,kind:t.kind,err:String(s)})}}_flushCandidates(e){let t=e.pendingCandidates;e.pendingCandidates=[];for(let i of t)e.pc.addIceCandidate(i).catch(()=>{})}_attachAnswererTracks(e){let t=e.pc,i=this.localStream?this.localStream.getTracks():[];for(let r of t.getTransceivers()){let s=r.receiver&&r.receiver.track?r.receiver.track.kind:null;if(!s||r.sender.track)continue;let o=i.find(a=>a.kind===s);o&&(r.sender.replaceTrack(o).catch(()=>{}),this.localStream&&r.sender.setStreams&&r.sender.setStreams(this.localStream)),r.direction="sendrecv",s==="video"&&this._preferCodecs(r)}}_preferCodecs(e){let t=globalThis.RTCRtpReceiver&&RTCRtpReceiver.getCapabilities&&RTCRtpReceiver.getCapabilities("video");if(this._canPreferCodecs=!!(e&&e.setCodecPreferences&&t),!!this._canPreferCodecs)try{e.setCodecPreferences($e(t.codecs))}catch{this._canPreferCodecs=!1}}_onConnState(e,t){if(e.pc!==t)return;let i=t.connectionState;this.log("pc-state",{peer:e.id,state:i,gen:e.gen}),i==="connected"?(this._clearTimers(e),e.attempts=0,e.iceRestarted=!1,this._setState(e,"connected"),this.tuneSenders()):i==="disconnected"?(this._setState(e,"reconnecting"),this._arm(e,hr,()=>{e.pc===t&&t.connectionState!=="connected"&&this._fail(e,"disconnected")})):i==="failed"?this._fail(e,"failed"):i==="closed"&&!this.stopped&&this.peers.get(e.id)===e&&this._fail(e,"closed")}_fail(e,t){if(this.stopped||this.peers.get(e.id)!==e)return;if(e.absent)return this._drop(e,"left");if(this._setState(e,"reconnecting"),!e.offerer)return this._askRestart(e);let i=e.pc;if(i&&!e.iceRestarted&&i.connectionState!=="closed"&&i.signalingState!=="closed"){e.iceRestarted=!0,this.log("ice-restart",{peer:e.id,why:t,gen:e.gen}),this._offer(e,{iceRestart:!0}).catch(()=>this._rebuild(e,"ice-restart-failed")),this._arm(e,fr,()=>{e.pc===i&&i.connectionState!=="connected"&&this._rebuild(e,"ice-restart-timeout")});return}this._rebuild(e,t)}_rebuild(e,t){if(this.stopped||this.peers.get(e.id)!==e)return;this._clearTimers(e),this._closePc(e),this._setState(e,"reconnecting");let i=B(e.attempts++);this.log("redial",{peer:e.id,why:t,attempt:e.attempts,inMs:i}),this._arm(e,i,()=>this._build(e,e.gen+1))}_askRestart(e){if(this.stopped||this.peers.get(e.id)!==e||e.offerer)return;let t=Date.now();this._signal(e,{kind:"restart"}),this._arm(e,Math.max(3e3,B(e.attempts++)),()=>{e.state!=="connected"&&!(e.offerAt>=t)&&this._askRestart(e)})}_drop(e,t){this.peers.get(e.id)===e&&(this._clearTimers(e),clearTimeout(e.unreachTimer),clearTimeout(e.waitTimer),this._closePc(e),this.peers.delete(e.id),this._setState(e,"left"),this.cb.onPeerLeft?.(e.id,t),this.tuneSenders())}_closePc(e){if(e.dc){try{e.dc.close()}catch{}e.dc=null}if(e.pc){let t=e.pc;e.pc=null;try{t.close()}catch{}}}_arm(e,t,i){let r=setTimeout(()=>{e.timers.delete(r),i()},t);e.timers.add(r)}_clearTimers(e){for(let t of e.timers)clearTimeout(t);e.timers.clear()}_armUnreachable(e){e.unreachTimer||e.unreachable||(e.unreachTimer=setTimeout(()=>{e.unreachTimer=null,!(this.stopped||this.peers.get(e.id)!==e||e.state==="connected")&&(e.unreachable=!0,this.log("unreachable",{peer:e.id,afterMs:this.unreachableMs,pc:e.pc?e.pc.iceConnectionState:null}),this._setState(e,"unreachable"))},this.unreachableMs))}_setState(e,t){t==="connected"?(clearTimeout(e.unreachTimer),e.unreachTimer=null,e.unreachable=!1):(t==="connecting"||t==="reconnecting")&&(e.unreachable?t="unreachable":this._armUnreachable(e)),e.state!==t&&(e.state=t,this.cb.onPeerState?.(e.id,t))}_signal(e,t){this.session?.send(e.id,{...t,gen:e.gen})}_wireDc(e,t){e.dc=t,t.onopen=()=>this.cb.onMessage?.(e.id,{type:"__open"}),t.onmessage=i=>{let r;try{r=JSON.parse(i.data)}catch{return}if(r&&r.type==="bye")return this._drop(e,"left");this.cb.onMessage?.(e.id,r)}}send(e,t){let i=this.peers.get(e);return i&&i.dc&&i.dc.readyState==="open"?(i.dc.send(JSON.stringify(t)),!0):!1}broadcast(e){for(let t of this.peers.keys())this.send(t,e)}peerConnection(e){let t=this.peers.get(e);return t?t.pc:null}peerState(e){let t=this.peers.get(e);return t?t.state:null}async replaceTrack(e,t,i){i&&(this.localStream=i);for(let r of this.peers.values())if(r.pc)for(let s of r.pc.getTransceivers())(s.receiver&&s.receiver.track?s.receiver.track.kind:null)===e&&await s.sender.replaceTrack(t).catch(()=>{});await this.tuneSenders()}setSendFormat(e){return this.sendFormat=e,this.tuneSenders()}async tuneSenders(){let e=this.peers.size,t=Ve(this.sendFormat,e);for(let i of this.peers.values())if(i.pc){for(let r of i.pc.getSenders())if(!(!r.track||r.track.kind!=="video"))try{let s=r.getParameters();s.degradationPreference="maintain-resolution",(!s.encodings||!s.encodings.length)&&(s.encodings=[{}]),s.encodings[0].maxBitrate=t*1e3,await r.setParameters(s)}catch(s){this.log("setParameters-error",{peer:i.id,err:String(s)})}}return t}stop(){if(!this.stopped){this.broadcast({type:"bye"}),this.stopped=!0;for(let e of this.peers.values())this._clearTimers(e),clearTimeout(e.waitTimer),clearTimeout(e.unreachTimer),this._signal(e,{kind:"bye"}),this._closePc(e);this.peers.clear();try{this.session?.leave()}catch{}}}_debugKill(e){let t=this.peers.get(e);return!t||!t.pc?!1:(this._closePc(t),this._fail(t,"debug-kill"),!0)}};var ji={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},Dt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},gr=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function _r(n){return!!n&&(n.name==="NotReadableError"||n.name==="TrackStartError"||/in use|busy/i.test(n.message||""))}function vr(n){return!!n&&(n.name==="NotAllowedError"||n.name==="PermissionDeniedError"||n.name==="SecurityError")}function Wi(n){return n.length&&n.every(e=>e.busy)?"camera-busy":n.some(e=>e.denied)?"permission-denied":"no-camera"}function Lt(n){return/stereo|\b3d\b|\bsbs\b|dual/i.test(n||"")}async function Ni(n="auto",e={}){let t=e.mediaDevices||globalThis.navigator&&navigator.mediaDevices,i=e.log||(()=>{}),r=[],s=e.calibration||{};if(n&&typeof n=="object"&&typeof n.getVideoTracks=="function"){let m=n.getVideoTracks()[0],u=m?m.getSettings():{},v=e.format==="sbs"?"sbs":"mono";return{stream:n,format:v,width:u.width||0,height:u.height||0,deviceId:u.deviceId||null,label:m?m.label:"",owned:!1,skipped:r,calibration:s}}if(!t||!t.getUserMedia)throw Object.assign(new Error("getUserMedia is not available (insecure context?)"),{code:"no-camera"});let o=async m=>{let u=await t.getUserMedia({video:m,audio:!1}),v=u.getVideoTracks()[0],y=v?v.getSettings():{};if(!v||v.readyState==="ended"||!(y.width>0)||!(y.height>0))throw u.getTracks().forEach(C=>C.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=y.displayxrStereo&&y.displayxrStereo.layout==="side-by-side"?y.displayxrStereo:null;return{stream:u,track:v,width:y.width,height:y.height,deviceId:y.deviceId||null,label:v.label||"",stereo:b}},a=(m,u)=>{r.push({label:m,error:`${u.name}: ${u.message}`,busy:_r(u),denied:vr(u)}),i("camera-skip",{label:m,error:u.name})},l=m=>m&&m.stream.getTracks().forEach(u=>u.stop()),c=(m,u)=>({stream:m.stream,format:u,width:m.width,height:m.height,deviceId:m.deviceId,label:m.label,owned:!0,skipped:r,calibration:{rectified:!1,...u==="sbs"&&m.stereo?{rectified:!!m.stereo.rectified,...m.stereo.baselineMm>0?{baselineMm:m.stereo.baselineMm}:{},...m.stereo.horizontalFovDeg>0?{hfovDeg:m.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof n=="string"&&!["auto","stereo","mono"].includes(n)){let m;try{m=await o({deviceId:{exact:n},...Dt})}catch(u){throw a(n,u),Object.assign(new Error(`camera unavailable: ${u.message}`),{code:Wi(r),skipped:r})}return se(m.width,m.height)?c(m,"sbs"):(l(m),c(await o({deviceId:{exact:n},...ji}),"mono"))}let p=new Set;if(n!=="mono"){let m=[];try{m=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput"&&u.deviceId&&Lt(u.label))}catch{}for(let u of m){p.add(u.deviceId);let v=null;try{v=await o({deviceId:{exact:u.deviceId},...Dt})}catch(y){a(u.label,y);continue}if(se(v.width,v.height))return i("camera-sbs",{label:v.label,width:v.width,height:v.height,direct:!0}),c(v,"sbs");l(v)}}let f=null;try{f=await o(ji)}catch(m){a("default",m)}if(n==="mono"&&f)return c(f,"mono");if(f&&se(f.width,f.height))return c(f,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(m=>m.kind==="videoinput")}catch{}h.sort((m,u)=>Number(Lt(u.label))-Number(Lt(m.label)));for(let m of h){if(!m.deviceId||f&&m.deviceId===f.deviceId||p.has(m.deviceId))continue;let u=null;try{u=await o({deviceId:{exact:m.deviceId},...Dt})}catch(v){a(m.label,v);continue}if(se(u.width,u.height))return l(f),i("camera-sbs",{label:u.label,width:u.width,height:u.height}),c(u,"sbs");l(u)}if(f)return n==="stereo"&&i("camera-no-stereo",{fallback:f.label}),c(f,"mono");let d=Wi(r);throw Object.assign(new Error(d==="camera-busy"?"every camera is in use by another app (e.g. eye tracking)":d==="permission-denied"?"camera access was denied":"no camera could be opened"),{code:d,skipped:r})}async function zi(n={}){let e=n.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...gr},video:!1})).getAudioTracks()[0]||null}catch(t){return(n.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}function Ue(n,e,t,i,r,s,o,a,l,c,p){if(s<0||s+a>t||o<0)return-1;let f=0,h=0,d=0,m=a*l;for(let y=0;y<l;y++){let b=(r+y)*e+i,C=(o+y)*e+t+s;for(let x=0;x<a;x++){let O=n[C+x];f+=O,h+=O*O,d+=n[b+x]*O}}let u=f/m,v=h/m-u*u;return v<1?-1:(d/m-c*u)/(p*Math.sqrt(v))}function yr(n,e,t,i,r,s){let o=0,a=0;for(let p=0;p<s;p++){let f=(i+p)*e+t;for(let h=0;h<r;h++){let d=n[f+h];o+=d,a+=d*d}}let l=r*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function At(n,e,t,i,r,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:p}={}){let f=e/2,{mean:h,std:d}=yr(n,e,i,r,s,o);if(d<6)return null;let m=-2,u=0,v=0,y=new Map,b=(R,g,w,_,M)=>{for(let A=_;A<=M;A++){let S=r+A;if(!(S<0||S+o>t))for(let F=R;F<=g;F+=w){let z=Ue(n,e,f,i,r,i-F,S,s,o,h,d);z>(y.get(F)??-2)&&y.set(F,z),z>m&&(m=z,u=F,v=A)}}},C=l-a>8;if(b(a,l,C?2:1,-c,c),C&&m>-1){let R=u,g=v;b(Math.max(a,R-2),Math.min(l,R+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(m<-1)return null;let x=-2,O=R=>{let g=-2;for(let w=-c;w<=c;w++){let _=r+w;if(!(_<0||_+o>t))for(let M=R-1;M<=R+1;M++)g=Math.max(g,Ue(n,e,f,i,r,i-M,_,s,o,h,d))}return g};for(let[R,g]of y){if(Math.abs(R-u)<3||g<=x)continue;let _=g>=(y.get(R-2)??-2)&&g>=(y.get(R+2)??-2)&&g>0?O(R):g;_>x&&(x=_)}if(l-a>12&&x>-2&&m-x<(p??.08))return null;let T=Ue(n,e,f,i,r,i-(u-1),r+v,s,o,h,d),I=Ue(n,e,f,i,r,i-(u+1),r+v,s,o,h,d),P=0,L=T-2*m+I;return T>-1&&I>-1&&L<0&&(P=Math.max(-.5,Math.min(.5,.5*(T-I)/L))),{d:u+P,dy:v,c:m}}function wr(n,e,t,i={}){let r=e/2,s=i.block||Math.max(8,Math.round(r/20)),o=i.step||Math.round(s*1.5),a=i.dMax??Math.round(r*.3),l=i.dMin??-Math.round(r*.05),c=Math.round(r*(i.roiX0??.15)),p=Math.round(r*(i.roiX1??.85))-s,f=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let m=f;m<=h;m+=o)for(let u=c;u<=p;u+=o){let v=At(n,e,t,u,m,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});v&&v.c>=(i.minNcc??.8)&&d.push({x:u,y:m,...v})}return d}function br(n,{tol:e=2,minFrac:t=.12,minBlocks:i=3}={}){if(!n.length)return null;let r=Math.max(i,Math.ceil(n.length*t)),s=n.map(o=>o.d).sort((o,a)=>a-o);for(let o of s){let a=n.filter(l=>Math.abs(l.d-o)<=e);if(a.length>=r){let l=a.map(c=>c.d).sort((c,p)=>c-p);return{d:l[l.length>>1],members:a}}}return null}function xr(n,e){let t=Math.min(...n.map(l=>l.y)),r=n.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...r),o=Math.max(...r)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function It(n,e,t,i={}){let r=e/2,s=i.block||Math.max(8,Math.round(r/20)),o=i.dMax??Math.round(r*.3),a=i.dMin??-Math.round(r*.05),l=i.focus||null,c="focus",p=0,f=null;if(!l){let C=wr(n,e,t,{...i,block:s,dMax:o,dMin:a});p=C.length;let x=br(C,i);if(!x)return null;l=xr(x.members,s),f=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),m=Math.round(Math.max(0,Math.min(r-h,l.x-h/2))),u=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),v=f===null?a:Math.max(a,Math.floor(f)-4),y=f===null?o:Math.min(o,Math.ceil(f)+4),b=At(n,e,t,m,u,h,d,{dMin:v,dMax:y,dyMax:i.dyMax??2});return b&&b.c>=(i.minNcc??.8)?{d:b.d,x:l.x,y:l.y,c:b.c,method:c,blocks:p}:f!==null?{d:f,x:l.x,y:l.y,c:0,method:c,blocks:p}:null}function Be(n,e){let t=new Uint8Array(e);for(let i=0,r=0;i<e;i++,r+=4)t[i]=n[r]*77+n[r+1]*150+n[r+2]*29>>8;return t}function qe({n=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>n&&e.shift();let r=[...e].sort((s,o)=>s-o);return t.value=r[r.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function Hi(n,e,t,i,r,s){let o=new Float32Array(r*s);for(let a=0;a<s;a++)for(let l=0;l<r;l++)o[a*r+l]=n[(i+a)*e+t+l];return o}function Sr(n,e,t,i,r,s,o,a,l,c){let p=e/2,f=r*s,h=0,d=0;for(let b=0;b<f;b++)h+=i[b],d+=i[b]*i[b];h/=f;let m=Math.sqrt(Math.max(1e-6,d/f-h*h)),u=-2,v=o,y=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let C=Math.max(0,o-l);C<=Math.min(p-r,o+l);C++){let x=0,O=0,T=0;for(let R=0;R<s;R++){let g=(b+R)*e+C;for(let w=0;w<r;w++){let _=n[g+w];x+=_,O+=_*_,T+=_*i[R*r+w]}}let I=x/f,P=O/f-I*I;if(P<1)continue;let L=(T/f-I*h)/(Math.sqrt(P)*m);L>u&&(u=L,v=C,y=b)}return{x:v,y,c:u}}function Ce({fullEveryMs:n=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:r=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,p,f,h,d={}){let m=p/2,u=d.block||Math.max(8,Math.round(m/20)),v=Math.round(u*3),y=Math.round(u*1.5),b=null;if(o&&o.w===v&&o.h===y){let I=Sr(c,p,f,o.tpl,v,y,o.x,o.y,t,i);if(I.c>=r){let P=At(c,p,f,I.x,I.y,v,y,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});P&&P.c>=.8&&(b={m:P,f:I})}}let C=({m:I,f:P})=>(o={...o,x:P.x,y:P.y,d:I.d,tpl:Hi(c,p,P.x,P.y,v,y)},{d:I.d,x:P.x+v/2,y:P.y+y/2,c:I.c,method:"track",blocks:0});if(b&&h-o.at<n)return C(b);let x=It(c,p,f,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let I=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!I?{d:x.d}:null,!I)return o.at=h,C(b)}else a=null;if(!x)return o=null,null;let O=Math.round(Math.max(0,Math.min(m-v,x.x-v/2))),T=Math.round(Math.max(0,Math.min(f-y,x.y-y/2)));return o={x:O,y:T,d:x.d,tpl:Hi(c,p,O,T,v,y),w:v,h:y,at:h},x},reset(){o=null,a=null}}}function Vi(n,e,t,i,r,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(r/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let d=0;d<l;d++)for(let m=0;m<a;m++){let u=0;for(let v=0;v<o;v++){let y=e+(d*o+v)*t+m*o;for(let b=0;b<o;b++)u+=n[y+b]}c[d*a+m]=u/h|0}return{img:c,w:a,h:l}}let p=o>>2,f=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+p)*t,m=e+(h*o+f)*t;for(let u=0;u<a;u++){let v=u*o+p,y=u*o+f;c[h*a+u]=n[d+v]+n[d+y]+n[m+v]+n[m+y]>>2}}return{img:c,w:a,h:l}}var $i="http://displayxr.org/ns/stereo/1.0/",Xe="http://ns.adobe.com/xap/1.0/\0";function Je(n={}){let e=i=>typeof i=="number"&&Number.isFinite(i)?i:null,t=n.layout==="sbs"||n.layout==="side-by-side"?"sbs":"mono";return{layout:t,columns:t==="sbs"?2:1,rows:1,convergencePx:e(n.convergencePx),baselineMm:e(n.baselineMm),horizontalFovDeg:e(n.horizontalFovDeg),rectified:n.rectified===!0?!0:n.rectified===!1?!1:null,eyeWidth:e(n.eyeWidth),eyeHeight:e(n.eyeHeight),software:typeof n.software=="string"&&n.software?n.software:null}}var Mr=n=>String(n).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),de=n=>Math.round(n*1e3)/1e3;function Ui(n){let e=Je(n),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:de(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:de(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:de(e.horizontalFovDeg)],["Rectified",e.rectified===null?null:e.rectified?"True":"False"],["EyeWidth",e.eyeWidth],["EyeHeight",e.eyeHeight],["Software",e.software]].filter(([,i])=>i!=null).map(([i,r])=>` dxr:${i}="${Mr(r)}"`).join("");return`<?xpacket begin="\uFEFF" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dxr="${$i}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Pt(n){if(typeof n!="string"||!n.includes($i))return null;let e=o=>{let a=new RegExp(`\\bdxr:${o}="([^"]*)"`).exec(n);if(a)return a[1];let l=new RegExp(`<dxr:${o}>([^<]*)</dxr:${o}>`).exec(n);return l?l[1]:null},t=o=>{let a=e(o);return a===null||a===""||!Number.isFinite(+a)?null:+a},i=e("Rectified"),r=e("Layout"),s=e("Software");return Je({layout:r==="side-by-side"||r==="sbs"?"sbs":"mono",convergencePx:t("ConvergencePx"),baselineMm:t("BaselineMm"),horizontalFovDeg:t("HorizontalFovDeg"),rectified:i===null?null:/^true$/i.test(i),eyeWidth:t("EyeWidth"),eyeHeight:t("EyeHeight"),software:s===null?null:s.replace(/"/g,'"').replace(/</g,"<").replace(/&/g,"&")})}var Ge=n=>new TextEncoder().encode(n),Ot=n=>new TextDecoder().decode(n),Bi=n=>n.length>4&&n[0]===255&&n[1]===216;function*qi(n){let e=2;for(;e+4<=n.length;){if(n[e]!==255)return;let t=n[e+1];if(t===216||t>=208&&t<=215||t===1||t===255){e+=t===255?1:2;continue}if(t===218||t===217)return;let i=n[e+2]<<8|n[e+3];if(i<2||e+2+i>n.length)return;yield{marker:t,start:e,end:e+2+i,data:n.subarray(e+4,e+2+i)},e+=2+i}}function Xi(n,e){if(n.length<e.length)return!1;for(let t=0;t<e.length;t++)if(n[t]!==e.charCodeAt(t))return!1;return!0}function Gi(n,e){if(!Bi(n))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Ge(Xe),...Ge(e)]),i=t.length+2;if(i>65535)throw new RangeError("jpegWithXmp: XMP packet too large for one APP1 segment");let r=new Uint8Array(4+t.length);r[0]=255,r[1]=225,r[2]=i>>8,r[3]=i&255,r.set(t,4);let s=2,o=null;for(let p of qi(n)){if(p.marker===225&&Xi(p.data,Xe)){o=p;break}if(p.marker===224||p.marker===225)s=p.end;else break}let[a,l]=o?[o.start,o.end]:[s,s],c=new Uint8Array(n.length-(l-a)+r.length);return c.set(n.subarray(0,a),0),c.set(r,a),c.set(n.subarray(l),a+r.length),c}function Ft(n){if(!Bi(n))return null;for(let e of qi(n))if(e.marker===225&&Xi(e.data,Xe))return Ot(e.data.subarray(Xe.length));return null}var Ji=n=>Pt(Ft(n)),H={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},Er=n=>n.length>4&&n[0]===26&&n[1]===69&&n[2]===223&&n[3]===163;function Ki(n){let e=[];for(let t=n;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function Yi(n,e=0){let t=e;if(!t)for(t=1;t<8&&n>2**(7*t)-2;t++);let i=new Array(t).fill(0),r=n;for(let s=t-1;s>=1;s--)i[s]=r%256,r=Math.floor(r/256);return i[0]=128>>t-1|r,i}function jt(n,e){let t=n[e],i=t>=128?1:t>=64?2:t>=32?3:t>=16?4:0;if(!i||e+i>n.length)return null;let r=0;for(let s=0;s<i;s++)r=r*256+n[e+s];return{id:r,width:i}}function Re(n,e){let t=n[e],i=1;for(;i<=8&&!(t&128>>i-1);)i++;if(i>8||e+i>n.length)return null;let r=t&255>>i,s=r===127>>i-1;for(let o=1;o<i;o++)r=r*256+n[e+o],n[e+o]!==255&&(s=!1);return{size:r,width:i,unknown:s}}function ce(n,e){return[...Ki(n),...Yi(e.length),...e]}function kr(n){let e=[];for(let[i,r]of Object.entries(n))r!=null&&e.push(...ce(H.SimpleTag,[...ce(H.TagName,[...Ge(String(i))]),...ce(H.TagString,[...Ge(String(r))])]));let t=ce(H.Tag,[...ce(H.Targets,[]),...e]);return new Uint8Array(ce(H.Tags,t))}function Zi(n){let e=Je(n);return{DXR_LAYOUT:e.layout==="sbs"?"side-by-side":"mono",DXR_COLUMNS:String(e.columns),DXR_ROWS:String(e.rows),DXR_CONVERGENCE_PX:e.convergencePx===null?null:String(de(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(de(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(de(e.horizontalFovDeg)),DXR_RECTIFIED:e.rectified===null?null:e.rectified?"true":"false",DXR_EYE_WIDTH:e.eyeWidth===null?null:String(e.eyeWidth),DXR_EYE_HEIGHT:e.eyeHeight===null?null:String(e.eyeHeight),DXR_SOFTWARE:e.software}}function Tr(n){if(!n||!("DXR_LAYOUT"in n))return null;let e=t=>n[t]===void 0||n[t]===""||!Number.isFinite(+n[t])?null:+n[t];return Je({layout:n.DXR_LAYOUT==="side-by-side"?"sbs":"mono",convergencePx:e("DXR_CONVERGENCE_PX"),baselineMm:e("DXR_BASELINE_MM"),horizontalFovDeg:e("DXR_HFOV_DEG"),rectified:n.DXR_RECTIFIED===void 0?null:n.DXR_RECTIFIED==="true",eyeWidth:e("DXR_EYE_WIDTH"),eyeHeight:e("DXR_EYE_HEIGHT"),software:n.DXR_SOFTWARE??null})}function Qi(n){if(!Er(n))return null;let e=Re(n,4);if(!e)return null;let t=4+e.width+e.size;for(;t<n.length;){let i=jt(n,t);if(!i)return null;let r=Re(n,t+i.width);if(!r)return null;let s=t+i.width+r.width;if(i.id===H.Segment)return{sizeAt:t+i.width,sizeWidth:r.width,unknown:r.unknown,dataStart:s,size:r.size};if(r.unknown)return null;t=s+r.size}return null}function en(n,e){let t=Qi(n);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=kr(e);if(t.unknown){let p=new Uint8Array(n.length+i.length);return p.set(n,0),p.set(i,n.length),p}let r=Math.min(n.length,t.dataStart+t.size),s=r-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=Yi(s,o?t.sizeWidth:8),l=new Uint8Array(t.sizeAt+a.length+(r-t.dataStart)+i.length+(n.length-r));l.set(n.subarray(0,t.sizeAt),0),l.set(a,t.sizeAt);let c=t.sizeAt+a.length;return l.set(n.subarray(t.dataStart,r),c),c+=r-t.dataStart,l.set(i,c),c+=i.length,l.set(n.subarray(r),c),l}function tn(n,e,t){let i={},r=(s,o,a)=>{let l=s;for(;l<o;){let c=jt(n,l);if(!c)return;let p=Re(n,l+c.width);if(!p||p.unknown)return;let f=l+c.width+p.width;a(c.id,f,Math.min(o,f+p.size)),l=f+p.size}};return r(e,t,(s,o,a)=>{s===H.Tag&&r(o,a,(l,c,p)=>{if(l!==H.SimpleTag)return;let f=null,h=null;r(c,p,(d,m,u)=>{d===H.TagName?f=Ot(n.subarray(m,u)):d===H.TagString&&(h=Ot(n.subarray(m,u)))}),f!==null&&(i[f]=h??"")})}),i}function Cr(n){let e=Qi(n);if(!e)return null;let t=e.unknown?n.length:Math.min(n.length,e.dataStart+e.size),i=null,r=e.dataStart;for(;r<t;){let s=jt(n,r);if(!s)break;let o=Re(n,r+s.width);if(!o)break;let a=r+s.width+o.width;if(s.id===H.Tags&&!o.unknown&&(i={...i||{},...tn(n,a,Math.min(t,a+o.size))}),o.unknown){i=i||Rr(n,t);break}r=a+o.size}return i}function Rr(n,e){let t=Ki(H.Tags);for(let i=e-t.length-1;i>=0;i--){if(n[i]!==t[0]||n[i+1]!==t[1]||n[i+2]!==t[2]||n[i+3]!==t[3])continue;let r=Re(n,i+4);if(r&&!r.unknown&&i+4+r.width+r.size===e)return tn(n,i+4+r.width,e)}return null}var nn=n=>Tr(Cr(n));var he="[inline3d/camera]",on="inline3d-camera/1",Dr=200,Lr=240,Ar=4e3,Ir=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],Ke=()=>typeof document<"u"&&document&&typeof document.createElement=="function",rn=()=>{let n=new Date,e=t=>String(t).padStart(2,"0");return`${n.getFullYear()}${e(n.getMonth()+1)}${e(n.getDate())}-${e(n.getHours())}${e(n.getMinutes())}${e(n.getSeconds())}`},Or=n=>/jpe?g/.test(n)?"jpg":/png/.test(n)?"png":/webp/.test(n)?"webp":/mp4/.test(n)?"mp4":/webm/.test(n)?"webm":"bin";function Ye(n,e,t){return`${String(n||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${Or(t)}`}var K=(n,e,t={})=>Object.assign(new Error(`${he} ${n}`),{code:e,...t});function sn(n,e=Ar){return n?(n.readyState||0)>=2&&n.videoWidth?Promise.resolve():new Promise((t,i)=>{let r=!1,s=()=>{r||(n.readyState||0)<2||!n.videoWidth||(r=!0,clearTimeout(o),n.removeEventListener("loadeddata",s),n.removeEventListener("playing",s),n.removeEventListener("resize",s),t())},o=setTimeout(()=>{r||(r=!0,i(K("the camera delivered no frame in time","no-frame")))},e);n.addEventListener("loadeddata",s),n.addEventListener("playing",s),n.addEventListener("resize",s),n.play?.().catch(()=>{})}):Promise.reject(K("no video element (no document?)","no-frame"))}function an(n,e,t=Lr){let i=n.videoWidth,r=n.videoHeight;if(!i||!r||(n.readyState||0)<2)return null;let s=Math.min(1,t/(i/2)),o=Math.max(2,Math.round(i*s/2)*2),a=Math.max(2,Math.round(r*s));(e.width!==o||e.height!==a)&&(e.width=o,e.height=a);let l=e.getContext("2d",{willReadFrequently:!0});try{return l.drawImage(n,0,0,o,a),{img:Be(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var Wt=class{constructor(e,{log:t=null}={}){this.format=e.format,this.stream=e.stream,this.width=e.width||0,this.height=e.height||0,this.deviceId=e.deviceId||null,this.label=e.label||"",this.owned=!!e.owned,this.skipped=Object.freeze([...e.skipped||[]]),this.calibration=Object.freeze({...e.calibration||{}});let i=this.calibration;this.stereo=this.format==="sbs"?Object.freeze({rectified:!!i.rectified,baselineMm:i.baselineMm>0?i.baselineMm:null,horizontalFovDeg:i.hfovDeg>0?i.hfovDeg:null}):null,this.state="live",this._log=t,this._listeners=new Map,this._scratch=null,this._views=new Set,this.video=null,Ke()&&(this.video=Object.assign(document.createElement("video"),{muted:!0,playsInline:!0,autoplay:!0}),this.video.srcObject=this.stream,this.video.play?.().catch(()=>{})),this._onEnded=()=>this._ended("ended");for(let r of this.stream.getVideoTracks())r.addEventListener?.("ended",this._onEnded)}get eyeWidth(){return this.format==="sbs"?this.width/2:this.width}log(e,t={}){this._log&&this._log(e,t)}on(e,t){if(typeof t!="function")throw new TypeError(`${he} on() takes a function`);return this._listeners.has(e)||this._listeners.set(e,new Set),this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}_emit(e,t){for(let i of[...this._listeners.get(e)||[]])try{i(t)}catch(r){console.error(`${he} '${e}' listener threw`,r)}}_ended(e){this.state==="live"&&(this.state="ended",this.log("ended",{reason:e}),this._emit("ended",{reason:e}))}async measureConvergence(){if(this.format!=="sbs"||!this.video||!Ke())return null;try{await sn(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=an(this.video,this._scratch);if(!e)return null;let t=Ce().measure(e.img,e.w,e.h,0);return t?t.d/e.scale:null}_meta(e,t=this.width,i=this.height){let r=this.stereo;return{layout:this.format,convergencePx:e,baselineMm:r?r.baselineMm:null,horizontalFovDeg:r?r.horizontalFovDeg:null,rectified:r?r.rectified:null,eyeWidth:this.format==="sbs"?t/2:t,eyeHeight:i,software:on}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:r}={}){if(this.state==="closed")throw K("the camera is closed","closed");if(!this.video||!Ke())throw K("capturePhoto needs a document","no-frame");await sn(this.video);let s=this.video.videoWidth,o=this.video.videoHeight,a=typeof r=="number"&&Number.isFinite(r)?r:await this.measureConvergence(),l=document.createElement("canvas");l.width=s,l.height=o,l.getContext("2d").drawImage(this.video,0,0,s,o);let c=await new Promise((d,m)=>l.toBlob(u=>u?d(u):m(K("toBlob produced nothing","encode-failed")),e,t)),p=this._meta(a,s,o),f=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(f=Ui(p),c=new Blob([Gi(new Uint8Array(await c.arrayBuffer()),f)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:Ye(i||`photo-${rn()}`,this.format,c.type||e),xmp:f};return this.log("photo",{width:s,height:o,layout:this.format,convergencePx:a,bytes:c.size,name:h.suggestedName}),h}record({mimeType:e,mono:t=!1,audio:i=null,videoBitsPerSecond:r,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw K("the camera is closed","closed");if(typeof MediaRecorder!="function")throw K("MediaRecorder is not available here","unsupported");let l=e||Ir.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw K(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],p=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...p);let f=new MediaStream(c),h={...l?{mimeType:l}:{},...r?{videoBitsPerSecond:r}:{}},d=new MediaRecorder(f,h),m=[];d.ondataavailable=g=>g.data&&g.data.size&&m.push(g.data);let u=null,v=[],y=null,b=0,C=!!t&&this.format==="sbs"&&Ke()&&this.video;if(C){y=document.createElement("canvas");let g=()=>{b=requestAnimationFrame(g);let _=this.video,M=_.videoWidth,A=_.videoHeight;!M||!A||(_.readyState||0)<2||((y.width!==M/2||y.height!==A)&&(y.width=M/2,y.height=A),y.getContext("2d").drawImage(_,0,0,M/2,A,0,0,M/2,A))};g();let w=y.captureStream(a);for(let _ of p)w.addTrack(_);u=new MediaRecorder(w,h),u.ondataavailable=_=>_.data&&_.data.size&&v.push(_.data)}let x=performance.now(),O=[],T=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&O.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&O.push(g)),d.start(s),u?.start(s),this.log("record-start",{mimeType:l,mono:C,audio:p.length});let I=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),P=o||`clip-${rn()}`,L=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),u&&u.state==="recording"&&u.pause()},resume(){d.state==="paused"&&d.resume(),u&&u.state==="paused"&&u.resume()},async stop(){clearInterval(T),b&&cancelAnimationFrame(b);let[g,w]=await Promise.all([I(d,m),I(u,v)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",M=[...O].sort((me,$)=>me-$),A=M.length?M[Math.floor(M.length/2)]:null,S=L._meta(A),F=/webm|matroska/.test(_),z=async(me,$)=>{let Z=new Blob(me,{type:_});if(F&&Z.size)try{Z=new Blob([en(new Uint8Array(await Z.arrayBuffer()),Zi({...S,layout:$}))],{type:_})}catch(ti){L.log("record-tag-failed",{message:String(ti&&ti.message)})}return Z},k=await z(g,L.format),j={blob:k,type:_,layout:L.format,durationMs:Math.round(performance.now()-x),convergencePx:A,stereo:L.stereo,suggestedName:Ye(P,L.format,_),tagged:F&&k.size>0};return u&&(j.mono=await z(w,"mono"),j.monoSuggestedName=Ye(P,"mono",_)),L.log("record-stop",{bytes:k.size,mono:j.mono?j.mono.size:null,ms:j.durationMs,convergencePx:A,name:j.suggestedName}),j}}}close(){if(this.state!=="closed"){this.state="closed";for(let e of this.stream.getVideoTracks())e.removeEventListener?.("ended",this._onEnded);for(let e of[...this._views])e.remove();this.owned&&this.stream.getTracks().forEach(e=>e.stop()),this.video&&(this.video.srcObject=null),this.log("closed",{})}}};async function zt(n={}){let e=typeof n=="string"||n&&typeof n.getVideoTracks=="function"?{prefer:n}:n||{},t=e.prefer===void 0||e.prefer===null?"auto":e.prefer,i=typeof e.log=="function"?e.log:e.debug?(a,l)=>console.log(`${he} ${a} ${JSON.stringify(l)}`):null,r=e.calibration&&typeof e.calibration=="object"?{...e.calibration}:{};r.horizontalFovDeg>0&&!(r.hfovDeg>0)&&(r.hfovDeg=r.horizontalFovDeg),delete r.horizontalFovDeg;let s=await Ni(t,{format:e.format,calibration:r,mediaDevices:e.mediaDevices,log:i||void 0});if(s.format==="sbs"&&typeof e.rectify=="function")try{let a=await e.rectify(s.stream,{width:s.width,height:s.height,deviceId:s.deviceId,label:s.label});a&&typeof a.getVideoTracks=="function"&&(s.stream=a,s.calibration={...s.calibration,rectified:!0})}catch(a){i?.("rectify-failed",{message:String(a&&a.message)}),s.rectifyError=a}let o=new Wt(s,{log:i});return s.rectifyError&&(o.rectifyError=s.rectifyError),o.log("open",{format:o.format,width:o.width,height:o.height,label:o.label,stereo:o.stereo,skipped:o.skipped.length}),o}var Ze=n=>!!n&&typeof n=="object"&&typeof n.capturePhoto=="function"&&typeof n.record=="function"&&n.stream&&typeof n.stream.getVideoTracks=="function";function Pr(n){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((n.clientWidth||0)*e),i=Math.round((n.clientHeight||0)*e);return!t||!i?!1:((n.width!==t||n.height!==i)&&(n.width=t,n.height=i),!0)}function Ht(n,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${he} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!Ze(t))throw new TypeError(`${he} addCameraView: cam must be a StereoCamera from openCamera()`);let r=new Nt(n,e,t,i);return t._views?.add(r),r}var Nt=class{constructor(e,t,i,r){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=r.mirror===void 0?!0:!!r.mirror,this.aspect=typeof r.aspect=="number"&&r.aspect>.3&&r.aspect<4?r.aspect:16/9,this.autoConverge=!!r.autoConverge,this.conv=xe(),this.conv.depth=0,this.setDepth(r.depth),this.route=null,this.handle=null,this.buffer=null,this.removed=!1,this._raf=0,this._loop=r._loop!==!1,this._autoAt=0,this._track=qe(),this._focus=Ce(),this._scratch=null,this.disparityPx=null,this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}get convergencePx(){return this.conv.current}get depth(){return this.conv.depth}setDepth(e){let t=e==null||!Number.isFinite(+e)?0:Math.max(-1,Math.min(1,+e));return this.conv.depth=t,t}setMirror(e){return this.mirror=e===void 0?!this.mirror:!!e,this.mirror}setAutoConverge(e){return this.autoConverge=e===void 0?!this.autoConverge:!!e,this.autoConverge||(this._track.reset(),this._focus.reset(),this.conv.measuredPx=null,this.disparityPx=null),this.autoConverge}_reroute(e,t){if(t!==void 0&&(this.wall=t),this.removed)return;let i=this.cam,r=i.state==="live"&&i.video,s=i.format==="sbs"&&r&&this.wall&&this.wall.supported?"woven-sbs":i.format==="sbs"?"flat-left":"flat";!e&&s===this.route||(this._unregister(),this.route=s,s==="woven-sbs"&&(this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven(),this.handle=this.wall.addImage(this.canvas,this.buffer)))}_onWallLost(){this._reroute(!0,{supported:!1})}_unregister(){if(this.handle){try{this.handle.remove()}catch{}this.handle=null}}_start(){let e=()=>{this._raf=requestAnimationFrame(e),this.paint()};this._raf=requestAnimationFrame(e)}paint(){if(this.removed)return;let e=this.cam.video;!e||this.cam.state==="closed"||(this.route==="woven-sbs"?this._paintWoven():this._paintFlat(e))}_paintFlat(e){if(!Pr(this.canvas))return;let t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2)return;let r=this.canvas.getContext("2d"),s=this.route==="flat-left"?t/2:t,o=X(s,i,this.canvas.width/this.canvas.height,0,0);r.save(),this.mirror&&(r.translate(this.canvas.width,0),r.scale(-1,1)),r.drawImage(e,o.sx,o.sy,o.sw,o.sh,0,0,this.canvas.width,this.canvas.height),r.restore()}_paintWoven(){let e=this.cam.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.buffer)return;let r=t/2,s=this.aspect,{w:o,h:a}=be(r,i,s),l=this.buffer;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a),this.autoConverge&&this._sample(e);let c=this.conv.step(r),p=l.getContext("2d");if(this.mirror)for(let f of oe(t,i)){let h=f.src==="L"?0:1,d=X(r,i,s,c,h),m=f.dx===0?0:o;p.save(),p.translate(m+o,0),p.scale(-1,1),p.drawImage(e,f.sx+d.sx,d.sy,d.sw,d.sh,0,0,o,a),p.restore()}else for(let f of[0,1]){let h=X(r,i,s,c,f);p.drawImage(e,f*r+h.sx,h.sy,h.sw,h.sh,f*o,0,o,a)}}_sample(e){let t=performance.now();if(t-this._autoAt<Dr)return;this._autoAt=t,this._scratch=this._scratch||document.createElement("canvas");let i=an(e,this._scratch),r=i?this._focus.measure(i.img,i.w,i.h,t):null,s=this._track.push(r?r.d/i.scale:null);this.conv.measuredPx=s,this.disparityPx=s}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,this._unregister(),this.cam._views?.delete(this))}};var cn=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],dn=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Fr=[1,0],Vt=10;function hn(n){let e=(16*n+128)*n+64;if(n>=2){let t=Math.floor(n/7)+2;e-=(25*t-10)*t-55,n>=7&&(e-=36)}return e}var ln=(n,e)=>Math.floor(hn(n)/8)-cn[e][n]*dn[e][n];function $t(n,e){let t=0;for(let i=7;i>=0;i--)t=t<<1^(t>>>7)*285,t^=(e>>>i&1)*n;return t}function jr(n){let e=new Array(n-1).fill(0);e.push(1);let t=1;for(let i=0;i<n;i++){for(let r=0;r<e.length;r++)e[r]=$t(e[r],t),r+1<e.length&&(e[r]^=e[r+1]);t=$t(t,2)}return e}function Wr(n,e){let t=e.map(()=>0);for(let i of n){let r=i^t.shift();t.push(0),e.forEach((s,o)=>t[o]^=$t(s,r))}return t}function Ut(n,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(n))],r=1;for(;r<=Vt&&!(4+(r<=9?8:16)+i.length*8<=ln(r,t)*8);r++);if(r>Vt)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${Vt} code`);let s=[],o=(g,w)=>{for(let _=w-1;_>=0;_--)s.push(g>>>_&1)};o(4,4),o(i.length,r<=9?8:16);for(let g of i)o(g,8);let a=ln(r,t)*8;o(0,Math.min(4,a-s.length)),o(0,(8-s.length%8)%8);for(let g=236;s.length<a;g^=253)o(g,8);let l=[];for(let g=0;g<s.length;g+=8)l.push(s.slice(g,g+8).reduce((w,_)=>w<<1|_,0));let c=dn[t][r],p=cn[t][r],f=Math.floor(hn(r)/8),h=c-f%c,d=Math.floor(f/c),m=jr(p),u=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-p+(g<h?0:1));w+=_.length;let M=Wr(_,m);g<h&&_.push(0),u.push(_.concat(M))}let v=[];for(let g=0;g<u[0].length;g++)for(let w=0;w<u.length;w++)(g!==d-p||w>=h)&&v.push(u[w][g]);let y=r*4+17,b=Array.from({length:y},()=>new Array(y).fill(!1)),C=Array.from({length:y},()=>new Array(y).fill(!1)),x=(g,w,_)=>{b[w][g]=_,C[w][g]=!0};for(let g=0;g<y;g++)x(6,g,g%2===0),x(g,6,g%2===0);let O=(g,w)=>{for(let _=-4;_<=4;_++)for(let M=-4;M<=4;M++){let A=Math.max(Math.abs(M),Math.abs(_)),S=g+M,F=w+_;S>=0&&S<y&&F>=0&&F<y&&x(S,F,A!==2&&A!==4)}};O(3,3),O(y-4,3),O(3,y-4);let T=[];if(r>1){let g=Math.floor(r/7)+2,w=Math.ceil((r*4+4)/(g*2-2))*2;T.push(6);for(let _=y-7;T.length<g;_-=w)T.splice(1,0,_)}for(let g=0;g<T.length;g++)for(let w=0;w<T.length;w++)if(!(g===0&&w===0||g===0&&w===T.length-1||g===T.length-1&&w===0))for(let _=-2;_<=2;_++)for(let M=-2;M<=2;M++)x(T[g]+M,T[w]+_,Math.max(Math.abs(M),Math.abs(_))!==1);let I=g=>{let w=Fr[t]<<3|g,_=w;for(let S=0;S<10;S++)_=_<<1^(_>>>9)*1335;let M=(w<<10|_)^21522,A=S=>(M>>>S&1)!==0;for(let S=0;S<=5;S++)x(8,S,A(S));x(8,7,A(6)),x(8,8,A(7)),x(7,8,A(8));for(let S=9;S<15;S++)x(14-S,8,A(S));for(let S=0;S<8;S++)x(y-1-S,8,A(S));for(let S=8;S<15;S++)x(8,y-15+S,A(S));x(8,y-8,!0)};if(I(0),r>=7){let g=r;for(let _=0;_<12;_++)g=g<<1^(g>>>11)*7973;let w=r<<12|g;for(let _=0;_<18;_++){let M=(w>>>_&1)!==0,A=y-11+_%3,S=Math.floor(_/3);x(A,S,M),x(S,A,M)}}let P=0;for(let g=y-1;g>=1;g-=2){g===6&&(g=5);for(let w=0;w<y;w++)for(let _=0;_<2;_++){let M=g-_,S=(g+1&2)===0?y-1-w:w;!C[S][M]&&P<v.length*8&&(b[S][M]=(v[P>>>3]>>>7-(P&7)&1)!==0,P++)}}let L=g=>{for(let w=0;w<y;w++)for(let _=0;_<y;_++){if(C[w][_])continue;let M;switch(g){case 0:M=(_+w)%2===0;break;case 1:M=w%2===0;break;case 2:M=_%3===0;break;case 3:M=(_+w)%3===0;break;case 4:M=(Math.floor(_/3)+Math.floor(w/2))%2===0;break;case 5:M=_*w%2+_*w%3===0;break;case 6:M=(_*w%2+_*w%3)%2===0;break;default:M=((_+w)%2+_*w%3)%2===0}M&&(b[w][_]=!b[w][_])}},R=Number.isInteger(e.mask)?e.mask:-1;if(R<0){let g=1/0;for(let w=0;w<8;w++){L(w),I(w);let _=Nr(b,y);_<g&&(g=_,R=w),L(w)}}return L(R),I(R),{version:r,size:y,mask:R,modules:b}}function Nr(n,e){let t=0,i=[];for(let o=0;o<e;o++)i.push(n[o]);for(let o=0;o<e;o++)i.push(n.map(a=>a[o]));for(let o of i){let a=1;for(let c=1;c<=e;c++)c<e&&o[c]===o[c-1]?a++:(a>=5&&(t+=a-2),a=1);let l=o.map(c=>c?"1":"0").join("");for(let c of["10111010000","00001011101"])for(let p=l.indexOf(c);p>=0;p=l.indexOf(c,p+1))t+=40}let r=0;for(let o=0;o<e;o++)for(let a=0;a<e;a++)if(n[o][a]&&r++,a<e-1&&o<e-1){let l=n[o][a];l===n[o][a+1]&&l===n[o+1][a]&&l===n[o+1][a+1]&&(t+=3)}let s=e*e;return t+=Math.floor(Math.abs(r*20-s*10)/s)*10,t}function fn(n,e,{px:t=4,dark:i="#000",light:r="#fff",ecl:s="M"}={}){let o=Ut(e,{ecl:s}),a=o.size+8;n.width=n.height=a*t;let l=n.getContext("2d");l.fillStyle=r,l.fillRect(0,0,a*t,a*t),l.fillStyle=i;for(let c=0;c<o.size;c++)for(let p=0;p<o.size;p++)o.modules[c][p]&&l.fillRect((p+4)*t,(c+4)*t,t,t);return o}function Y(n,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=n,t}async function Bt(n){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(String(n)));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}var Qe="wss://signal.displayxr.org",un=Object.freeze([Qe,"wss://dxr-signal.displayxr.workers.dev"]),pn=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function fe(n=Qe,e={}){if(!n||typeof n!="string")throw Y("no-signaling-url","dxrSignaling(url): url must be a ws:// or wss:// string (omit it for the hosted DisplayXR server)");let t=c=>String(c).replace(/\/+$/,""),i=t(n),r=e.WebSocket||globalThis.WebSocket,s=e.pingMs||2e4,o=Array.isArray(e.aliases)?e.aliases.filter(c=>typeof c=="string"&&c).map(t):un.includes(i)?[...un]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,p){let h=`k=${await Bt(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=L=>`${a[L]}/v1/connect?${h}`,m=null,u=!1,v=0,y=null,b=new Set,C=[],x=L=>O(L,a.length),O=(L,R)=>new Promise((g,w)=>{let _=!1,M=!1,A=!1,S=new r(d(l));m=S;let F=z=>{if(!_){_=!0;try{S.close()}catch{}w(z)}};S.onopen=()=>{A=!0,S.send(JSON.stringify({t:"join",v:1,room:c,id:p.id,max:p.maxPeers}))},S.onmessage=z=>{let k;try{k=JSON.parse(typeof z.data=="string"?z.data:String(z.data))}catch{return}switch(k.t){case"welcome":{v=0;let j=Array.isArray(k.peers)?k.peers.filter($=>typeof $=="string"):[];clearInterval(y),y=setInterval(()=>T({t:"ping"}),s);let me=C;C=[];for(let $ of me)T($);if(L){let $=new Set(j);for(let Z of b)$.has(Z)||p.onPeerLeft?.(Z);b=$,p.onReconnect?.(j)}else b=new Set(j);_=!0,M=!0,g({id:k.id,peers:j,iceServers:Array.isArray(k.iceServers)?k.iceServers:void 0,max:k.max,tier:k.tier==="key"?"key":"anon",key:typeof k.key=="string"?k.key:void 0,turn:k.turn&&typeof k.turn=="object"?k.turn:void 0});break}case"full":u=!0,F(Y("room-full",`this call is full (${k.max} participants)`));break;case"expired":{u=!0,clearInterval(y);let j=Y("expired","this room has reached its lifetime on the signalling server");_?p.onDisconnect?.(j):F(j);break}case"error":if(!_&&pn.includes(k.code))u=!0,F(Y(k.code,k.message||k.code));else if(!_&&(k.code==="rate-limited"||k.code==="quota")){let j=Y(k.code,k.message||k.code);j.retryMs=k.retryMs>0?k.retryMs:0,F(j)}else!_&&k.code==="id-taken"&&F(Y("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof k.id=="string"&&!b.has(k.id)&&(b.add(k.id),p.onPeerJoined?.(k.id));break;case"peer-left":typeof k.id=="string"&&(b.delete(k.id),p.onPeerLeft?.(k.id));break;case"signal":typeof k.from=="string"&&p.onSignal?.(k.from,k.data);break}},S.onerror=()=>{if(!A&&!_&&R>1){_=!0,l=(l+1)%a.length,O(L,R-1).then(g,w);return}F(Y("signaling-unreachable",`cannot reach ${a[l]}`))},S.onclose=()=>{clearInterval(y),F(Y("signaling-closed","signalling closed before joining")),M&&!u&&m===S&&I()}}),T=L=>{m&&m.readyState===1?m.send(JSON.stringify(L)):u||C.push(L)},I=()=>{p.onDisconnect?.();let L=()=>{u||x(!0).catch(R=>{if(u||R&&(R.code==="room-full"||pn.includes(R.code))){p.onDisconnect?.(R);return}setTimeout(L,Math.max(B(v++,{baseMs:500,maxMs:15e3}),R&&R.retryMs||0))})};setTimeout(L,B(v++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(L,R)=>T({t:"signal",to:L,data:R}),leave:()=>{if(!u){u=!0,clearInterval(y);try{m&&m.readyState===1&&m.send(JSON.stringify({t:"leave"})),m&&m.close(1e3,"leave")}catch{}}}}}}}var qt=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),gn=n=>typeof n=="string"&&qt[n.toLowerCase()]||n,_n=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),De=Object.freeze({lobbyStartTitle:"Start a 3D call",lobbyJoinTitle:"Join the 3D call",lobbyFullTitle:"This call is full",lobbyLeftTitle:"You left the call",lobbyFullText:"It already has {maxPeers} participants.",lobbyText:"Check your framing below. Camera: {camera} \u2014 {kind}.",cameraDefault:"default",kindBusy:"busy (joining audio-only)",kindNone:"none (joining audio-only)",kindSbs:"sending 3D (side-by-side, {width}\xD7{height})",kindMono:"sending 2D ({width}\xD7{height})",liftOff:"Mono cameras: 2D (2D\u21923D is off).",liftChecking:"Mono cameras: checking 2D\u21923D\u2026",liftMissing:"Mono cameras: 2D\u21923D unavailable in this build.",liftNoProvider:"Mono cameras: 2D (no 2D\u21923D provider here).",liftNative:"Mono cameras: 2D\u21923D (native{provider}).",liftWeb:"Mono cameras: 2D\u21923D (in this page, WebGPU).",liftProven:"Mono cameras: 2D\u21923D.",liftUnproven:"Mono cameras: 2D\u21923D (confirmed on the first mono participant).",start:"Start 3D call",join:"Join call",rejoin:"Rejoin",retryCamera:"Retry camera",cameraSelect:"Camera",joining:"Joining\u2026",waitingTitle:"Waiting for others",waitingText:"Share this link (or scan the code). Anyone who opens it joins \u2014 keep it private.",inviteTitle:"Invite",inviteText:"Anyone with this link can join.",inviteLink:"Invite link",copyLink:"Copy link",copied:"Copied",pressCopy:"Press Ctrl/Cmd+C",qrLabel:"QR code of the invite link",banner2D:"You are seeing this call in 2D.",bannerLink:"View in 3D with DisplayXR Browser",mute:"Mute microphone",unmute:"Unmute microphone",cameraOn:"Turn camera on",cameraOff:"Turn camera off",cameraRetry:"No camera \u2014 click to retry",cameraBusyRetry:"{cameraBusy} \u2014 click to retry",depth:"Depth",invite:"Invite",leave:"Leave call",connecting:"Connecting\u2026",reconnecting:"Reconnecting\u2026",leftCall:"Left the call",cameraOffPlate:"Camera off",noCamera:"No camera",unreachable:"Can't reach this participant \u2014 the network needs a relay (TURN)",cameraBusy:"Camera busy \u2014 in use by another app (e.g. eye tracking)",you:"You",badge3D:"3D",badge2D3D:"2D\u21923D",badge2D:"2D",badgePending:"\u2026"});function vn(n){let e={...De,...n&&typeof n=="object"?n:{}};return(t,i)=>{let r=typeof e[t]=="string"?e[t]:De[t]||t;if(i)for(let[s,o]of Object.entries(i))r=r.split(`{${s}}`).join(String(o));return r}}var mn="dxr-call-style",Vr=`
|
package/index.d.ts
CHANGED
|
@@ -280,6 +280,14 @@ export interface SceneOptions extends TileOptions {
|
|
|
280
280
|
* mono path). NOT called when a lazy tile merely scrolls off screen — that layer is coming
|
|
281
281
|
* back. A throw is caught and warned about.
|
|
282
282
|
*/
|
|
283
|
+
/**
|
|
284
|
+
* This caller sizes the canvas within the device's GL limits itself, so the core must not
|
|
285
|
+
* inspect its drawing buffer. With it the core never calls `getContext()` on the canvas, which
|
|
286
|
+
* matters for an engine that creates its context AFTER `addScene` (asynchronously): a core
|
|
287
|
+
* `getContext()` would create it first, with the default attributes. The SDK's own renderers
|
|
288
|
+
* pass it. Default false.
|
|
289
|
+
*/
|
|
290
|
+
bufferClamped?: boolean;
|
|
283
291
|
onLayerLost?: () => void;
|
|
284
292
|
}
|
|
285
293
|
|
|
@@ -525,6 +525,7 @@ export function attachPlayCanvasModel(out, wall, canvas, src, opts, pending = []
|
|
|
525
525
|
? { viewRig: pageViewRig({ verticalFovDeg: viewer.page.fov, convergence: 2, comfortDepth: ctl.comfortDepth }) }
|
|
526
526
|
: { virtualDisplayHeight }),
|
|
527
527
|
onLayerLost: viewer.onLayerLost,
|
|
528
|
+
bufferClamped: true, // this viewer clamps its own buffer; the core must never touch its context
|
|
528
529
|
...(observe ? { observe } : {}),
|
|
529
530
|
...(firstWovenHoldMs !== undefined ? { firstWovenHoldMs } : {}),
|
|
530
531
|
});
|
package/js/inline3d-model.js
CHANGED
|
@@ -420,6 +420,7 @@ export function addModel(wall, canvas, src, opts = {}) {
|
|
|
420
420
|
// The layer can go away for good (the session ends, the constructor refuses): take the
|
|
421
421
|
// canvas flat rather than leave its last side-by-side frame on the page (web#28).
|
|
422
422
|
onLayerLost: viewer.onLayerLost,
|
|
423
|
+
bufferClamped: true, // this viewer clamps its own buffer; the core must never touch its context
|
|
423
424
|
...(observe ? { observe } : {}),
|
|
424
425
|
...(firstWovenHoldMs !== undefined ? { firstWovenHoldMs } : {}),
|
|
425
426
|
});
|
|
@@ -3544,6 +3544,7 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
|
|
|
3544
3544
|
? { viewRig: (initialViewRig = pageViewRig({ verticalFovDeg: viewer.page.fov, convergence: 2, comfortDepth: ctl.comfortDepth })) }
|
|
3545
3545
|
: { virtualDisplayHeight }),
|
|
3546
3546
|
onLayerLost: viewer.onLayerLost,
|
|
3547
|
+
bufferClamped: true, // this viewer clamps its own buffer; the core must never touch its context
|
|
3547
3548
|
...(observe ? { observe } : {}),
|
|
3548
3549
|
...(firstWovenHoldMs !== undefined ? { firstWovenHoldMs } : {}),
|
|
3549
3550
|
});
|
package/js/inline3d-splat.js
CHANGED
|
@@ -479,6 +479,7 @@ export function addSplat(wall, canvas, src, opts = {}) {
|
|
|
479
479
|
// The layer can go away for good (the session ends, the constructor refuses): take the
|
|
480
480
|
// canvas flat rather than leave its last side-by-side frame on the page (web#28).
|
|
481
481
|
onLayerLost: viewer.onLayerLost,
|
|
482
|
+
bufferClamped: true, // this viewer clamps its own buffer; the core must never touch its context
|
|
482
483
|
...(observe ? { observe } : {}),
|
|
483
484
|
...(firstWovenHoldMs !== undefined ? { firstWovenHoldMs } : {}),
|
|
484
485
|
});
|
package/js/inline3d.js
CHANGED
|
@@ -1015,6 +1015,9 @@ class Inline3D {
|
|
|
1015
1015
|
const win = this._register(canvas, 'scene', { virtualDisplayHeight: 0.24, ...opts });
|
|
1016
1016
|
win.onFrame = onFrame;
|
|
1017
1017
|
win.ownsBuffer = false; // the app sizes a scene canvas; we never touch canvas.width/height
|
|
1018
|
+
// The SDK's own renderers (./viewer, ./splat, ./model) clamp their buffers before sizing and
|
|
1019
|
+
// say so, so the core never inspects (or creates!) their GL context — see _checkSceneBuffer.
|
|
1020
|
+
if (opts.bufferClamped === true) win.warnedBufMismatch = true;
|
|
1018
1021
|
return this._handle(canvas, win);
|
|
1019
1022
|
}
|
|
1020
1023
|
|
|
@@ -2506,8 +2509,15 @@ class Inline3D {
|
|
|
2506
2509
|
* splitting canvas.width: the eye boundary lands off-centre and the panel shows a double image.
|
|
2507
2510
|
* Say so once. ./viewer, ./splat and ./model clamp before sizing and never trip this.
|
|
2508
2511
|
*
|
|
2509
|
-
* Only called after the app has
|
|
2510
|
-
* getContext() of the same type returns it, of another type
|
|
2512
|
+
* Only called after the app's onFrame has run a stereo frame. For a page that draws there, the
|
|
2513
|
+
* canvas already HAS its context: getContext() of the same type returns it, of another type
|
|
2514
|
+
* returns null. NOT for an engine that boots asynchronously (PlayCanvas: the onFrame runs, draws
|
|
2515
|
+
* nothing, the device is created later). There getContext() here CREATES the context — with the
|
|
2516
|
+
* default attributes, antialias:true among them — and the engine's own getContext() then gets
|
|
2517
|
+
* that one back, its attributes ignored: a multisampled default framebuffer the engine never
|
|
2518
|
+
* asked for, which its MSAA resolve cannot blit into (GL_INVALID_OPERATION, nothing drawn —
|
|
2519
|
+
* every addModel tile, 1.28.0–1.32.0). The SDK's renderers opt out (`bufferClamped`); a page
|
|
2520
|
+
* with an async engine should create its context before addScene.
|
|
2511
2521
|
*/
|
|
2512
2522
|
_checkSceneBuffer(win) {
|
|
2513
2523
|
const c = win.canvas;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.33.
|
|
3
|
+
"version": "1.33.1",
|
|
4
4
|
"description": "Turn any HTML <canvas> into a 3D window on a spatial display, inside an ordinary web page, for the DisplayXR Browser. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|