@displayxr/inline3d 1.31.0 → 1.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -0
- package/call.d.ts +6 -1
- package/dist/call.js +4 -4
- package/index.d.ts +36 -0
- package/js/call/signaling.js +14 -6
- package/js/inline3d-display-metrics.js +51 -0
- package/js/inline3d-splat-deferred.js +12 -0
- package/js/inline3d-splat-effects.js +92 -2
- package/js/inline3d-splat-playcanvas.js +270 -3
- package/js/inline3d-splat.js +14 -0
- package/js/inline3d.js +21 -0
- package/package.json +2 -1
- package/splat.d.ts +69 -1
package/dist/call.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* @displayxr/inline3d 1.
|
|
2
|
-
var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),Tn=["high","normal","low","paused"],Cn=.02,Rn=1e3/20,Dn=3e3,Ln=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 An(){return import(it())}async function nt(n,{importer:e=An,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 m=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,u=null;if(m){try{u=await m(r)}catch{u=null}let h=!!(u&&u.webFallback&&u.webFallback.webgpu);if(u&&!u.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(u&&u.native),provider:u&&u.provider||null}),{lift:c,capabilities:m,caps:u,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)<Cn?"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||!Tn.includes(e)||typeof n.setPriority!="function")return!1;try{return n.setPriority(e)!==!1}catch{return!1}}function st({degradedMs:n=Rn,recoveredMs:e=Ln,holdMs:t=Dn,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),m=(h,d)=>{if(!d.handle)return;let p=Le({id:h,speakerId:o,visible:d.visible});if(p===d.priority)return;d.priority=p;let f=rt(d.handle,p);c("lift-priority",{peer:h,priority:p,applied:f})},u={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:p,visible:f=!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:f}),x={gen:b,handle:null,visible:f,priority:C,pending:null};s.set(h,x);let I={quality:"auto",...r,mode:"live",wall:p,ui:"none",convergence:ve(a),priority:C};return c("lift-acquire",{peer:h,priority:C,convergence:I.convergence}),x.pending=Promise.resolve().then(()=>n(d,I)).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,m(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()])u.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,p]of s)m(d,p)},setVisible(h,d){let p=s.get(h);!p||p.visible===!!d||(p.visible=!!d,m(h,p))},setDepth(h){a=h;let d=ve(h);for(let p of s.values())p.handle&&typeof p.handle.setConvergence=="function"&&p.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 u}var In=null;function ni(n){In=typeof n=="function"?n:null}var Pn=new WeakMap;function ri(n,e){n&&(typeof n=="object"||typeof n=="function")&&Pn.set(n,e)}var si=new WeakMap,J;function oi(n){let e=null;for(let[t,i]of n)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function Fn(n){if(!n||typeof n.getParameter!="function")return null;let e=si.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=oi([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=oi([["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 si.set(n,c),c}function ai(){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=Fn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function li(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,m=Math.min(l,c);if(!(m<1))return a;let u=l<=c,h=Math.max(1,Math.min(Math.floor(n*m+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*m+1e-9),Math.floor(t.maxH/r)));return{eyeW:h,eyeH:d,cols:i,scale:m,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*r,limitName:u?t.nameW:t.nameH,limitValue:u?t.valueW:t.valueH}}function at(n){return Math.round(n*1e3)/1e3}function ci(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 di(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 hi(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 jn(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",fi="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,m=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=m,a&&!l?(this._phase=fi,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?m: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)*jn(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===fi?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 Nn=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Oe=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,ht=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Wn=["getDisplayInfo","getRenderingModes","requestRenderingMode"],xi=["renderingmodechange","hardwaredisplaystatechange"],gt="trackingstatechange",Si=["unknown","tracking","searching"],pi=[...xi,gt];function Ie(n){try{let e=n?n.trackingState:void 0;return Si.includes(e)?e:null}catch{return null}}var ft=()=>{if(!Q())return!1;try{let n=window.XRDisplayLayer.prototype;return Wn.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 zn(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 mi=!1;function pt(){mi||(mi=!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 Mi(){return Nn()&&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 Hn(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 Vn=16;function V(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var $n=1200,gi=!1;function Un(n){if(n==null)return ie;let e=dt(n);return e||(gi||(gi=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(n)} } }) is not a curve this SDK knows (${ct.join(" / ")}); using '${ie}'.`)),ie)}var _i=!1;function Bn(){_i||(_i=!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 Ei(n){let e=_t(n);return e!==void 0?[e,n]:[n]}function qn(n){for(let e of Ei(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 Xn(n){for(let e of Ei(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 vi=!1;function Gn(){vi||(vi=!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 yi=!1;function Jn(){yi||(yi=!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 ki(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(!Mi())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(m){return{supported:!1,trackingState:"unknown",error:m}}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=ki(n).finally(()=>{we=null}),we)}var wi=.7,Kn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Yn(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(Kn.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 Zn=4;function bi(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,Un(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Ie(e)!==null,this._trackingState=this._trackingSupported?Ie(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||!Oe()||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 Yn(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=er(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&&Jn();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()"),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),Hn(e.viewRig||mt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&Bn(),!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 Gn(),!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())},Vn))}_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=Xn(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=qn(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(!pi.includes(e))throw new TypeError(`[inline3d] on() knows ${pi.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=xi.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:Qn(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(()=>{})),zn(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<wi||c/o<wi?!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||!Oe()||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||!Oe()))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()||!Oe()||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=li(r,s,ai(),{cols:t?2:1});return l.clamped&&(o*=l.scale,r=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(ci("[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=di(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(hi("[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:f,h:v}=this._eyeSize(e,e.sbs);(f!==e.eyeW||v!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let m=e.bufScale||1,u=e.cornerRadius*m,h=e.feather*m;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,u,h);return}let d=s.width/2,p=Math.min(this._stereoFactor,this._bakedStereo);if(p<1){Pe(o,r,0,0,a/2,l,0,0,d,s.height,u,h),tr(o,r,a/2,l,d,s.height,p,u,h);return}u>0||h>0?(Pe(o,r,0,0,a/2,l,0,0,d,s.height,u,h),Pe(o,r,a/2,0,a/2,l,d,0,d,s.height,u,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(Ie(e)||"unknown")})}_setTrackingState(e){let t=Si.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(Ie(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>=Zn*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:bi(e.canvas)},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=bi(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 Qn(n){return typeof n=="number"&&Number.isFinite(n)&&n>=0?n:$n}function er(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,m,u){m>0&&n.roundRect?(n.save(),n.beginPath(),n.roundRect(o,a,l,c,m),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),u>0&&Ti(n,o,a,l,c,u)}function tr(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&&Ti(n,r,0,r,s,l)}function Ti(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,m,u,h,d]of a){let p=n.createLinearGradient(h[0],h[1],d[0],d[1]);p.addColorStop(0,"rgba(0,0,0,1)"),p.addColorStop(1,"rgba(0,0,0,0)"),n.fillStyle=p,n.fillRect(l,c,m,u)}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 Ci(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=Ci(n,e);return r===null||!(t>0)||!(i>0)?0:r*t/(2*i)}function Ne(n,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,n||0))}function We(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 Ne(t+n.depth*.05*e,e)},step(e){return n.current=We(n.current,n.target(e)),n.current}};return n}var ze=1,wt="inline3d-call/1",Ri=Object.freeze(["sbs","mono"]),ae=4,Di=4,bt=5,ir=150,nr=5e3,rr=/^[A-Za-z0-9_-]{16,64}$/,sr=16;function xt(n){let e=new Uint8Array(sr);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ai(e)}function Li(n){let e=new Uint8Array(8);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ai(e)}function Ai(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"&&rr.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:Ri.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:Ri.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>=ir&&e<=nr?{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 ar(n,e=Me){let t=e.indexOf(String(n||"").toUpperCase());return t<0?e.length:t}function $e(n,e=Me){let t=i=>ar(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.0 — 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,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
|
-
`,i=n.split(t),r=i.findIndex(d=>d.startsWith("m=video"));if(r<0)return n;let s=i.findIndex((d,p)=>p>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 p=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);p&&a.set(p[1],p[2].toUpperCase());let f=d.match(/^a=fmtp:(\d+) apt=(\d+)/);f&&(l.has(f[2])||l.set(f[2],[]),l.get(f[2]).push(f[1]))}let c=i[r].split(" "),m=c.slice(3),u=[];for(let d of e)for(let p of m)if(a.get(p)===d&&!u.includes(p)){u.push(p);for(let f of l.get(p)||[])m.includes(f)&&!u.includes(f)&&u.push(f)}if(!u.length)return n;let h=m.filter(d=>!u.includes(d));return i[r]=[...c.slice(0,3),...u,...h].join(" "),i.join(t)}var Ii=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),cr=4e3,dr=1e4,hr=2e4,fr=8e3,ur=1e4;function Te(n){let e=Number.isInteger(n)?n:ae;return Math.max(2,Math.min(Di,e))}function Pi(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:ur,this.signaling=e,this.id=t,this.maxPeers=Te(i),this.pageIce=r||null,this.iceServers=r||Ii,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:m,onGhost:u}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:m,onGhost:u};let h=f=>(...v)=>this.ready?f(...v):this._pending.push(()=>f(...v));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(f=>this._onPeerJoined(f)),onPeerLeft:h(f=>this._onPeerLeftSignaling(f)),onSignal:h((f,v)=>this._onSignal(f,v)),onDisconnect:f=>m?.(f?"closed":"reconnecting",f),onPeerUnreachable:h(f=>u?.(f,!0)),onPeerReachable:h(f=>u?.(f,!1)),onReconnect:h(f=>{m?.("connected");for(let v of f)this._onPeerJoined(v)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Ii,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let f=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw f.code="room-full",f}this.ready=!0;for(let f of d)this._onPeerJoined(f);let p=this._pending;this._pending=[];for(let f of p)f();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"&&Pi(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),fr)}_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:Pi(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(m=>m.kind==="audio"),a=s.find(m=>m.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,hr,()=>{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,cr,()=>{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,dr,()=>{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 Fi={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},Dt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},pr=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function mr(n){return!!n&&(n.name==="NotReadableError"||n.name==="TrackStartError"||/in use|busy/i.test(n.message||""))}function gr(n){return!!n&&(n.name==="NotAllowedError"||n.name==="PermissionDeniedError"||n.name==="SecurityError")}function ji(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 p=n.getVideoTracks()[0],f=p?p.getSettings():{},v=e.format==="sbs"?"sbs":"mono";return{stream:n,format:v,width:f.width||0,height:f.height||0,deviceId:f.deviceId||null,label:p?p.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 p=>{let f=await t.getUserMedia({video:p,audio:!1}),v=f.getVideoTracks()[0],y=v?v.getSettings():{};if(!v||v.readyState==="ended"||!(y.width>0)||!(y.height>0))throw f.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:f,track:v,width:y.width,height:y.height,deviceId:y.deviceId||null,label:v.label||"",stereo:b}},a=(p,f)=>{r.push({label:p,error:`${f.name}: ${f.message}`,busy:mr(f),denied:gr(f)}),i("camera-skip",{label:p,error:f.name})},l=p=>p&&p.stream.getTracks().forEach(f=>f.stop()),c=(p,f)=>({stream:p.stream,format:f,width:p.width,height:p.height,deviceId:p.deviceId,label:p.label,owned:!0,skipped:r,calibration:{rectified:!1,...f==="sbs"&&p.stereo?{rectified:!!p.stereo.rectified,...p.stereo.baselineMm>0?{baselineMm:p.stereo.baselineMm}:{},...p.stereo.horizontalFovDeg>0?{hfovDeg:p.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof n=="string"&&!["auto","stereo","mono"].includes(n)){let p;try{p=await o({deviceId:{exact:n},...Dt})}catch(f){throw a(n,f),Object.assign(new Error(`camera unavailable: ${f.message}`),{code:ji(r),skipped:r})}return se(p.width,p.height)?c(p,"sbs"):(l(p),c(await o({deviceId:{exact:n},...Fi}),"mono"))}let m=new Set;if(n!=="mono"){let p=[];try{p=(await t.enumerateDevices()).filter(f=>f.kind==="videoinput"&&f.deviceId&&Lt(f.label))}catch{}for(let f of p){m.add(f.deviceId);let v=null;try{v=await o({deviceId:{exact:f.deviceId},...Dt})}catch(y){a(f.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 u=null;try{u=await o(Fi)}catch(p){a("default",p)}if(n==="mono"&&u)return c(u,"mono");if(u&&se(u.width,u.height))return c(u,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(p=>p.kind==="videoinput")}catch{}h.sort((p,f)=>Number(Lt(f.label))-Number(Lt(p.label)));for(let p of h){if(!p.deviceId||u&&p.deviceId===u.deviceId||m.has(p.deviceId))continue;let f=null;try{f=await o({deviceId:{exact:p.deviceId},...Dt})}catch(v){a(p.label,v);continue}if(se(f.width,f.height))return l(u),i("camera-sbs",{label:f.label,width:f.width,height:f.height}),c(f,"sbs");l(f)}if(u)return n==="stereo"&&i("camera-no-stereo",{fallback:u.label}),c(u,"mono");let d=ji(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 Wi(n={}){let e=n.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...pr},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,m){if(s<0||s+a>t||o<0)return-1;let u=0,h=0,d=0,p=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 I=n[C+x];u+=I,h+=I*I,d+=n[b+x]*I}}let f=u/p,v=h/p-f*f;return v<1?-1:(d/p-c*f)/(m*Math.sqrt(v))}function _r(n,e,t,i,r,s){let o=0,a=0;for(let m=0;m<s;m++){let u=(i+m)*e+t;for(let h=0;h<r;h++){let d=n[u+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:m}={}){let u=e/2,{mean:h,std:d}=_r(n,e,i,r,s,o);if(d<6)return null;let p=-2,f=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,u,i,r,i-F,S,s,o,h,d);z>(y.get(F)??-2)&&y.set(F,z),z>p&&(p=z,f=F,v=A)}}},C=l-a>8;if(b(a,l,C?2:1,-c,c),C&&p>-1){let R=f,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(p<-1)return null;let x=-2,I=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,u,i,r,i-M,_,s,o,h,d))}return g};for(let[R,g]of y){if(Math.abs(R-f)<3||g<=x)continue;let _=g>=(y.get(R-2)??-2)&&g>=(y.get(R+2)??-2)&&g>0?I(R):g;_>x&&(x=_)}if(l-a>12&&x>-2&&p-x<(m??.08))return null;let T=Ue(n,e,u,i,r,i-(f-1),r+v,s,o,h,d),O=Ue(n,e,u,i,r,i-(f+1),r+v,s,o,h,d),P=0,L=T-2*p+O;return T>-1&&O>-1&&L<0&&(P=Math.max(-.5,Math.min(.5,.5*(T-O)/L))),{d:f+P,dy:v,c:p}}function vr(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)),m=Math.round(r*(i.roiX1??.85))-s,u=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let p=u;p<=h;p+=o)for(let f=c;f<=m;f+=o){let v=At(n,e,t,f,p,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});v&&v.c>=(i.minNcc??.8)&&d.push({x:f,y:p,...v})}return d}function yr(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,m)=>c-m);return{d:l[l.length>>1],members:a}}}return null}function wr(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 Ot(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",m=0,u=null;if(!l){let C=vr(n,e,t,{...i,block:s,dMax:o,dMin:a});m=C.length;let x=yr(C,i);if(!x)return null;l=wr(x.members,s),u=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),p=Math.round(Math.max(0,Math.min(r-h,l.x-h/2))),f=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),v=u===null?a:Math.max(a,Math.floor(u)-4),y=u===null?o:Math.min(o,Math.ceil(u)+4),b=At(n,e,t,p,f,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:m}:u!==null?{d:u,x:l.x,y:l.y,c:0,method:c,blocks:m}: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 zi(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 br(n,e,t,i,r,s,o,a,l,c){let m=e/2,u=r*s,h=0,d=0;for(let b=0;b<u;b++)h+=i[b],d+=i[b]*i[b];h/=u;let p=Math.sqrt(Math.max(1e-6,d/u-h*h)),f=-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(m-r,o+l);C++){let x=0,I=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+=_,I+=_*_,T+=_*i[R*r+w]}}let O=x/u,P=I/u-O*O;if(P<1)continue;let L=(T/u-O*h)/(Math.sqrt(P)*p);L>f&&(f=L,v=C,y=b)}return{x:v,y,c:f}}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,m,u,h,d={}){let p=m/2,f=d.block||Math.max(8,Math.round(p/20)),v=Math.round(f*3),y=Math.round(f*1.5),b=null;if(o&&o.w===v&&o.h===y){let O=br(c,m,u,o.tpl,v,y,o.x,o.y,t,i);if(O.c>=r){let P=At(c,m,u,O.x,O.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:O})}}let C=({m:O,f:P})=>(o={...o,x:P.x,y:P.y,d:O.d,tpl:zi(c,m,P.x,P.y,v,y)},{d:O.d,x:P.x+v/2,y:P.y+y/2,c:O.c,method:"track",blocks:0});if(b&&h-o.at<n)return C(b);let x=Ot(c,m,u,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let O=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!O?{d:x.d}:null,!O)return o.at=h,C(b)}else a=null;if(!x)return o=null,null;let I=Math.round(Math.max(0,Math.min(p-v,x.x-v/2))),T=Math.round(Math.max(0,Math.min(u-y,x.y-y/2)));return o={x:I,y:T,d:x.d,tpl:zi(c,m,I,T,v,y),w:v,h:y,at:h},x},reset(){o=null,a=null}}}function Hi(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 p=0;p<a;p++){let f=0;for(let v=0;v<o;v++){let y=e+(d*o+v)*t+p*o;for(let b=0;b<o;b++)f+=n[y+b]}c[d*a+p]=f/h|0}return{img:c,w:a,h:l}}let m=o>>2,u=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+m)*t,p=e+(h*o+u)*t;for(let f=0;f<a;f++){let v=f*o+m,y=f*o+u;c[h*a+f]=n[d+v]+n[d+y]+n[p+v]+n[p+y]>>2}}return{img:c,w:a,h:l}}var Vi="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 xr=n=>String(n).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),de=n=>Math.round(n*1e3)/1e3;function $i(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}="${xr(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="${Vi}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Pt(n){if(typeof n!="string"||!n.includes(Vi))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),It=n=>new TextDecoder().decode(n),Ui=n=>n.length>4&&n[0]===255&&n[1]===216;function*Bi(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 qi(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 Xi(n,e){if(!Ui(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 m of Bi(n)){if(m.marker===225&&qi(m.data,Xe)){o=m;break}if(m.marker===224||m.marker===225)s=m.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(!Ui(n))return null;for(let e of Bi(n))if(e.marker===225&&qi(e.data,Xe))return It(e.data.subarray(Xe.length));return null}var Gi=n=>Pt(Ft(n)),H={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},Sr=n=>n.length>4&&n[0]===26&&n[1]===69&&n[2]===223&&n[3]===163;function Ji(n){let e=[];for(let t=n;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function Ki(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[...Ji(n),...Ki(e.length),...e]}function Mr(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 Yi(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 Er(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 Zi(n){if(!Sr(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 Qi(n,e){let t=Zi(n);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=Mr(e);if(t.unknown){let m=new Uint8Array(n.length+i.length);return m.set(n,0),m.set(i,n.length),m}let r=Math.min(n.length,t.dataStart+t.size),s=r-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=Ki(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 en(n,e,t){let i={},r=(s,o,a)=>{let l=s;for(;l<o;){let c=jt(n,l);if(!c)return;let m=Re(n,l+c.width);if(!m||m.unknown)return;let u=l+c.width+m.width;a(c.id,u,Math.min(o,u+m.size)),l=u+m.size}};return r(e,t,(s,o,a)=>{s===H.Tag&&r(o,a,(l,c,m)=>{if(l!==H.SimpleTag)return;let u=null,h=null;r(c,m,(d,p,f)=>{d===H.TagName?u=It(n.subarray(p,f)):d===H.TagString&&(h=It(n.subarray(p,f)))}),u!==null&&(i[u]=h??"")})}),i}function kr(n){let e=Zi(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||{},...en(n,a,Math.min(t,a+o.size))}),o.unknown){i=i||Tr(n,t);break}r=a+o.size}return i}function Tr(n,e){let t=Ji(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 en(n,i+4+r.width,e)}return null}var tn=n=>Er(kr(n));var he="[inline3d/camera]",sn="inline3d-camera/1",Cr=200,Rr=240,Dr=4e3,Lr=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],Ke=()=>typeof document<"u"&&document&&typeof document.createElement=="function",nn=()=>{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())}`},Ar=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":""}.${Ar(t)}`}var K=(n,e,t={})=>Object.assign(new Error(`${he} ${n}`),{code:e,...t});function rn(n,e=Dr){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 on(n,e,t=Rr){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 Nt=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 rn(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=on(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:sn}}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 rn(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,p)=>l.toBlob(f=>f?d(f):p(K("toBlob produced nothing","encode-failed")),e,t)),m=this._meta(a,s,o),u=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(u=$i(m),c=new Blob([Xi(new Uint8Array(await c.arrayBuffer()),u)],{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-${nn()}`,this.format,c.type||e),xmp:u};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||Lr.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()],m=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...m);let u=new MediaStream(c),h={...l?{mimeType:l}:{},...r?{videoBitsPerSecond:r}:{}},d=new MediaRecorder(u,h),p=[];d.ondataavailable=g=>g.data&&g.data.size&&p.push(g.data);let f=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 m)w.addTrack(_);f=new MediaRecorder(w,h),f.ondataavailable=_=>_.data&&_.data.size&&v.push(_.data)}let x=performance.now(),I=[],T=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&I.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&I.push(g)),d.start(s),f?.start(s),this.log("record-start",{mimeType:l,mono:C,audio:m.length});let O=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),P=o||`clip-${nn()}`,L=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),f&&f.state==="recording"&&f.pause()},resume(){d.state==="paused"&&d.resume(),f&&f.state==="paused"&&f.resume()},async stop(){clearInterval(T),b&&cancelAnimationFrame(b);let[g,w]=await Promise.all([O(d,p),O(f,v)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",M=[...I].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([Qi(new Uint8Array(await Z.arrayBuffer()),Yi({...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 f&&(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 Nt(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 Or(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 Wt(n,e,t,i);return t._views?.add(r),r}var Wt=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(!Or(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),m=l.getContext("2d");if(this.mirror)for(let u of oe(t,i)){let h=u.src==="L"?0:1,d=X(r,i,s,c,h),p=u.dx===0?0:o;m.save(),m.translate(p+o,0),m.scale(-1,1),m.drawImage(e,u.sx+d.sx,d.sy,d.sw,d.sh,0,0,o,a),m.restore()}else for(let u of[0,1]){let h=X(r,i,s,c,u);m.drawImage(e,u*r+h.sx,h.sy,h.sw,h.sh,u*o,0,o,a)}}_sample(e){let t=performance.now();if(t-this._autoAt<Cr)return;this._autoAt=t,this._scratch=this._scratch||document.createElement("canvas");let i=on(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 ln=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],cn=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Ir=[1,0],Vt=10;function dn(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 an=(n,e)=>Math.floor(dn(n)/8)-ln[e][n]*cn[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 Pr(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 Fr(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<=an(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=an(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=cn[t][r],m=ln[t][r],u=Math.floor(dn(r)/8),h=c-u%c,d=Math.floor(u/c),p=Pr(m),f=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-m+(g<h?0:1));w+=_.length;let M=Fr(_,p);g<h&&_.push(0),f.push(_.concat(M))}let v=[];for(let g=0;g<f[0].length;g++)for(let w=0;w<f.length;w++)(g!==d-m||w>=h)&&v.push(f[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 I=(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)}};I(3,3),I(y-4,3),I(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 O=g=>{let w=Ir[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(O(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),O(w);let _=jr(b,y);_<g&&(g=_,R=w),L(w)}}return L(R),O(R),{version:r,size:y,mask:R,modules:b}}function jr(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 m=l.indexOf(c);m>=0;m=l.indexOf(c,m+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 hn(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 m=0;m<o.size;m++)o.modules[c][m]&&l.fillRect((m+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://dxr-signal.displayxr.workers.dev",fn=Object.freeze([Qe,"wss://signal.displayxr.org"]),un=["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):fn.includes(i)?[...fn]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,m){let h=`k=${await Bt(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=L=>`${a[L]}/v1/connect?${h}`,p=null,f=!1,v=0,y=null,b=new Set,C=[],x=L=>I(L,a.length),I=(L,R)=>new Promise((g,w)=>{let _=!1,M=!1,A=!1,S=new r(d(l));p=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:m.id,max:m.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)||m.onPeerLeft?.(Z);b=$,m.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":f=!0,F(Y("room-full",`this call is full (${k.max} participants)`));break;case"expired":{f=!0,clearInterval(y);let j=Y("expired","this room has reached its lifetime on the signalling server");_?m.onDisconnect?.(j):F(j);break}case"error":if(!_&&un.includes(k.code))f=!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),m.onPeerJoined?.(k.id));break;case"peer-left":typeof k.id=="string"&&(b.delete(k.id),m.onPeerLeft?.(k.id));break;case"signal":typeof k.from=="string"&&m.onSignal?.(k.from,k.data);break}},S.onerror=()=>{if(!A&&!_&&R>1){_=!0,l=(l+1)%a.length,I(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&&!f&&p===S&&O()}}),T=L=>{p&&p.readyState===1?p.send(JSON.stringify(L)):f||C.push(L)},O=()=>{m.onDisconnect?.();let L=()=>{f||x(!0).catch(R=>{if(f||R&&(R.code==="room-full"||un.includes(R.code))){m.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(!f){f=!0,clearInterval(y);try{p&&p.readyState===1&&p.send(JSON.stringify({t:"leave"})),p&&p.close(1e3,"leave")}catch{}}}}}}}var qt=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),mn=n=>typeof n=="string"&&qt[n.toLowerCase()]||n,gn=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 _n(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 pn="dxr-call-style",zr=`
|
|
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=`
|
|
6
6
|
.dxr-call-host{--dxr-accent:#4da3ff;--dxr-ink:#fff;--dxr-shell:rgba(16,17,22,.92);--dxr-danger:#ff5a5f;--dxr-radius:12px;
|
|
7
7
|
--dxr-font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
|
|
8
8
|
display:flex;flex-direction:column;gap:12px;color:var(--dxr-ink);
|
|
@@ -83,4 +83,4 @@ var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),Tn=["high"
|
|
|
83
83
|
.dxr-call-depth{display:flex;align-items:center;gap:6px;padding:0 8px;font-size:12px;opacity:.9;}
|
|
84
84
|
.dxr-call-depth input{width:110px;accent-color:var(--dxr-accent);}
|
|
85
85
|
.dxr-call-note{font-size:12px;opacity:.65;}
|
|
86
|
-
`;function vn(n=document){if(n.getElementById(pn))return;let e=n.createElement("style");e.id=pn,e.textContent=zr,(n.head||n.documentElement).appendChild(e)}var ee=n=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${n}"/></svg>`,q={mic:ee("M12 14a3 3 0 0 0 3-3V5a3 3 0 0 0-6 0v6a3 3 0 0 0 3 3zm5-3a5 5 0 0 1-10 0H5a7 7 0 0 0 6 6.92V21h2v-3.08A7 7 0 0 0 19 11z"),micOff:ee("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z"),cam:ee("M17 10.5V7a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-3.5l4 4v-11z"),camOff:ee("M21 6.5l-4 4V7a1 1 0 0 0-1-1H9.82L21 17.18zM3.27 2 2 3.27 4.73 6H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73z"),link:ee("M3.9 12a3.1 3.1 0 0 1 3.1-3.1h4V7H7a5 5 0 0 0 0 10h4v-1.9H7A3.1 3.1 0 0 1 3.9 12zM8 13h8v-2H8zm9-6h-4v1.9h4a3.1 3.1 0 0 1 0 6.2h-4V17h4a5 5 0 0 0 0-10z"),leave:ee("M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85a1 1 0 0 1-1.41-.02L.29 13.08a1 1 0 0 1 0-1.41C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67a1 1 0 0 1 0 1.41l-2.48 2.48a1 1 0 0 1-1.41.02 11.3 11.3 0 0 0-2.66-1.85 1 1 0 0 1-.56-.9v-3.1A15.3 15.3 0 0 0 12 9z"),mutedSmall:ee("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z")};function E(n,e={},t=[]){let i=document.createElement(n);for(let[r,s]of Object.entries(e))s!=null&&(r==="class"?i.className=s:r==="html"?i.innerHTML=s:r==="text"?i.textContent=s:r.startsWith("on")&&typeof s=="function"?i.addEventListener(r.slice(2),s):r in i&&typeof s!="string"?i[r]=s:i.setAttribute(r,s));for(let r of[].concat(t))r&&i.appendChild(typeof r=="string"?document.createTextNode(r):r);return i}var N=(n,e)=>n&&n.classList.toggle("dxr-call-hidden",!e);var wn="[inline3d/call]",Hr="https://github.com/DisplayXR/displayxr-browser",bn=Object.freeze({accent:"theme.accent",tileAspect:"theme.tileAspect",inviteBase:"invite.base",updateUrl:"invite.updateUrl",browserUrl:"landing.browserUrl",maxLifted:"liftOptions.max",calibration:"openCamera({ calibration }) of '@displayxr/inline3d/camera' (pass the camera as `camera`)",rectify:"openCamera({ rectify }) of '@displayxr/inline3d/camera'",log:"debug: true (and diagnostics())",recoverSession:"nothing \u2014 a call always recovers the document's session (sharedInline3D())",wallOptions:"sharedInline3D(opts) \u2014 the document's wall is configured by the page",scrollIntoView:"nothing \u2014 always on with ui: true"}),yn=new Set;function Vr(n){yn.has(n)||(yn.add(n),console.warn(`${wn} option \`${n}\` is deprecated (removed in 1.31) \u2014 use ${bn[n]}`))}function Xt(n={}){for(let v of Object.keys(bn))n[v]!==void 0&&Vr(v);let e=n.theme&&typeof n.theme=="object"?n.theme:{},t=n.invite&&typeof n.invite=="object"?n.invite:{},i=n.landing&&typeof n.landing=="object"?n.landing:{},r=n.ui===void 0?!0:n.ui==="tiles"?"tiles":!!n.ui,s=r===!0,o=e.tileAspect!==void 0?e.tileAspect:n.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=n.room===void 0||n.room===null?"auto":n.room;if(l!=="auto"&&!le(l)){let v=Se(l);if(!v)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=v}let c=n.liftOptions&&typeof n.liftOptions=="object"?{...n.liftOptions}:null,m=c&&c.max!==void 0?c.max:n.maxLifted;c&&delete c.max;let u=e.accent!==void 0?e.accent:n.accent,h={};for(let[v,y]of Object.entries(gn)){let b=v==="accent"?u:e[v];typeof b=="string"&&b?h[y]=v==="accent"?mn(b):b:typeof b=="number"&&v==="radius"&&(h[y]=`${b}px`)}let d=t.base!==void 0?t.base:n.inviteBase,p=t.updateUrl!==void 0?t.updateUrl:n.updateUrl,f=i.browserUrl!==void 0?i.browserUrl:n.browserUrl;return{room:l,signaling:n.signaling||fe(void 0,typeof n.key=="string"&&n.key?{key:n.key}:{}),iceServers:Array.isArray(n.iceServers)?n.iceServers:void 0,camera:n.camera===void 0?"auto":n.camera,format:n.format==="sbs"?"sbs":n.format==="mono"?"mono":void 0,calibration:n.calibration&&typeof n.calibration=="object"?{...n.calibration}:{},rectify:typeof n.rectify=="function"?n.rectify:null,audio:n.audio===void 0?!0:!!n.audio,autoConverge:n.autoConverge===void 0?!0:!!n.autoConverge,mono3D:ye(n.mono3D),maxPeers:Te(n.maxPeers===void 0?ae:n.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+m)&&m!==null&&m!==void 0?Math.max(0,Math.min(ae,Math.floor(+m))):ae,layout:n.layout==="speaker"?"speaker":n.layout==="none"?"none":"grid",ui:r,chrome:s,autoJoin:n.autoJoin===void 0?!s:!!n.autoJoin,selfView:n.selfView===void 0?!0:!!n.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:p===void 0?s:!!p},landing:{browserUrl:typeof f=="string"?f:Hr,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!n.debug,log:typeof n.log=="function"?n.log:n.debug?(v,y)=>console.log(`${wn} ${v} ${JSON.stringify(y)}`):null,_liftImporter:typeof n._liftImporter=="function"?n._liftImporter:void 0}}var Ns=Object.freeze(["normalizeCallOptions","newRoomId","isValidRoomId","buildInviteLink","normalizeHello","makeHello","routeFor","badgeFor","createLiveGate","convergenceShiftPx","lowPass","clampShift","eyeCropRect","mirrorSwapOps","mirrorSwapPixels","maxBitrateKbps","measureFocusDisparity","preferVideoCodecs","sortCodecCapabilities","VIDEO_CODEC_ORDER","MeshTransport","clampMaxPeers","qrEncode","roomKey","SIGNAL_PROTOCOL","WIRE_VERSION","CALL_SDK","PLATE_TEXT","CALL_ACCENTS","normalizeMono3D","resolveLift","createLiftPool","createFrameWatch","liftConvergenceFor","liftPriorityFor","setLiftPriority","defaultLiftSpecifier","LIFT_PRIORITY"]);var Jt="dxr-call:",$r=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],Gt="[inline3d/call] <dxr-call>",ue=n=>n!=null&&!/^(false|0|off|no)$/i.test(String(n).trim()),xn=n=>{if(n==null||String(n).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(n)),t=e?+e[1]/+e[2]:+n;return Number.isFinite(t)?t:void 0},W=n=>n==null||String(n).trim()===""?void 0:String(n).trim();function Kt(n){let e=typeof n=="function"?n:l=>n&&typeof n.getAttribute=="function"?n.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",W(e("room")));let r=W(e("signaling"));r&&(t.signaling=fe(r,W(e("key"))?{key:W(e("key"))}:{})),i("key",W(e("key"))),i("camera",W(e("camera"))),i("layout",W(e("layout"))),i("maxPeers",xn(e("max-peers")));let s=W(e("ui"));ue(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),ue(e("auto-join"))&&(t.autoJoin=!0);let o=W(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),ue(e("no-audio"))&&(t.audio=!1),ue(e("no-self-view"))&&(t.selfView=!1),ue(e("no-auto-converge"))&&(t.autoConverge=!1);let a={accent:W(e("accent")),tileAspect:xn(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),W(e("invite-base"))&&(t.invite={base:W(e("invite-base"))}),W(e("browser-url"))&&(t.landing={browserUrl:W(e("browser-url"))}),ue(e("debug"))&&(t.debug=!0),t}var Ur=typeof HTMLElement=="function"?HTMLElement:class{},pe=class n extends Ur{static mount=null;constructor(){super(),this.options=null,this.call=null,this.ready=null,this._gen=0,this._off=[],this._pending=null}connectedCallback(){if(this.call||this._pending)return;let e=++this._gen,t={...Kt(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||n.mount||Yt;this._pending=new Promise(r=>r(i(this,t))).then(r=>{if(this._pending=null,e!==this._gen)return r.leave(),null;if(this.call=r,this._off=$r.map(s=>r.on(s,o=>this._dispatch(s,o))),this._off.push(r.on("error",s=>console.warn(`${Gt} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:r}),r.state==="in-call"){this._dispatch("joined",{room:r.room,id:r.id});for(let s of r.peers)this._dispatch("peer",{id:s.id})}return r},r=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(r&&r.message||r),error:r||null}),console.warn(`${Gt} mount failed: ${String(r&&r.message||r)}`),r}),this.ready=this._pending,this.ready.catch(()=>{})}disconnectedCallback(){this._gen++;let e=this.call;this.call=null,e&&e.leave();for(let t of this._off)try{t()}catch{}this._off=[]}_dispatch(e,t){typeof CustomEvent!="function"||typeof this.dispatchEvent!="function"||this.dispatchEvent(new CustomEvent(Jt+e,{detail:t,bubbles:!0,composed:!0}))}};function et(n="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(n);return t?(t!==pe&&console.warn(`${Gt} <${n}> is already defined by another class; leaving it`),!1):(e.define(n,pe),!0)}var G="[inline3d/call]",Br=2e3,qr=2500,Xr=500,Zt=.02,Gr=4,Jr=2,Kr=200,Sn=240,Yr=new Set(["I420","I420A","I422","I444","NV12"]);async function kn(n,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=Xt(t);if(!i.signaling||typeof i.signaling.join!="function")throw new TypeError("@displayxr/inline3d/call: opts.signaling must be a SignalingAdapter \u2014 dxrSignaling([url]) or your own");let r=new Qt(n,e,i);return await r._init(),r.handle}async function Yt(n,e={}){if(!n||typeof n.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,r=t||await Fe(i.wallOptions);return kn(r,n,i)}var Qt=class{constructor(e,t,i){this.o=i,this.t=_n(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=Li(),this.room=i.room==="auto"?Se(globalThis.location):i.room,this.state="idle",this.tiles=new Map,this.listeners=new Map,this.local=null,this.muted=!1,this.camOff=!1,this.depth=0,this.speakerId=null,this.transport=null,this._raf=0,this._statsTimer=0,this._hintGate=kt(bt),this.mono3D=i.mono3D,this.mono3DOn=i.mono3D!=="off",this.liftApi=null,this.liftPool=null,this._liftP=null,this.liftProven=!1,this.liftMissing=!1,this._liftWarned=!1,this._frameWatch=st(),this.handle=this._makeHandle(),this.wallLive&&this._hookWall(this.wall)}get woven(){return!!(this.wall&&this.wall.supported&&this.wallLive)}log(e,t={}){this.o.log&&this.o.log(e,t)}emit(e,t){let i=this.listeners.get(e);if(i)for(let r of[...i])try{r(t)}catch(s){console.error(`${G} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${G} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${G} ${e}: ${t}`),this.emit("warning",{code:e,message:t})}async _init(){this._buildDom(),this.wallLive&&this._ensureLift(),await this._openMedia(this.o.camera),this._startLoop(),this.o.autoJoin?await this.join():this._setState("lobby")}async _openMedia(e,t,{keepOnFail:i=!1}={}){let r=(h,d)=>this.log(h,d),s=null,o=null,a=Ze(e)?e:null;try{if(s=a||await zt({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:r}),a&&a.state!=="live")throw Object.assign(new Error("the camera given is not live"),{code:"no-camera",skipped:[]})}catch(h){o=h;let d=h.code==="camera-busy";if(this.error(d?"camera-busy":h.code||"no-camera",d?`${this.t("cameraBusy")}. Joining audio-only.`:`no camera: ${h.message}. Joining audio-only.`,h),i&&this.local&&this.local.videoTrack)return this.local;this.camStatus=d?"busy":"none"}s&&(this.camStatus="ok"),s&&s.rectifyError&&this.error("rectify-failed",`rectify() threw \u2014 sending the raw pair: ${s.rectifyError.message}`,s.rectifyError);let l=this.local?this.local.audioTrack:null;this.o.audio&&!l&&(l=await Wi({log:r})),l&&(l.enabled=!this.muted);let c=s&&s.stream.getVideoTracks()[0]||null;if(c){try{c.contentHint="detail"}catch{}c.enabled=!this.camOff}let m=new MediaStream([c,l].filter(Boolean)),u=this.local;return this.local={stream:m,cam:s,camStream:s?s.stream:null,video:s?s.video:null,videoTrack:c,audioTrack:l,format:s?s.format:"mono",width:s?s.width:0,height:s?s.height:0,calibration:s?s.calibration:{},owned:s?s.owned&&s!==a:!1,label:s?s.label:"",skipped:s?s.skipped:o?.skipped||[]},s&&s!==u?.cam&&(this._camEndedOff?.(),this._camEndedOff=s.on("ended",()=>{this.local?.cam===s&&(this.local.videoTrack=null,this.camStatus="none",this.error("no-camera",'the camera ended (revoked, unplugged, or taken by another app). Audio-only until "Retry camera".'),this.transport?.broadcast(this.stateMsg()),this._refreshSelf(),this._refreshBar())})),this.log("camera",{format:this.local.format,width:this.local.width,height:this.local.height,label:this.local.label,skipped:this.local.skipped.length}),u&&u.owned&&u.cam&&u.cam!==s&&u.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return Mt({format:e.format,width:e.width,height:e.height,baselineMm:e.calibration?.baselineMm,hfovDeg:e.calibration?.hfovDeg,rectified:!!e.calibration?.rectified})}stateMsg(){return{type:"state",muted:this.muted,cameraOff:this.camOff||!this.local?.videoTrack,speaking:!!this._selfSpeaking}}async join(){if(this.state==="joining"||this.state==="in-call")return this.handle;if(this.state==="left"&&!this.local?.videoTrack&&await this._openMedia(this.o.camera),this.room||(this.room=xt(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",He(location.href,this.room))}catch{}this._setState("joining");let e=new ke({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(i,r)=>this.log(i,r)});this.transport=e;let t=null;try{t=await e.start({room:this.room,localStream:this.local.stream,sendFormat:this.local.format,onPeer:i=>this._onPeer(i),onPeerLeft:(i,r)=>this._onPeerLeft(i,r),onStream:(i,r)=>this.tiles.get(i)?.setStream(r),onMessage:(i,r)=>this._onMessage(i,r),onPeerState:(i,r)=>{this.tiles.get(i)?.setConn(r),this.emit("state",{id:i,state:r})},onRefused:i=>this.log("refused-peer",{id:i}),onGhost:(i,r)=>this._onGhost(i,r),onSignalingState:(i,r)=>{this.log("signaling",{state:i}),i==="closed"&&r&&this.error(r.code||"signaling-closed",r.message,r)}})}catch(i){throw this.transport=null,i&&i.code==="room-full"?(this._setState("full"),this.error("room-full",i.message,i)):(this._setState("lobby"),this.error(i.code||"join-failed",`could not join: ${i.message}`,i)),i}if(this._setState("in-call"),this.o.chrome)try{this.container.scrollIntoView?.({block:"start",behavior:"instant"}),this._fitGrid()}catch{}return this._startStats(),this._pagehide=()=>this.leave("pagehide"),globalThis.addEventListener?.("pagehide",this._pagehide),this.log("joined",{id:this.id,peers:this.tiles.size}),this.emit("joined",{room:this.room,id:this.id}),setTimeout(()=>{this.transport===e&&this._reportTurn(t)},0),this.handle}_reportTurn(e){let t=e&&e.turn;!t||typeof t!="object"||(t.status==="off"&&t.reason==="cap"?this.error("turn-cap","relay (TURN) capacity for this month is used up; direct connections still work, but a participant behind a strict NAT may be unreachable",null):(t.reason==="budget"||t.reason==="rate")&&this.warning("turn-shed",t.reason==="rate"?"no relay (TURN) for this session: too many credential requests from this address this hour":"no relay (TURN) for this anonymous session: the hosted service is near its monthly relay budget (a publishable key keeps TURN)"))}_onPeer(e){if(this.tiles.has(e))return;let t=new tt(this,e);this.tiles.set(e,t),this._layout(),this.emit("peer",{id:e})}_onGhost(e,t){let i=this.tiles.get(e);if(t&&!i){let r=new tt(this,e);r.ghost=!0,this.tiles.set(e,r),r.setConn("unreachable"),this._layout()}else!t&&i&&i.ghost&&(i.destroy(),this.tiles.delete(e),this._layout())}_onPeerLeft(e,t){let i=this.tiles.get(e);i&&(i.setConn("left"),this.emit("peerleft",{id:e,reason:t}),i.leaveTimer=setTimeout(()=>{i.destroy(),this.tiles.get(e)===i&&this.tiles.delete(e),this.speakerId===e&&this._setSpeaker(null),this._layout()},qr))}_onMessage(e,t){let i=this.tiles.get(e);if(!i||!t)return;if(t.type==="__open"){this.transport.send(e,this.hello()),this.transport.send(e,this.stateMsg()),i.onChannelOpen();return}let r=St(t);if(r)return i.setHello(r);let s=Et(t);if(s)return i.setHint(s);let o=Oi(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return He(e,this.room)}mute(e){return this.muted=e===void 0?!this.muted:!!e,this.local?.audioTrack&&(this.local.audioTrack.enabled=!this.muted),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this.log("mute",{muted:this.muted}),this.muted}setCameraOff(e){return this.camOff=e===void 0?!this.camOff:!!e,this.local?.videoTrack&&(this.local.videoTrack.enabled=!this.camOff),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this._refreshSelf(),this.camOff}setDepth(e){let t=e==null||!Number.isFinite(+e)?0:Math.max(-1,Math.min(1,+e));this.depth=t;for(let i of this.tiles.values())i.conv.depth=t;return this.liftPool?.setDepth(t),this.ui?.depth&&+this.ui.depth.value!==t&&(this.ui.depth.value=String(t)),t}async setCamera(e,{format:t}={}){let i=this.local?.format,r=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",r.videoTrack,r.stream),await this.transport.setSendFormat(r.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==r.format&&this.log("send-format",{format:r.format}),{format:r.format,width:r.width,height:r.height,label:r.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=Et({type:"hint",subjectZmm:e});return t?(this.transport?.broadcast(t),!0):!1}leave(e="left"){if(this.state!=="left"){globalThis.removeEventListener?.("pagehide",this._pagehide),this.transport?.stop(),this.transport=null;for(let t of this.tiles.values())t.destroy();this.tiles.clear(),this.liftPool?.releaseAll(),clearInterval(this._statsTimer),this._setSpeaker(null),this.local&&(this._camEndedOff?.(),this._camEndedOff=null,this.local.stream.getTracks().forEach(t=>t.stop()),this.local.owned&&this.local.cam?this.local.cam.close():this.local.cam&&this.self?.detach(),this.local.videoTrack=null,this.local.audioTrack=null),this.self?.detach(),this._unhookWall(),this._setState("left"),this._layout(),this.emit("left",{room:this.room,reason:e})}}_hookWall(e){if(!e||!e.session||typeof e.session.addEventListener!="function")return;let t=e.close;this._wallHook={w:e,orig:t,pageClosed:!1};let i=this._wallHook;e.close=(...r)=>(i.pageClosed=!0,t.apply(e,r)),i.onEnd=()=>this._sessionEnded(i),e.session.addEventListener("end",i.onEnd),this._watchLive(e)}_watchLive(e){this.weaveLive=!1;let t=e.session;if(!t||typeof t.requestAnimationFrame!="function"){this.weaveLive=!0;return}let i=Rt(),r=performance.now(),s=(o,a)=>{if(e!==this.wall||!this.wallLive||this.state==="left")return;let l=null;if(e.refSpace)try{let c=a.getViewerPose(e.refSpace);l=c&&c.views?c.views.length:0}catch{l=0}if(!i.feed(l)){try{t.requestAnimationFrame(s)}catch{}return}this.weaveLive=!0,this.log("weave-live",{ms:Math.round(performance.now()-r)});for(let c of this.tiles.values())(c.route==="woven-sbs"||c.route==="lifted")&&c.reroute(!0);this.self&&this.self.route==="woven-sbs"&&this.self.reroute(!0),this._layout()};try{t.requestAnimationFrame(s)}catch{this.weaveLive=!0}}_unhookWall(){let e=this._wallHook;if(e){this._wallHook=null,e.w.close!==e.orig&&(e.w.close=e.orig);try{e.w.session.removeEventListener("end",e.onEnd)}catch{}}}_sessionEnded(e){if(this._wallHook===e){this.wallLive=!1,this.weaveLive=!1,this.log("session-ended",{byPage:e.pageClosed});for(let t of this.tiles.values())t.onWallLost();if(this.self?.onWallLost(),e.pageClosed||this.state==="left"){this._unhookWall();return}this.error("session-ended","the inline-3D session ended; tiles are flat while it is re-opened"),this._unhookWall(),this._recoverWall(0)}}_recoverWall(e){this.state==="left"||e>10||setTimeout(async()=>{if(this.state==="left")return;let t=null;try{t=await Fe()}catch{t=null}if(!t||!t.supported)return this._recoverWall(e+1);this.wall=t,this.wallLive=!0,this._hookWall(t),this.log("session-recovered",{attempt:e});for(let i of this.tiles.values())i.reroute(!0);this.self?.reroute(!0)},B(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let r of this.tiles.values())r.paint();e&&this.liftPool&&this.liftPool.anyWeb&&this._watchFrames(i-e),e=i};this._raf=requestAnimationFrame(t)}_watchFrames(e){let t=this._frameWatch.feed(e);if(!t)return;let i={degraded:t==="degraded",frameMs:Math.round(this._frameWatch.frameMs*10)/10,tiles:this.liftPool.size};this.log("lift-frame-time",i),t==="degraded"&&console.warn(`${G} lifted tiles are slowing the page (~${Math.round(1e3/i.frameMs)} fps with ${i.tiles} lifted) \u2014 setMono3D(false) shows mono peers flat`),this.emit("quality",{id:null,in:null,out:null,lift:i})}_ensureLift(){if(!this.mono3DOn)return Promise.resolve(null);if(!this._liftP){let e=(r,s)=>this.log(r,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=nt(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(r=>(this.liftApi=r,r.lift?(this.liftPool=ot({lift:r.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!r.caps&&r.capabilities&&Promise.resolve().then(()=>r.capabilities(i)).then(s=>{r.caps=s||null,this._refreshLobby()}).catch(()=>{})):r.reason==="import-failed"||r.reason==="no-lift-export"?this.liftMissing=!0:r.reason!=="off"&&console.info(`${G} mono\u21923D unavailable (${r.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),r))}return this._liftP}_warnLiftMissing(){this._liftWarned||!this.liftMissing||!this.mono3DOn||(this._liftWarned=!0,this.warning("lift-not-bundled","a 2D participant is on a 3D display but the 2D\u21923D module could not be imported from this build, so they stay flat. Import it explicitly \u2014 `import { lift } from '@displayxr/inline3d/lift'; mountCall(el, { mono3D: lift })` \u2014 or use `@displayxr/inline3d/call/full`, which bundles it."))}_rerouteMono(){for(let e of this.tiles.values())e.format&&e.format!=="sbs"&&e.reroute(!1)}setMono3D(e){let t=e===void 0?!this.mono3DOn:!!e;return t===this.mono3DOn||(this.mono3DOn=t,t&&this.mono3D==="off"&&(this.mono3D="auto"),this._frameWatch.reset(),this.log("mono3d",{on:t}),this._rerouteMono(),t&&this.wallLive&&this._ensureLift(),this._refreshLobby()),t}_liftHint(){if(!this.wallLive)return"";let e=this.t;if(!this.mono3DOn)return e("liftOff");let t=this.liftApi;if(!t)return e("liftChecking");if(!t.lift)return this.liftMissing?e("liftMissing"):e("liftNoProvider");let i=t.caps;return i&&i.native?e("liftNative",{provider:i.provider?`, ${i.provider}`:""}):i&&i.webFallback&&i.webFallback.webgpu?e("liftWeb"):this.liftProven?e("liftProven"):e("liftUnproven")}_mono3DInfo(){let e=this.liftApi,t=e&&e.caps;return Object.freeze({on:this.mono3DOn,state:this.mono3DOn?e?e.lift?"ready":"unavailable":this._liftP?"loading":"idle":"off",reason:e?e.reason:null,native:t?!!t.native:null,provider:t&&t.provider||null,lifted:this.liftPool?this.liftPool.size:0,max:this.o.maxLifted,proven:this.liftProven})}_startStats(){clearInterval(this._statsTimer);let e=0;this._statsTimer=setInterval(()=>this._stats(++e%4===0),Xr)}async _stats(e){if(!this.transport)return;let t=null,i=0;for(let[o,a]of this.tiles){let l=this.transport.peerConnection(o);if(!l)continue;let c;try{c=await l.getStats()}catch{continue}let m={};c.forEach(d=>{d.type==="codec"&&(m[d.id]=d.mimeType)});let u={in:null,out:null};c.forEach(d=>{if(d.type==="inbound-rtp"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(a.level=Math.max(d.audioLevel,(a.level||0)*.6)),d.type==="media-source"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(i=Math.max(i,d.audioLevel)),!!e){if(d.type==="inbound-rtp"&&d.kind==="video"){let p=a._prevIn;u.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:m[d.codecId]||null,kbps:p?Math.round((d.bytesReceived-p.bytes)*8/(d.timestamp-p.t)):null,dropped:d.framesDropped||0,decoder:d.decoderImplementation||null},a._prevIn={bytes:d.bytesReceived,t:d.timestamp}}else if(d.type==="outbound-rtp"&&d.kind==="video"){let p=a._prevOut;u.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:m[d.codecId]||null,kbps:p?Math.round((d.bytesSent-p.bytes)*8/(d.timestamp-p.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(u.in||u.out)&&(a.quality=u,this.emit("quality",{id:o,...u}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>Zt||a.remote.speaking),h>Zt&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let r=t?t.id:null;r&&r!==this.speakerId?(this._challengeTicks=this._challenger===r?(this._challengeTicks||0)+1:1,this._challenger=r,this._challengeTicks>=2&&this._setSpeaker(r)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>Zt;s!==!!this._selfSpeaking&&(this._selfSpeaking=s,this.transport?.broadcast(this.stateMsg()),this.self?.setSpeaking(s))}_setSpeaker(e){e!==this.speakerId&&(this.speakerId=e,this._challengeTicks=0,this.liftPool?.setSpeaker(e),this.emit("speaker",{id:e}),this.o.layout==="speaker"&&this._layout())}_fitGrid(){let e=this.ui;if(!e||!this.o.chrome||typeof globalThis.innerHeight!="number")return;let t=this.container.getBoundingClientRect?.(),i=e.grid.getBoundingClientRect?.();if(!t||!i||!i.height)return;let r=Math.max(160,Math.floor(globalThis.innerHeight-Math.max(0,t.top)-(t.height-i.height)-8)),s=parseFloat(this.container.style.getPropertyValue("--dxr-call-fit"))||0;Math.abs(r-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${r}px`),this._fitHooked||(this._fitHooked=!0,globalThis.addEventListener?.("resize",()=>this._fitGrid()))}_setState(e){this.state=e,this.log("state",{state:e}),this._layout()}_buildDom(){let e=this.container,t=this.t;vn(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[r,s]of Object.entries(this.o.cssVars))e.style.setProperty(r,s);let i=this.ui={};i.banner=E("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[E("span",{text:t("banner2D")}),E("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=E("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=E("div",{class:"dxr-call-self",part:"self"}),i.bar=E("div",{class:"dxr-call-bar",part:"bar"}),i.foot=E("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||N(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new ei(this,i.selfSlot):N(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(r,s,o,a="")=>E("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":r,title:r,html:s,onclick:o});e.mic=i(t("mute"),q.mic,()=>this.mute()),e.cam=i(t("cameraOff"),q.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=E("input",{type:"range",min:"-1",max:"1",step:"0.05",value:"0","aria-label":t("depth")}),e.depth.addEventListener("input",()=>this.setDepth(+e.depth.value)),e.depth.addEventListener("dblclick",()=>this.setDepth(0)),e.inviteBtn=i(t("invite"),q.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),q.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,E("label",{class:"dxr-call-depth"},[t("depth"),e.depth]),e.inviteBtn,e.leave)}_refreshBar(){let e=this.ui;if(!e||!e.mic)return;let t=this.t;e.mic.innerHTML=this.muted?q.micOff:q.mic,e.mic.setAttribute("aria-pressed",String(this.muted)),e.mic.title=this.muted?t("unmute"):t("mute");let i=!this.local?.videoTrack;e.cam.innerHTML=this.camOff||i?q.camOff:q.cam,e.cam.setAttribute("aria-pressed",String(this.camOff||i)),e.cam.title=i?this.camStatus==="busy"?t("cameraBusyRetry",{cameraBusy:t("cameraBusy")}):t("cameraRetry"):this.camOff?t("cameraOn"):t("cameraOff")}_refreshSelf(){this.self?.update()}_refreshLobby(){(this.state==="lobby"||this.state==="idle")&&this._layout()}_renderInvite(e,t,i){e.replaceChildren();let r=this.inviteLink();if(!r)return;let s=this.t,o=E("input",{type:"text",readOnly:!0,value:r,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:s("copyLink")});a.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(r),a.textContent=s("copied")}catch{o.select(),a.textContent=s("pressCopy")}setTimeout(()=>a.textContent=s("copyLink"),1800)});let l=E("canvas",{"aria-label":s("qrLabel"),role:"img"});try{hn(l,r,{px:4})}catch{l.style.display="none"}e.append(E("h3",{text:t}),E("p",{text:i}),E("div",{class:"dxr-call-invite"},[E("div",{class:"dxr-call-row",style:"flex:1 1 280px"},[o,a]),l]))}_layout(){let e=this.ui;if(!e)return;let t=this.container,i=this.t,r=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",r),N(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),N(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,m]of this.tiles)m.el.classList.toggle("dxr-call-tile--main",c===o);if(!this.o.chrome)return;this._refreshBar(),queueMicrotask(()=>this._fitGrid());let a=e.panel;if(r){N(a,!0),a.replaceChildren();let c=this.local,m=!!this.room,u=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(m?"lobbyJoinTitle":"lobbyStartTitle"),h={width:c?.width||0,height:c?.height||0},d=this.camStatus==="busy"?i("kindBusy"):!c||!c.videoTrack?i("kindNone"):c.format==="sbs"?i("kindSbs",h):i("kindMono",h),p=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,f=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(m?"join":"start")});f.addEventListener("click",()=>this.join().catch(()=>{}));let v=E("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(v),v.addEventListener("change",()=>this.setCamera(v.value).catch(b=>this.error("camera-failed",b.message,b)));let y=!c||!c.videoTrack?E("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;y?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(E("h3",{text:u}),E("p",{text:p}),E("div",{class:"dxr-call-row"},[this.state==="full"?null:f,y,v]))}else this.state==="in-call"&&s===0?(N(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(N(a,!0),a.replaceChildren(E("p",{text:i("joining")}))):N(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),N(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:wt,wire:ze,state:this.state,wall:this.wall,wallLive:this.wallLive,weaveLive:this.weaveLive,woven:this.woven,local:e?{format:e.format,width:e.width,height:e.height,label:e.label,calibration:e.calibration,owned:e.owned,skipped:e.skipped,camera:e.cam||null,stream:e.stream}:null,hello:this.hello(),transport:this.transport,peers:[...this.tiles.values()].map(t=>t.diag()),mono3D:{...this._mono3DInfo(),lift:this.liftApi,pool:this.liftPool?this.liftPool.list():[]},speaker:this.speakerId,depth:this.depth,options:this.o,kill:t=>this.transport?._debugKill(t)}}async _fillCameras(e){let t=[];try{t=(await navigator.mediaDevices.enumerateDevices()).filter(r=>r.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((r,s)=>E("option",{value:r.deviceId,text:r.label||`Camera ${s+1}`}))),i&&(e.value=i),N(e,t.length>1)}_makeHandle(){let e=this,t={format:"display",session:null},i={get room(){return e.room},get id(){return e.id},get state(){return e.state},get localFormat(){return e.local?e.local.format:null},get muted(){return e.muted},get cameraOff(){return e.camOff},get depth(){return e.depth},get speaker(){return e.speakerId},get camera(){return e.camStatus},get mono3D(){return e._mono3DInfo()},get peers(){return Object.freeze([...e.tiles.values()].map(s=>s.info()))},join:()=>e.join().then(()=>{}),inviteLink:()=>e.inviteLink(),mute:s=>e.mute(s),setCameraOff:s=>e.setCameraOff(s),setCamera:(s,o)=>e.setCamera(s,o),setDepth:s=>e.setDepth(s),retryCamera:()=>e.retryCamera(),setMono3D:s=>e.setMono3D(s),leave:()=>e.leave("left"),tile:s=>e.tiles.get(s)?.el||null,diagnostics:()=>e.diagnostics(),on(s,o){if(typeof o!="function")throw new TypeError(`${G} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${G} the '${s}' event is deprecated (removed in 1.31)${a?` \u2014 listen for '${a}'`:" \u2014 it is internal now; diagnostics() has the wall"}`)}return e.listeners.has(s)||e.listeners.set(s,new Set),e.listeners.get(s).add(o),()=>e.listeners.get(s)?.delete(o)},off(s,o){e.listeners.get(s)?.delete(o)}},r={wall:["diagnostics().wall (or the wall you passed / sharedInline3D())",()=>e.wall],format:["localFormat",()=>i.localFormat],sendHint:["nothing \u2014 auto-convergence superseded it",()=>s=>e.sendHint(s)],_debug:["diagnostics()",()=>({transport:e.transport,kill:s=>e.transport?._debugKill(s)})]};for(let[s,[o,a]]of Object.entries(r))Object.defineProperty(i,s,{enumerable:!1,configurable:!0,get(){return e._handleWarned?.has(s)||((e._handleWarned||=new Set).add(s),console.warn(`${G} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function Zr(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 Mn(n,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Zr(n))return;let r=n.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=X(a,o,n.width/n.height,0,0);r.save(),i&&(r.translate(n.width,0),r.scale(-1,1)),r.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,n.width,n.height),r.restore()}var tt=class{constructor(e,t){this.call=e,this.id=t,this.hello=null,this.format=null,this.route=null,this.routedKey=null,this.handle=null,this.conn="connecting",this.remote={muted:!1,cameraOff:!1,speaking:!1},this.level=0,this.speaking=!1,this.quality=null,this.conv=xe(),this.autoTrack=qe(),this.autoFocus=Ce(),this.autoAt=0,this.autoCanvas=null,this.autoLocked=!1,this.autoStats={n:0,ms:0,readMs:0,method:null,via:null},this.autoPending=!1,this.autoGen=0,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=kt(bt),this.layerFails=0,this.forceFlat=!1,this.lifted=!1,this.liftHandle=null,this.liftLive=!1,this.liftFailed=!1,this.liftFails=0,this.visible=!0,this.video=Object.assign(document.createElement("video"),{muted:!0,playsInline:!0,autoplay:!0}),this.audio=Object.assign(document.createElement("audio"),{autoplay:!0}),this.video.addEventListener("playing",()=>this._maybeRoute()),this.video.addEventListener("loadeddata",()=>this._maybeRoute()),this.video.addEventListener("resize",()=>this._maybeRoute()),this.canvas=E("canvas"),this.cover=E("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,E("div",{class:"dxr-call-talk"})]),e.o.ui||N(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge()}display(){return Ct(this.route)}info(){return Object.freeze({id:this.id,format:this.format||"mono",display:this.display(),state:this.conn,muted:this.remote.muted,cameraOff:this.remote.cameraOff,speaking:this.speaking})}diag(){return{...this.info(),route:this.route,rectified:!!(this.hello&&this.hello.rectified),hello:this.hello,quality:this.quality,convergencePx:this.conv.current,autoConverge:{disparityPx:this.conv.measuredPx,ms:this.autoStats.n?this.autoStats.ms/this.autoStats.n:null,readMs:this.autoStats.n?this.autoStats.readMs/this.autoStats.n:null,method:this.autoStats.method,via:this.autoStats.via},lift:this.lifted?{live:this.liftLive,native:!!(this.liftHandle&&this.liftHandle.native),priority:this.call.liftPool?this.call.liftPool.priority(this.id):null,state:this.liftHandle?this.liftHandle.state||null:"pending"}:null,element:this.el}}setStream(e){this.video.srcObject!==e&&(this.video.srcObject=e,this.audio.srcObject=e,this._resetAutoConverge()),this.video.play().catch(()=>{}),this.audio.play().catch(()=>{})}onChannelOpen(){clearTimeout(this.helloTimer),this.helloTimer=setTimeout(()=>{this.format||(this.format="mono",this._maybeRoute())},Br)}setHello(e){clearTimeout(this.helloTimer),this.hello=e,this.conv.hello=e;let t=this.format!==e.format;this.format=e.format,this.call.log("hello",{peer:this.id,format:e.format,width:e.width,height:e.height,rectified:e.rectified}),t?this._maybeRoute():this._renderBadge()}setHint(e){this.hintGate(performance.now())&&(this.conv.subjectZmm=e.subjectZmm)}setRemoteState(e){this.remote=e,this._renderBadge(),this._renderPlate(),this._updateVisible()}setSpeaking(e){e!==this.speaking&&(this.speaking=e,this.el.classList.toggle("dxr-call-tile--speaking",e))}setConn(e){e==="unreachable"&&this.conn!=="unreachable"&&this.call.error("unreachable",`${this.call.t("unreachable")}. Still retrying in the background.`,Object.assign(new Error("unreachable"),{peer:this.id})),this.conn=e,e==="connected"&&this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this._renderPlate()}_renderPlate(){let e=this.call.t,t=this.conn==="left"?e("leftCall"):this.conn==="unreachable"?e("unreachable"):this.conn==="reconnecting"?e("reconnecting"):this.conn!=="connected"?e("connecting"):this.remote.cameraOff?e("cameraOffPlate"):null;this.plate.textContent=t||"",N(this.plate,!!t)}_renderBadge(){let e=this.call.t,t=this.route==="woven-sbs"?e("badge3D"):this.route==="lifted"?e("badge2D3D"):e("badge2D"),i=this.route?this.route==="lifted"&&!this.liftLive?`${t}${e("badgePending")}`:t:e("badgePending");this.badge.replaceChildren(E("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",q.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,r=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:Tt({format:this.format,woven:t.woven,mono3D:t.mono3DOn?"auto":"off",lift:!!i,overBudget:i?!i.canAcquire(this.id):!1,failed:this.liftFailed});this.format!=="sbs"&&t.woven&&t.mono3DOn&&!t._liftP&&t._ensureLift(),this.format!=="sbs"&&t.woven&&t.liftMissing&&t._warnLiftMissing();let s=`${r.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=r.route,r.route==="woven-sbs"?this._registerWoven():r.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:r.route,format:this.format,mono3d:r.mono3d||null}),t.emit("display",{id:this.id,display:this.display()}),t.listeners.get("format")?.size&&t.emit("format",{id:this.id,format:this.format,route:r.route,mono3d:r.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),N(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(N(this.cover,!1),e.log("first-woven",{peer:this.id,woven:i.woven,reason:i.reason,ms:Math.round(i.ms)}),!i.woven&&i.reason==="layer-failed"&&this._layerFailed())})}_registerLifted(){let e=this.call,t=e.liftPool;this.lifted=!0,this.liftLive=!1,this.video.classList.add("dxr-call-liftsrc"),this.canvas.classList.add("dxr-call-liftflat"),this.video.parentNode!==this.stage&&this.stage.insertBefore(this.video,this.stage.firstChild),this._observeVisible(),t.acquire(this.id,this.video,{wall:e.wall,visible:this.visible,onError:i=>this._liftError(i)}).then(i=>{if(!i||!this.lifted||t.handle(this.id)!==i)return;this.liftHandle=i;let r=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>r(s&&s.state)),i.on?.("error",s=>{s&&s.fatal&&this._liftError(s.error)})],i.state==="live"?this._liftShowing(!0):i.canvas&&i.canvas.style&&(i.canvas.style.visibility="hidden"),e.log("lifted",{peer:this.id,native:!!i.native,woven:!!i.woven,state:i.state||null,provider:i.stats&&i.stats.provider||null})})}_liftShowing(e){if(e===this.liftLive)return;this.liftLive=e;let t=this.liftHandle;e?(t&&t.canvas&&t.canvas.style&&!t.native&&(t.canvas.style.visibility=""),this.canvas.style.visibility="hidden",this.liftFails=0,this.call.liftProven||(this.call.liftProven=!0,this.call._refreshLobby())):this.canvas.style.visibility="",this.call.log("lift-live",{peer:this.id,live:e}),this._renderBadge()}_liftError(e){this.lifted&&(this.call.log("lift-error",{peer:this.id,message:String(e&&e.message||e).slice(0,200)}),this.liftFailed=!0,this.reroute(!0),!(this.liftFails++>=Jr)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},B(this.liftFails-1,{baseMs:3e3,maxMs:3e4}))))}_observeVisible(){this._io||typeof IntersectionObserver!="function"||(this._io=new IntersectionObserver(e=>{let t=e[e.length-1];this._onscreen=!!(t&&t.isIntersecting),this._updateVisible()}),this._io.observe(this.stage))}_updateVisible(){let e=this._onscreen!==!1&&!this.remote.cameraOff;e!==this.visible&&(this.visible=e,this.call.liftPool?.setVisible(this.id,e))}_layerFailed(){if(this.forceFlat=!0,this.reroute(!0),this.layerFails++>=Gr)return;let e=B(this.layerFails-1,{baseMs:1500,maxMs:2e4});this.call.log("layer-retry",{peer:this.id,attempt:this.layerFails,inMs:e}),clearTimeout(this.layerTimer),this.layerTimer=setTimeout(()=>{this.forceFlat=!1,this.call.woven&&this.reroute(!0)},e)}onWallLost(){this.handle=null,this.reroute(!0)}_unregister(){if(N(this.cover,!1),this.lifted){this.lifted=!1;for(let e of this._liftOff||[])typeof e=="function"&&e();this._liftOff=null,this.call.liftPool?.release(this.id),queueMicrotask(()=>this.call.state!=="left"&&this.call._rerouteMono()),this.liftHandle=null,this.liftLive=!1,this.canvas.style.visibility="",this.canvas.classList.remove("dxr-call-liftflat"),this._io&&(this._io.disconnect(),this._io=null),this.video.parentNode&&(this.video.remove(),this.video.classList.remove("dxr-call-liftsrc"),setTimeout(()=>this.video.srcObject&&this.video.play().catch(()=>{}),0))}if(this.handle){try{this.handle.remove()}catch{}this.handle=null}}paint(){this.route&&(this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||Mn(this.canvas,this.video):Mn(this.canvas,this.video,{eyeHalf:this.route==="flat-left"?0:null}))}_paintConv(){let e=this.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.convCanvas)return;let r=t/2,s=this.call.o.tileAspect,{w:o,h:a}=be(r,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a),this.call.o.autoConverge&&this._sampleDisparity(e,t,i);let c=this.conv.step(r),m=l.getContext("2d");for(let u of[0,1]){let h=X(r,i,s,c,u);m.drawImage(e,u*r+h.sx,h.sy,h.sw,h.sh,u*o,0,o,a)}}_sampleDisparity(e,t,i){let r=performance.now();if(this.autoPending||r-this.autoAt<Kr)return;if(this.autoAt=r,typeof VideoFrame=="function"){let u=null;try{u=new VideoFrame(e)}catch{u=null}if(u&&Yr.has(u.format)){this.autoPending=!0;let h=this.autoGen,d=u.visibleRect?u.visibleRect.width:u.displayWidth,p=u.visibleRect?u.visibleRect.height:u.displayHeight,f=new Uint8Array(u.allocationSize());u.copyTo(f).then(v=>{if(h!==this.autoGen)return;let y=performance.now(),b=Math.max(1,Math.ceil(d/2/Sn)),C=Hi(f,v[0].offset,v[0].stride,d,p,b);this._applyMeasurement(C.img,C.w,C.h,C.w/d,r,performance.now()-y,"videoframe")}).catch(()=>{h===this.autoGen&&this._applyMeasurement(null,0,0,1,r,0,"videoframe")}).finally(()=>{u.close(),this.autoPending=!1});return}u&&u.close()}let s=Math.min(1,Sn/(t/2)),o=Math.max(2,Math.round(t*s/2)*2),a=Math.max(2,Math.round(i*s));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let l=this.autoCanvas;(l.width!==o||l.height!==a)&&(l.width=o,l.height=a);let c=l.getContext("2d",{willReadFrequently:!0}),m=null;try{c.drawImage(e,0,0,o,a),m=Be(c.getImageData(0,0,o,a).data,o*a)}catch{m=null}this._applyMeasurement(m,o,a,o/t,r,performance.now()-r,"canvas")}_applyMeasurement(e,t,i,r,s,o,a){if(this.destroyed)return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,m=this.autoTrack.push(c?c.d/r:null);this.conv.measuredPx=m,this.autoStats.n++,this.autoStats.readMs+=o,this.autoStats.ms+=o+(performance.now()-l),this.autoStats.method=c?c.method:null,this.autoStats.via=a,c&&!this.autoLocked&&(this.autoLocked=!0,this.call.log("auto-converge",{peer:this.id,disparityPx:Math.round(m*10)/10,at:{x:Math.round(c.x/r),y:Math.round(c.y/r)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,clearTimeout(this.helloTimer),clearTimeout(this.layerTimer),clearTimeout(this.leaveTimer),clearTimeout(this.liftTimer),this._unregister(),this.video.srcObject=null,this.audio.srcObject=null,this.el.remove()}},ei=class{constructor(e,t){this.call=e,this.canvas=E("canvas"),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,E("div",{class:"dxr-call-talk"})]),t.appendChild(this.el),this.view=null,this.cam=null}get route(){return this.view?this.view.route:null}update(){let e=this.call.local,t=this.call.t,i=!e||!e.videoTrack;this.plate.textContent=i?this.call.camStatus==="busy"?t("cameraBusy"):this.call.camStatus==="pending"?"":t("noCamera"):this.call.camOff?t("cameraOffPlate"):"",N(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,r=this.call.woven?this.call.wall:{supported:!1};if(!i||i.state!=="live")return this.detach(),this._badge();this.view&&this.cam===i?this.view._reroute(e,r):(this.detach(),this.cam=i,this.view=Ht(r,this.canvas,i,{mirror:!0,autoConverge:!1,aspect:this.call.o.tileAspect})),this._badge()}_badge(){let e=this.call.t;this.badge.replaceChildren(E("b",{text:`${e("you")} \xB7 ${this.route==="woven-sbs"?e("badge3D"):e("badge2D")}`}))}onWallLost(){this.view?._onWallLost(),this._badge()}detach(){this.view&&this.view.remove(),this.view=null,this.cam=null}setSpeaking(e){this.el.classList.toggle("dxr-call-tile--speaking",e)}},Qr="1.31",En=new Set;function D(n,e,t){let i=()=>{En.has(n)||(En.add(n),console.warn(`${G} \`${n}\` is internal and leaves '@displayxr/inline3d/call' in ${Qr} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(r,s,o){return i(),Reflect.apply(r,s,o)},construct(r,s){return i(),Reflect.construct(r,s)}}):t&&typeof t=="object"?new Proxy(t,{get(r,s,o){return typeof s=="string"&&i(),Reflect.get(r,s,o)}}):t}var io=D("normalizeCallOptions","js/call/options.js",Xt),no=D("newRoomId","js/call/wire.js",xt),ro=D("isValidRoomId","js/call/wire.js",le),so=D("buildInviteLink","js/call/wire.js",He),oo=D("normalizeHello","js/call/wire.js",St),ao=D("makeHello","js/call/wire.js",Mt),lo=D("routeFor","js/call/wire.js",Tt),co=D("badgeFor","js/call/wire.js",Ct),ho=D("createLiveGate","js/call/wire.js",Rt),fo=D("convergenceShiftPx","js/camera/converge.js",je),uo=D("lowPass","js/camera/converge.js",We),po=D("clampShift","js/camera/converge.js",Ne),mo=D("eyeCropRect","js/camera/geometry.js",X),go=D("mirrorSwapOps","js/camera/geometry.js",oe),_o=D("mirrorSwapPixels","js/camera/geometry.js",yt),vo=D("maxBitrateKbps","js/call/wire.js",Ve),yo=D("measureFocusDisparity","js/camera/disparity.js",Ot),wo=D("preferVideoCodecs","js/call/sdp.js",Ee),bo=D("sortCodecCapabilities","js/call/sdp.js",$e),xo=D("VIDEO_CODEC_ORDER","js/call/sdp.js",Me),So=D("MeshTransport","js/call/transport.js",ke),Mo=D("clampMaxPeers","js/call/transport.js",Te),Eo=D("qrEncode","js/call/qr.js",Ut),ko=D("roomKey","js/call/signaling.js",Bt);var To=D("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:De.unreachable,cameraBusy:De.cameraBusy})),Co=D("CALL_ACCENTS","js/call/ui.js",qt),Ro=D("normalizeMono3D","js/call/lift.js",ye),Do=D("resolveLift","js/call/lift.js",nt),Lo=D("createLiftPool","js/call/lift.js",ot),Ao=D("createFrameWatch","js/call/lift.js",st),Oo=D("liftConvergenceFor","js/call/lift.js",ve),Io=D("liftPriorityFor","js/call/lift.js",Le),Po=D("setLiftPriority","js/call/lift.js",rt),Fo=D("defaultLiftSpecifier","js/call/lift.js",it),jo=D("LIFT_PRIORITY","js/call/lift.js",_e);et();ii(()=>new URL("./lift.js",import.meta.url).href);export{Jt as CALL_EVENT_PREFIX,sn as CAMERA_SDK,Qe as DXR_SIGNAL_DEFAULT,pe as DxrCallElement,kn as addCall,Ht as addCameraView,Kt as attrsToOpts,ki as createInline3D,et as defineCallElement,fe as dxrSignaling,Mi as inline3DAvailable,Ze as isStereoCamera,Yt as mountCall,zt as openCamera,Se as parseInviteLink,Pt as parseStereoXmp,Gi as readJpegStereoMeta,Ft as readJpegXmp,tn as readWebmStereoMeta,Fe as sharedInline3D,Ye as suggestedName};
|
|
86
|
+
`;function yn(n=document){if(n.getElementById(mn))return;let e=n.createElement("style");e.id=mn,e.textContent=Vr,(n.head||n.documentElement).appendChild(e)}var ee=n=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${n}"/></svg>`,q={mic:ee("M12 14a3 3 0 0 0 3-3V5a3 3 0 0 0-6 0v6a3 3 0 0 0 3 3zm5-3a5 5 0 0 1-10 0H5a7 7 0 0 0 6 6.92V21h2v-3.08A7 7 0 0 0 19 11z"),micOff:ee("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z"),cam:ee("M17 10.5V7a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-3.5l4 4v-11z"),camOff:ee("M21 6.5l-4 4V7a1 1 0 0 0-1-1H9.82L21 17.18zM3.27 2 2 3.27 4.73 6H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73z"),link:ee("M3.9 12a3.1 3.1 0 0 1 3.1-3.1h4V7H7a5 5 0 0 0 0 10h4v-1.9H7A3.1 3.1 0 0 1 3.9 12zM8 13h8v-2H8zm9-6h-4v1.9h4a3.1 3.1 0 0 1 0 6.2h-4V17h4a5 5 0 0 0 0-10z"),leave:ee("M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85a1 1 0 0 1-1.41-.02L.29 13.08a1 1 0 0 1 0-1.41C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67a1 1 0 0 1 0 1.41l-2.48 2.48a1 1 0 0 1-1.41.02 11.3 11.3 0 0 0-2.66-1.85 1 1 0 0 1-.56-.9v-3.1A15.3 15.3 0 0 0 12 9z"),mutedSmall:ee("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z")};function E(n,e={},t=[]){let i=document.createElement(n);for(let[r,s]of Object.entries(e))s!=null&&(r==="class"?i.className=s:r==="html"?i.innerHTML=s:r==="text"?i.textContent=s:r.startsWith("on")&&typeof s=="function"?i.addEventListener(r.slice(2),s):r in i&&typeof s!="string"?i[r]=s:i.setAttribute(r,s));for(let r of[].concat(t))r&&i.appendChild(typeof r=="string"?document.createTextNode(r):r);return i}var W=(n,e)=>n&&n.classList.toggle("dxr-call-hidden",!e);var bn="[inline3d/call]",$r="https://github.com/DisplayXR/displayxr-browser",xn=Object.freeze({accent:"theme.accent",tileAspect:"theme.tileAspect",inviteBase:"invite.base",updateUrl:"invite.updateUrl",browserUrl:"landing.browserUrl",maxLifted:"liftOptions.max",calibration:"openCamera({ calibration }) of '@displayxr/inline3d/camera' (pass the camera as `camera`)",rectify:"openCamera({ rectify }) of '@displayxr/inline3d/camera'",log:"debug: true (and diagnostics())",recoverSession:"nothing \u2014 a call always recovers the document's session (sharedInline3D())",wallOptions:"sharedInline3D(opts) \u2014 the document's wall is configured by the page",scrollIntoView:"nothing \u2014 always on with ui: true"}),wn=new Set;function Ur(n){wn.has(n)||(wn.add(n),console.warn(`${bn} option \`${n}\` is deprecated (removed in 1.31) \u2014 use ${xn[n]}`))}function Xt(n={}){for(let v of Object.keys(xn))n[v]!==void 0&&Ur(v);let e=n.theme&&typeof n.theme=="object"?n.theme:{},t=n.invite&&typeof n.invite=="object"?n.invite:{},i=n.landing&&typeof n.landing=="object"?n.landing:{},r=n.ui===void 0?!0:n.ui==="tiles"?"tiles":!!n.ui,s=r===!0,o=e.tileAspect!==void 0?e.tileAspect:n.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=n.room===void 0||n.room===null?"auto":n.room;if(l!=="auto"&&!le(l)){let v=Se(l);if(!v)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=v}let c=n.liftOptions&&typeof n.liftOptions=="object"?{...n.liftOptions}:null,p=c&&c.max!==void 0?c.max:n.maxLifted;c&&delete c.max;let f=e.accent!==void 0?e.accent:n.accent,h={};for(let[v,y]of Object.entries(_n)){let b=v==="accent"?f:e[v];typeof b=="string"&&b?h[y]=v==="accent"?gn(b):b:typeof b=="number"&&v==="radius"&&(h[y]=`${b}px`)}let d=t.base!==void 0?t.base:n.inviteBase,m=t.updateUrl!==void 0?t.updateUrl:n.updateUrl,u=i.browserUrl!==void 0?i.browserUrl:n.browserUrl;return{room:l,signaling:n.signaling||fe(void 0,typeof n.key=="string"&&n.key?{key:n.key}:{}),iceServers:Array.isArray(n.iceServers)?n.iceServers:void 0,camera:n.camera===void 0?"auto":n.camera,format:n.format==="sbs"?"sbs":n.format==="mono"?"mono":void 0,calibration:n.calibration&&typeof n.calibration=="object"?{...n.calibration}:{},rectify:typeof n.rectify=="function"?n.rectify:null,audio:n.audio===void 0?!0:!!n.audio,autoConverge:n.autoConverge===void 0?!0:!!n.autoConverge,mono3D:ye(n.mono3D),maxPeers:Te(n.maxPeers===void 0?ae:n.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+p)&&p!==null&&p!==void 0?Math.max(0,Math.min(ae,Math.floor(+p))):ae,layout:n.layout==="speaker"?"speaker":n.layout==="none"?"none":"grid",ui:r,chrome:s,autoJoin:n.autoJoin===void 0?!s:!!n.autoJoin,selfView:n.selfView===void 0?!0:!!n.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:m===void 0?s:!!m},landing:{browserUrl:typeof u=="string"?u:$r,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!n.debug,log:typeof n.log=="function"?n.log:n.debug?(v,y)=>console.log(`${bn} ${v} ${JSON.stringify(y)}`):null,_liftImporter:typeof n._liftImporter=="function"?n._liftImporter:void 0}}var Vs=Object.freeze(["normalizeCallOptions","newRoomId","isValidRoomId","buildInviteLink","normalizeHello","makeHello","routeFor","badgeFor","createLiveGate","convergenceShiftPx","lowPass","clampShift","eyeCropRect","mirrorSwapOps","mirrorSwapPixels","maxBitrateKbps","measureFocusDisparity","preferVideoCodecs","sortCodecCapabilities","VIDEO_CODEC_ORDER","MeshTransport","clampMaxPeers","qrEncode","roomKey","SIGNAL_PROTOCOL","WIRE_VERSION","CALL_SDK","PLATE_TEXT","CALL_ACCENTS","normalizeMono3D","resolveLift","createLiftPool","createFrameWatch","liftConvergenceFor","liftPriorityFor","setLiftPriority","defaultLiftSpecifier","LIFT_PRIORITY"]);var Jt="dxr-call:",Br=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],Gt="[inline3d/call] <dxr-call>",ue=n=>n!=null&&!/^(false|0|off|no)$/i.test(String(n).trim()),Sn=n=>{if(n==null||String(n).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(n)),t=e?+e[1]/+e[2]:+n;return Number.isFinite(t)?t:void 0},N=n=>n==null||String(n).trim()===""?void 0:String(n).trim();function Kt(n){let e=typeof n=="function"?n:l=>n&&typeof n.getAttribute=="function"?n.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",N(e("room")));let r=N(e("signaling"));r&&(t.signaling=fe(r,N(e("key"))?{key:N(e("key"))}:{})),i("key",N(e("key"))),i("camera",N(e("camera"))),i("layout",N(e("layout"))),i("maxPeers",Sn(e("max-peers")));let s=N(e("ui"));ue(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),ue(e("auto-join"))&&(t.autoJoin=!0);let o=N(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),ue(e("no-audio"))&&(t.audio=!1),ue(e("no-self-view"))&&(t.selfView=!1),ue(e("no-auto-converge"))&&(t.autoConverge=!1);let a={accent:N(e("accent")),tileAspect:Sn(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),N(e("invite-base"))&&(t.invite={base:N(e("invite-base"))}),N(e("browser-url"))&&(t.landing={browserUrl:N(e("browser-url"))}),ue(e("debug"))&&(t.debug=!0),t}var qr=typeof HTMLElement=="function"?HTMLElement:class{},pe=class n extends qr{static mount=null;constructor(){super(),this.options=null,this.call=null,this.ready=null,this._gen=0,this._off=[],this._pending=null}connectedCallback(){if(this.call||this._pending)return;let e=++this._gen,t={...Kt(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||n.mount||Yt;this._pending=new Promise(r=>r(i(this,t))).then(r=>{if(this._pending=null,e!==this._gen)return r.leave(),null;if(this.call=r,this._off=Br.map(s=>r.on(s,o=>this._dispatch(s,o))),this._off.push(r.on("error",s=>console.warn(`${Gt} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:r}),r.state==="in-call"){this._dispatch("joined",{room:r.room,id:r.id});for(let s of r.peers)this._dispatch("peer",{id:s.id})}return r},r=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(r&&r.message||r),error:r||null}),console.warn(`${Gt} mount failed: ${String(r&&r.message||r)}`),r}),this.ready=this._pending,this.ready.catch(()=>{})}disconnectedCallback(){this._gen++;let e=this.call;this.call=null,e&&e.leave();for(let t of this._off)try{t()}catch{}this._off=[]}_dispatch(e,t){typeof CustomEvent!="function"||typeof this.dispatchEvent!="function"||this.dispatchEvent(new CustomEvent(Jt+e,{detail:t,bubbles:!0,composed:!0}))}};function et(n="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(n);return t?(t!==pe&&console.warn(`${Gt} <${n}> is already defined by another class; leaving it`),!1):(e.define(n,pe),!0)}var G="[inline3d/call]",Xr=2e3,Gr=2500,Jr=500,Zt=.02,Kr=4,Yr=2,Zr=200,Mn=240,Qr=new Set(["I420","I420A","I422","I444","NV12"]);async function Tn(n,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=Xt(t);if(!i.signaling||typeof i.signaling.join!="function")throw new TypeError("@displayxr/inline3d/call: opts.signaling must be a SignalingAdapter \u2014 dxrSignaling([url]) or your own");let r=new Qt(n,e,i);return await r._init(),r.handle}async function Yt(n,e={}){if(!n||typeof n.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,r=t||await Fe(i.wallOptions);return Tn(r,n,i)}var Qt=class{constructor(e,t,i){this.o=i,this.t=vn(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=Ai(),this.room=i.room==="auto"?Se(globalThis.location):i.room,this.state="idle",this.tiles=new Map,this.listeners=new Map,this.local=null,this.muted=!1,this.camOff=!1,this.depth=0,this.speakerId=null,this.transport=null,this._raf=0,this._statsTimer=0,this._hintGate=kt(bt),this.mono3D=i.mono3D,this.mono3DOn=i.mono3D!=="off",this.liftApi=null,this.liftPool=null,this._liftP=null,this.liftProven=!1,this.liftMissing=!1,this._liftWarned=!1,this._frameWatch=st(),this.handle=this._makeHandle(),this.wallLive&&this._hookWall(this.wall)}get woven(){return!!(this.wall&&this.wall.supported&&this.wallLive)}log(e,t={}){this.o.log&&this.o.log(e,t)}emit(e,t){let i=this.listeners.get(e);if(i)for(let r of[...i])try{r(t)}catch(s){console.error(`${G} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${G} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${G} ${e}: ${t}`),this.emit("warning",{code:e,message:t})}async _init(){this._buildDom(),this.wallLive&&this._ensureLift(),await this._openMedia(this.o.camera),this._startLoop(),this.o.autoJoin?await this.join():this._setState("lobby")}async _openMedia(e,t,{keepOnFail:i=!1}={}){let r=(h,d)=>this.log(h,d),s=null,o=null,a=Ze(e)?e:null;try{if(s=a||await zt({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:r}),a&&a.state!=="live")throw Object.assign(new Error("the camera given is not live"),{code:"no-camera",skipped:[]})}catch(h){o=h;let d=h.code==="camera-busy";if(this.error(d?"camera-busy":h.code||"no-camera",d?`${this.t("cameraBusy")}. Joining audio-only.`:`no camera: ${h.message}. Joining audio-only.`,h),i&&this.local&&this.local.videoTrack)return this.local;this.camStatus=d?"busy":"none"}s&&(this.camStatus="ok"),s&&s.rectifyError&&this.error("rectify-failed",`rectify() threw \u2014 sending the raw pair: ${s.rectifyError.message}`,s.rectifyError);let l=this.local?this.local.audioTrack:null;this.o.audio&&!l&&(l=await zi({log:r})),l&&(l.enabled=!this.muted);let c=s&&s.stream.getVideoTracks()[0]||null;if(c){try{c.contentHint="detail"}catch{}c.enabled=!this.camOff}let p=new MediaStream([c,l].filter(Boolean)),f=this.local;return this.local={stream:p,cam:s,camStream:s?s.stream:null,video:s?s.video:null,videoTrack:c,audioTrack:l,format:s?s.format:"mono",width:s?s.width:0,height:s?s.height:0,calibration:s?s.calibration:{},owned:s?s.owned&&s!==a:!1,label:s?s.label:"",skipped:s?s.skipped:o?.skipped||[]},s&&s!==f?.cam&&(this._camEndedOff?.(),this._camEndedOff=s.on("ended",()=>{this.local?.cam===s&&(this.local.videoTrack=null,this.camStatus="none",this.error("no-camera",'the camera ended (revoked, unplugged, or taken by another app). Audio-only until "Retry camera".'),this.transport?.broadcast(this.stateMsg()),this._refreshSelf(),this._refreshBar())})),this.log("camera",{format:this.local.format,width:this.local.width,height:this.local.height,label:this.local.label,skipped:this.local.skipped.length}),f&&f.owned&&f.cam&&f.cam!==s&&f.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return Mt({format:e.format,width:e.width,height:e.height,baselineMm:e.calibration?.baselineMm,hfovDeg:e.calibration?.hfovDeg,rectified:!!e.calibration?.rectified})}stateMsg(){return{type:"state",muted:this.muted,cameraOff:this.camOff||!this.local?.videoTrack,speaking:!!this._selfSpeaking}}async join(){if(this.state==="joining"||this.state==="in-call")return this.handle;if(this.state==="left"&&!this.local?.videoTrack&&await this._openMedia(this.o.camera),this.room||(this.room=xt(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",He(location.href,this.room))}catch{}this._setState("joining");let e=new ke({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(i,r)=>this.log(i,r)});this.transport=e;let t=null;try{t=await e.start({room:this.room,localStream:this.local.stream,sendFormat:this.local.format,onPeer:i=>this._onPeer(i),onPeerLeft:(i,r)=>this._onPeerLeft(i,r),onStream:(i,r)=>this.tiles.get(i)?.setStream(r),onMessage:(i,r)=>this._onMessage(i,r),onPeerState:(i,r)=>{this.tiles.get(i)?.setConn(r),this.emit("state",{id:i,state:r})},onRefused:i=>this.log("refused-peer",{id:i}),onGhost:(i,r)=>this._onGhost(i,r),onSignalingState:(i,r)=>{this.log("signaling",{state:i}),i==="closed"&&r&&this.error(r.code||"signaling-closed",r.message,r)}})}catch(i){throw this.transport=null,i&&i.code==="room-full"?(this._setState("full"),this.error("room-full",i.message,i)):(this._setState("lobby"),this.error(i.code||"join-failed",`could not join: ${i.message}`,i)),i}if(this._setState("in-call"),this.o.chrome)try{this.container.scrollIntoView?.({block:"start",behavior:"instant"}),this._fitGrid()}catch{}return this._startStats(),this._pagehide=()=>this.leave("pagehide"),globalThis.addEventListener?.("pagehide",this._pagehide),this.log("joined",{id:this.id,peers:this.tiles.size}),this.emit("joined",{room:this.room,id:this.id}),setTimeout(()=>{this.transport===e&&this._reportTurn(t)},0),this.handle}_reportTurn(e){let t=e&&e.turn;!t||typeof t!="object"||(t.status==="off"&&t.reason==="cap"?this.error("turn-cap","relay (TURN) capacity for this month is used up; direct connections still work, but a participant behind a strict NAT may be unreachable",null):(t.reason==="budget"||t.reason==="rate")&&this.warning("turn-shed",t.reason==="rate"?"no relay (TURN) for this session: too many credential requests from this address this hour":"no relay (TURN) for this anonymous session: the hosted service is near its monthly relay budget (a publishable key keeps TURN)"))}_onPeer(e){if(this.tiles.has(e))return;let t=new tt(this,e);this.tiles.set(e,t),this._layout(),this.emit("peer",{id:e})}_onGhost(e,t){let i=this.tiles.get(e);if(t&&!i){let r=new tt(this,e);r.ghost=!0,this.tiles.set(e,r),r.setConn("unreachable"),this._layout()}else!t&&i&&i.ghost&&(i.destroy(),this.tiles.delete(e),this._layout())}_onPeerLeft(e,t){let i=this.tiles.get(e);i&&(i.setConn("left"),this.emit("peerleft",{id:e,reason:t}),i.leaveTimer=setTimeout(()=>{i.destroy(),this.tiles.get(e)===i&&this.tiles.delete(e),this.speakerId===e&&this._setSpeaker(null),this._layout()},Gr))}_onMessage(e,t){let i=this.tiles.get(e);if(!i||!t)return;if(t.type==="__open"){this.transport.send(e,this.hello()),this.transport.send(e,this.stateMsg()),i.onChannelOpen();return}let r=St(t);if(r)return i.setHello(r);let s=Et(t);if(s)return i.setHint(s);let o=Oi(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return He(e,this.room)}mute(e){return this.muted=e===void 0?!this.muted:!!e,this.local?.audioTrack&&(this.local.audioTrack.enabled=!this.muted),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this.log("mute",{muted:this.muted}),this.muted}setCameraOff(e){return this.camOff=e===void 0?!this.camOff:!!e,this.local?.videoTrack&&(this.local.videoTrack.enabled=!this.camOff),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this._refreshSelf(),this.camOff}setDepth(e){let t=e==null||!Number.isFinite(+e)?0:Math.max(-1,Math.min(1,+e));this.depth=t;for(let i of this.tiles.values())i.conv.depth=t;return this.liftPool?.setDepth(t),this.ui?.depth&&+this.ui.depth.value!==t&&(this.ui.depth.value=String(t)),t}async setCamera(e,{format:t}={}){let i=this.local?.format,r=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",r.videoTrack,r.stream),await this.transport.setSendFormat(r.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==r.format&&this.log("send-format",{format:r.format}),{format:r.format,width:r.width,height:r.height,label:r.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=Et({type:"hint",subjectZmm:e});return t?(this.transport?.broadcast(t),!0):!1}leave(e="left"){if(this.state!=="left"){globalThis.removeEventListener?.("pagehide",this._pagehide),this.transport?.stop(),this.transport=null;for(let t of this.tiles.values())t.destroy();this.tiles.clear(),this.liftPool?.releaseAll(),clearInterval(this._statsTimer),this._setSpeaker(null),this.local&&(this._camEndedOff?.(),this._camEndedOff=null,this.local.stream.getTracks().forEach(t=>t.stop()),this.local.owned&&this.local.cam?this.local.cam.close():this.local.cam&&this.self?.detach(),this.local.videoTrack=null,this.local.audioTrack=null),this.self?.detach(),this._unhookWall(),this._setState("left"),this._layout(),this.emit("left",{room:this.room,reason:e})}}_hookWall(e){if(!e||!e.session||typeof e.session.addEventListener!="function")return;let t=e.close;this._wallHook={w:e,orig:t,pageClosed:!1};let i=this._wallHook;e.close=(...r)=>(i.pageClosed=!0,t.apply(e,r)),i.onEnd=()=>this._sessionEnded(i),e.session.addEventListener("end",i.onEnd),this._watchLive(e)}_watchLive(e){this.weaveLive=!1;let t=e.session;if(!t||typeof t.requestAnimationFrame!="function"){this.weaveLive=!0;return}let i=Rt(),r=performance.now(),s=(o,a)=>{if(e!==this.wall||!this.wallLive||this.state==="left")return;let l=null;if(e.refSpace)try{let c=a.getViewerPose(e.refSpace);l=c&&c.views?c.views.length:0}catch{l=0}if(!i.feed(l)){try{t.requestAnimationFrame(s)}catch{}return}this.weaveLive=!0,this.log("weave-live",{ms:Math.round(performance.now()-r)});for(let c of this.tiles.values())(c.route==="woven-sbs"||c.route==="lifted")&&c.reroute(!0);this.self&&this.self.route==="woven-sbs"&&this.self.reroute(!0),this._layout()};try{t.requestAnimationFrame(s)}catch{this.weaveLive=!0}}_unhookWall(){let e=this._wallHook;if(e){this._wallHook=null,e.w.close!==e.orig&&(e.w.close=e.orig);try{e.w.session.removeEventListener("end",e.onEnd)}catch{}}}_sessionEnded(e){if(this._wallHook===e){this.wallLive=!1,this.weaveLive=!1,this.log("session-ended",{byPage:e.pageClosed});for(let t of this.tiles.values())t.onWallLost();if(this.self?.onWallLost(),e.pageClosed||this.state==="left"){this._unhookWall();return}this.error("session-ended","the inline-3D session ended; tiles are flat while it is re-opened"),this._unhookWall(),this._recoverWall(0)}}_recoverWall(e){this.state==="left"||e>10||setTimeout(async()=>{if(this.state==="left")return;let t=null;try{t=await Fe()}catch{t=null}if(!t||!t.supported)return this._recoverWall(e+1);this.wall=t,this.wallLive=!0,this._hookWall(t),this.log("session-recovered",{attempt:e});for(let i of this.tiles.values())i.reroute(!0);this.self?.reroute(!0)},B(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let r of this.tiles.values())r.paint();e&&this.liftPool&&this.liftPool.anyWeb&&this._watchFrames(i-e),e=i};this._raf=requestAnimationFrame(t)}_watchFrames(e){let t=this._frameWatch.feed(e);if(!t)return;let i={degraded:t==="degraded",frameMs:Math.round(this._frameWatch.frameMs*10)/10,tiles:this.liftPool.size};this.log("lift-frame-time",i),t==="degraded"&&console.warn(`${G} lifted tiles are slowing the page (~${Math.round(1e3/i.frameMs)} fps with ${i.tiles} lifted) \u2014 setMono3D(false) shows mono peers flat`),this.emit("quality",{id:null,in:null,out:null,lift:i})}_ensureLift(){if(!this.mono3DOn)return Promise.resolve(null);if(!this._liftP){let e=(r,s)=>this.log(r,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=nt(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(r=>(this.liftApi=r,r.lift?(this.liftPool=ot({lift:r.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!r.caps&&r.capabilities&&Promise.resolve().then(()=>r.capabilities(i)).then(s=>{r.caps=s||null,this._refreshLobby()}).catch(()=>{})):r.reason==="import-failed"||r.reason==="no-lift-export"?this.liftMissing=!0:r.reason!=="off"&&console.info(`${G} mono\u21923D unavailable (${r.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),r))}return this._liftP}_warnLiftMissing(){this._liftWarned||!this.liftMissing||!this.mono3DOn||(this._liftWarned=!0,this.warning("lift-not-bundled","a 2D participant is on a 3D display but the 2D\u21923D module could not be imported from this build, so they stay flat. Import it explicitly \u2014 `import { lift } from '@displayxr/inline3d/lift'; mountCall(el, { mono3D: lift })` \u2014 or use `@displayxr/inline3d/call/full`, which bundles it."))}_rerouteMono(){for(let e of this.tiles.values())e.format&&e.format!=="sbs"&&e.reroute(!1)}setMono3D(e){let t=e===void 0?!this.mono3DOn:!!e;return t===this.mono3DOn||(this.mono3DOn=t,t&&this.mono3D==="off"&&(this.mono3D="auto"),this._frameWatch.reset(),this.log("mono3d",{on:t}),this._rerouteMono(),t&&this.wallLive&&this._ensureLift(),this._refreshLobby()),t}_liftHint(){if(!this.wallLive)return"";let e=this.t;if(!this.mono3DOn)return e("liftOff");let t=this.liftApi;if(!t)return e("liftChecking");if(!t.lift)return this.liftMissing?e("liftMissing"):e("liftNoProvider");let i=t.caps;return i&&i.native?e("liftNative",{provider:i.provider?`, ${i.provider}`:""}):i&&i.webFallback&&i.webFallback.webgpu?e("liftWeb"):this.liftProven?e("liftProven"):e("liftUnproven")}_mono3DInfo(){let e=this.liftApi,t=e&&e.caps;return Object.freeze({on:this.mono3DOn,state:this.mono3DOn?e?e.lift?"ready":"unavailable":this._liftP?"loading":"idle":"off",reason:e?e.reason:null,native:t?!!t.native:null,provider:t&&t.provider||null,lifted:this.liftPool?this.liftPool.size:0,max:this.o.maxLifted,proven:this.liftProven})}_startStats(){clearInterval(this._statsTimer);let e=0;this._statsTimer=setInterval(()=>this._stats(++e%4===0),Jr)}async _stats(e){if(!this.transport)return;let t=null,i=0;for(let[o,a]of this.tiles){let l=this.transport.peerConnection(o);if(!l)continue;let c;try{c=await l.getStats()}catch{continue}let p={};c.forEach(d=>{d.type==="codec"&&(p[d.id]=d.mimeType)});let f={in:null,out:null};c.forEach(d=>{if(d.type==="inbound-rtp"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(a.level=Math.max(d.audioLevel,(a.level||0)*.6)),d.type==="media-source"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(i=Math.max(i,d.audioLevel)),!!e){if(d.type==="inbound-rtp"&&d.kind==="video"){let m=a._prevIn;f.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:m?Math.round((d.bytesReceived-m.bytes)*8/(d.timestamp-m.t)):null,dropped:d.framesDropped||0,decoder:d.decoderImplementation||null},a._prevIn={bytes:d.bytesReceived,t:d.timestamp}}else if(d.type==="outbound-rtp"&&d.kind==="video"){let m=a._prevOut;f.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:m?Math.round((d.bytesSent-m.bytes)*8/(d.timestamp-m.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(f.in||f.out)&&(a.quality=f,this.emit("quality",{id:o,...f}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>Zt||a.remote.speaking),h>Zt&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let r=t?t.id:null;r&&r!==this.speakerId?(this._challengeTicks=this._challenger===r?(this._challengeTicks||0)+1:1,this._challenger=r,this._challengeTicks>=2&&this._setSpeaker(r)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>Zt;s!==!!this._selfSpeaking&&(this._selfSpeaking=s,this.transport?.broadcast(this.stateMsg()),this.self?.setSpeaking(s))}_setSpeaker(e){e!==this.speakerId&&(this.speakerId=e,this._challengeTicks=0,this.liftPool?.setSpeaker(e),this.emit("speaker",{id:e}),this.o.layout==="speaker"&&this._layout())}_fitGrid(){let e=this.ui;if(!e||!this.o.chrome||typeof globalThis.innerHeight!="number")return;let t=this.container.getBoundingClientRect?.(),i=e.grid.getBoundingClientRect?.();if(!t||!i||!i.height)return;let r=Math.max(160,Math.floor(globalThis.innerHeight-Math.max(0,t.top)-(t.height-i.height)-8)),s=parseFloat(this.container.style.getPropertyValue("--dxr-call-fit"))||0;Math.abs(r-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${r}px`),this._fitHooked||(this._fitHooked=!0,globalThis.addEventListener?.("resize",()=>this._fitGrid()))}_setState(e){this.state=e,this.log("state",{state:e}),this._layout()}_buildDom(){let e=this.container,t=this.t;yn(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[r,s]of Object.entries(this.o.cssVars))e.style.setProperty(r,s);let i=this.ui={};i.banner=E("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[E("span",{text:t("banner2D")}),E("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=E("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=E("div",{class:"dxr-call-self",part:"self"}),i.bar=E("div",{class:"dxr-call-bar",part:"bar"}),i.foot=E("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||W(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new ei(this,i.selfSlot):W(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(r,s,o,a="")=>E("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":r,title:r,html:s,onclick:o});e.mic=i(t("mute"),q.mic,()=>this.mute()),e.cam=i(t("cameraOff"),q.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=E("input",{type:"range",min:"-1",max:"1",step:"0.05",value:"0","aria-label":t("depth")}),e.depth.addEventListener("input",()=>this.setDepth(+e.depth.value)),e.depth.addEventListener("dblclick",()=>this.setDepth(0)),e.inviteBtn=i(t("invite"),q.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),q.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,E("label",{class:"dxr-call-depth"},[t("depth"),e.depth]),e.inviteBtn,e.leave)}_refreshBar(){let e=this.ui;if(!e||!e.mic)return;let t=this.t;e.mic.innerHTML=this.muted?q.micOff:q.mic,e.mic.setAttribute("aria-pressed",String(this.muted)),e.mic.title=this.muted?t("unmute"):t("mute");let i=!this.local?.videoTrack;e.cam.innerHTML=this.camOff||i?q.camOff:q.cam,e.cam.setAttribute("aria-pressed",String(this.camOff||i)),e.cam.title=i?this.camStatus==="busy"?t("cameraBusyRetry",{cameraBusy:t("cameraBusy")}):t("cameraRetry"):this.camOff?t("cameraOn"):t("cameraOff")}_refreshSelf(){this.self?.update()}_refreshLobby(){(this.state==="lobby"||this.state==="idle")&&this._layout()}_renderInvite(e,t,i){e.replaceChildren();let r=this.inviteLink();if(!r)return;let s=this.t,o=E("input",{type:"text",readOnly:!0,value:r,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:s("copyLink")});a.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(r),a.textContent=s("copied")}catch{o.select(),a.textContent=s("pressCopy")}setTimeout(()=>a.textContent=s("copyLink"),1800)});let l=E("canvas",{"aria-label":s("qrLabel"),role:"img"});try{fn(l,r,{px:4})}catch{l.style.display="none"}e.append(E("h3",{text:t}),E("p",{text:i}),E("div",{class:"dxr-call-invite"},[E("div",{class:"dxr-call-row",style:"flex:1 1 280px"},[o,a]),l]))}_layout(){let e=this.ui;if(!e)return;let t=this.container,i=this.t,r=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",r),W(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),W(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,p]of this.tiles)p.el.classList.toggle("dxr-call-tile--main",c===o);if(!this.o.chrome)return;this._refreshBar(),queueMicrotask(()=>this._fitGrid());let a=e.panel;if(r){W(a,!0),a.replaceChildren();let c=this.local,p=!!this.room,f=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(p?"lobbyJoinTitle":"lobbyStartTitle"),h={width:c?.width||0,height:c?.height||0},d=this.camStatus==="busy"?i("kindBusy"):!c||!c.videoTrack?i("kindNone"):c.format==="sbs"?i("kindSbs",h):i("kindMono",h),m=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,u=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(p?"join":"start")});u.addEventListener("click",()=>this.join().catch(()=>{}));let v=E("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(v),v.addEventListener("change",()=>this.setCamera(v.value).catch(b=>this.error("camera-failed",b.message,b)));let y=!c||!c.videoTrack?E("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;y?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(E("h3",{text:f}),E("p",{text:m}),E("div",{class:"dxr-call-row"},[this.state==="full"?null:u,y,v]))}else this.state==="in-call"&&s===0?(W(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(W(a,!0),a.replaceChildren(E("p",{text:i("joining")}))):W(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),W(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:wt,wire:ze,state:this.state,wall:this.wall,wallLive:this.wallLive,weaveLive:this.weaveLive,woven:this.woven,local:e?{format:e.format,width:e.width,height:e.height,label:e.label,calibration:e.calibration,owned:e.owned,skipped:e.skipped,camera:e.cam||null,stream:e.stream}:null,hello:this.hello(),transport:this.transport,peers:[...this.tiles.values()].map(t=>t.diag()),mono3D:{...this._mono3DInfo(),lift:this.liftApi,pool:this.liftPool?this.liftPool.list():[]},speaker:this.speakerId,depth:this.depth,options:this.o,kill:t=>this.transport?._debugKill(t)}}async _fillCameras(e){let t=[];try{t=(await navigator.mediaDevices.enumerateDevices()).filter(r=>r.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((r,s)=>E("option",{value:r.deviceId,text:r.label||`Camera ${s+1}`}))),i&&(e.value=i),W(e,t.length>1)}_makeHandle(){let e=this,t={format:"display",session:null},i={get room(){return e.room},get id(){return e.id},get state(){return e.state},get localFormat(){return e.local?e.local.format:null},get muted(){return e.muted},get cameraOff(){return e.camOff},get depth(){return e.depth},get speaker(){return e.speakerId},get camera(){return e.camStatus},get mono3D(){return e._mono3DInfo()},get peers(){return Object.freeze([...e.tiles.values()].map(s=>s.info()))},join:()=>e.join().then(()=>{}),inviteLink:()=>e.inviteLink(),mute:s=>e.mute(s),setCameraOff:s=>e.setCameraOff(s),setCamera:(s,o)=>e.setCamera(s,o),setDepth:s=>e.setDepth(s),retryCamera:()=>e.retryCamera(),setMono3D:s=>e.setMono3D(s),leave:()=>e.leave("left"),tile:s=>e.tiles.get(s)?.el||null,diagnostics:()=>e.diagnostics(),on(s,o){if(typeof o!="function")throw new TypeError(`${G} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${G} the '${s}' event is deprecated (removed in 1.31)${a?` \u2014 listen for '${a}'`:" \u2014 it is internal now; diagnostics() has the wall"}`)}return e.listeners.has(s)||e.listeners.set(s,new Set),e.listeners.get(s).add(o),()=>e.listeners.get(s)?.delete(o)},off(s,o){e.listeners.get(s)?.delete(o)}},r={wall:["diagnostics().wall (or the wall you passed / sharedInline3D())",()=>e.wall],format:["localFormat",()=>i.localFormat],sendHint:["nothing \u2014 auto-convergence superseded it",()=>s=>e.sendHint(s)],_debug:["diagnostics()",()=>({transport:e.transport,kill:s=>e.transport?._debugKill(s)})]};for(let[s,[o,a]]of Object.entries(r))Object.defineProperty(i,s,{enumerable:!1,configurable:!0,get(){return e._handleWarned?.has(s)||((e._handleWarned||=new Set).add(s),console.warn(`${G} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function es(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 En(n,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!es(n))return;let r=n.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=X(a,o,n.width/n.height,0,0);r.save(),i&&(r.translate(n.width,0),r.scale(-1,1)),r.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,n.width,n.height),r.restore()}var tt=class{constructor(e,t){this.call=e,this.id=t,this.hello=null,this.format=null,this.route=null,this.routedKey=null,this.handle=null,this.conn="connecting",this.remote={muted:!1,cameraOff:!1,speaking:!1},this.level=0,this.speaking=!1,this.quality=null,this.conv=xe(),this.autoTrack=qe(),this.autoFocus=Ce(),this.autoAt=0,this.autoCanvas=null,this.autoLocked=!1,this.autoStats={n:0,ms:0,readMs:0,method:null,via:null},this.autoPending=!1,this.autoGen=0,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=kt(bt),this.layerFails=0,this.forceFlat=!1,this.lifted=!1,this.liftHandle=null,this.liftLive=!1,this.liftFailed=!1,this.liftFails=0,this.visible=!0,this.video=Object.assign(document.createElement("video"),{muted:!0,playsInline:!0,autoplay:!0}),this.audio=Object.assign(document.createElement("audio"),{autoplay:!0}),this.video.addEventListener("playing",()=>this._maybeRoute()),this.video.addEventListener("loadeddata",()=>this._maybeRoute()),this.video.addEventListener("resize",()=>this._maybeRoute()),this.canvas=E("canvas"),this.cover=E("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,E("div",{class:"dxr-call-talk"})]),e.o.ui||W(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge()}display(){return Ct(this.route)}info(){return Object.freeze({id:this.id,format:this.format||"mono",display:this.display(),state:this.conn,muted:this.remote.muted,cameraOff:this.remote.cameraOff,speaking:this.speaking})}diag(){return{...this.info(),route:this.route,rectified:!!(this.hello&&this.hello.rectified),hello:this.hello,quality:this.quality,convergencePx:this.conv.current,autoConverge:{disparityPx:this.conv.measuredPx,ms:this.autoStats.n?this.autoStats.ms/this.autoStats.n:null,readMs:this.autoStats.n?this.autoStats.readMs/this.autoStats.n:null,method:this.autoStats.method,via:this.autoStats.via},lift:this.lifted?{live:this.liftLive,native:!!(this.liftHandle&&this.liftHandle.native),priority:this.call.liftPool?this.call.liftPool.priority(this.id):null,state:this.liftHandle?this.liftHandle.state||null:"pending"}:null,element:this.el}}setStream(e){this.video.srcObject!==e&&(this.video.srcObject=e,this.audio.srcObject=e,this._resetAutoConverge()),this.video.play().catch(()=>{}),this.audio.play().catch(()=>{})}onChannelOpen(){clearTimeout(this.helloTimer),this.helloTimer=setTimeout(()=>{this.format||(this.format="mono",this._maybeRoute())},Xr)}setHello(e){clearTimeout(this.helloTimer),this.hello=e,this.conv.hello=e;let t=this.format!==e.format;this.format=e.format,this.call.log("hello",{peer:this.id,format:e.format,width:e.width,height:e.height,rectified:e.rectified}),t?this._maybeRoute():this._renderBadge()}setHint(e){this.hintGate(performance.now())&&(this.conv.subjectZmm=e.subjectZmm)}setRemoteState(e){this.remote=e,this._renderBadge(),this._renderPlate(),this._updateVisible()}setSpeaking(e){e!==this.speaking&&(this.speaking=e,this.el.classList.toggle("dxr-call-tile--speaking",e))}setConn(e){e==="unreachable"&&this.conn!=="unreachable"&&this.call.error("unreachable",`${this.call.t("unreachable")}. Still retrying in the background.`,Object.assign(new Error("unreachable"),{peer:this.id})),this.conn=e,e==="connected"&&this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this._renderPlate()}_renderPlate(){let e=this.call.t,t=this.conn==="left"?e("leftCall"):this.conn==="unreachable"?e("unreachable"):this.conn==="reconnecting"?e("reconnecting"):this.conn!=="connected"?e("connecting"):this.remote.cameraOff?e("cameraOffPlate"):null;this.plate.textContent=t||"",W(this.plate,!!t)}_renderBadge(){let e=this.call.t,t=this.route==="woven-sbs"?e("badge3D"):this.route==="lifted"?e("badge2D3D"):e("badge2D"),i=this.route?this.route==="lifted"&&!this.liftLive?`${t}${e("badgePending")}`:t:e("badgePending");this.badge.replaceChildren(E("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",q.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,r=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:Tt({format:this.format,woven:t.woven,mono3D:t.mono3DOn?"auto":"off",lift:!!i,overBudget:i?!i.canAcquire(this.id):!1,failed:this.liftFailed});this.format!=="sbs"&&t.woven&&t.mono3DOn&&!t._liftP&&t._ensureLift(),this.format!=="sbs"&&t.woven&&t.liftMissing&&t._warnLiftMissing();let s=`${r.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=r.route,r.route==="woven-sbs"?this._registerWoven():r.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:r.route,format:this.format,mono3d:r.mono3d||null}),t.emit("display",{id:this.id,display:this.display()}),t.listeners.get("format")?.size&&t.emit("format",{id:this.id,format:this.format,route:r.route,mono3d:r.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),W(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(W(this.cover,!1),e.log("first-woven",{peer:this.id,woven:i.woven,reason:i.reason,ms:Math.round(i.ms)}),!i.woven&&i.reason==="layer-failed"&&this._layerFailed())})}_registerLifted(){let e=this.call,t=e.liftPool;this.lifted=!0,this.liftLive=!1,this.video.classList.add("dxr-call-liftsrc"),this.canvas.classList.add("dxr-call-liftflat"),this.video.parentNode!==this.stage&&this.stage.insertBefore(this.video,this.stage.firstChild),this._observeVisible(),t.acquire(this.id,this.video,{wall:e.wall,visible:this.visible,onError:i=>this._liftError(i)}).then(i=>{if(!i||!this.lifted||t.handle(this.id)!==i)return;this.liftHandle=i;let r=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>r(s&&s.state)),i.on?.("error",s=>{s&&s.fatal&&this._liftError(s.error)})],i.state==="live"?this._liftShowing(!0):i.canvas&&i.canvas.style&&(i.canvas.style.visibility="hidden"),e.log("lifted",{peer:this.id,native:!!i.native,woven:!!i.woven,state:i.state||null,provider:i.stats&&i.stats.provider||null})})}_liftShowing(e){if(e===this.liftLive)return;this.liftLive=e;let t=this.liftHandle;e?(t&&t.canvas&&t.canvas.style&&!t.native&&(t.canvas.style.visibility=""),this.canvas.style.visibility="hidden",this.liftFails=0,this.call.liftProven||(this.call.liftProven=!0,this.call._refreshLobby())):this.canvas.style.visibility="",this.call.log("lift-live",{peer:this.id,live:e}),this._renderBadge()}_liftError(e){this.lifted&&(this.call.log("lift-error",{peer:this.id,message:String(e&&e.message||e).slice(0,200)}),this.liftFailed=!0,this.reroute(!0),!(this.liftFails++>=Yr)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},B(this.liftFails-1,{baseMs:3e3,maxMs:3e4}))))}_observeVisible(){this._io||typeof IntersectionObserver!="function"||(this._io=new IntersectionObserver(e=>{let t=e[e.length-1];this._onscreen=!!(t&&t.isIntersecting),this._updateVisible()}),this._io.observe(this.stage))}_updateVisible(){let e=this._onscreen!==!1&&!this.remote.cameraOff;e!==this.visible&&(this.visible=e,this.call.liftPool?.setVisible(this.id,e))}_layerFailed(){if(this.forceFlat=!0,this.reroute(!0),this.layerFails++>=Kr)return;let e=B(this.layerFails-1,{baseMs:1500,maxMs:2e4});this.call.log("layer-retry",{peer:this.id,attempt:this.layerFails,inMs:e}),clearTimeout(this.layerTimer),this.layerTimer=setTimeout(()=>{this.forceFlat=!1,this.call.woven&&this.reroute(!0)},e)}onWallLost(){this.handle=null,this.reroute(!0)}_unregister(){if(W(this.cover,!1),this.lifted){this.lifted=!1;for(let e of this._liftOff||[])typeof e=="function"&&e();this._liftOff=null,this.call.liftPool?.release(this.id),queueMicrotask(()=>this.call.state!=="left"&&this.call._rerouteMono()),this.liftHandle=null,this.liftLive=!1,this.canvas.style.visibility="",this.canvas.classList.remove("dxr-call-liftflat"),this._io&&(this._io.disconnect(),this._io=null),this.video.parentNode&&(this.video.remove(),this.video.classList.remove("dxr-call-liftsrc"),setTimeout(()=>this.video.srcObject&&this.video.play().catch(()=>{}),0))}if(this.handle){try{this.handle.remove()}catch{}this.handle=null}}paint(){this.route&&(this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||En(this.canvas,this.video):En(this.canvas,this.video,{eyeHalf:this.route==="flat-left"?0:null}))}_paintConv(){let e=this.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.convCanvas)return;let r=t/2,s=this.call.o.tileAspect,{w:o,h:a}=be(r,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a),this.call.o.autoConverge&&this._sampleDisparity(e,t,i);let c=this.conv.step(r),p=l.getContext("2d");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)}}_sampleDisparity(e,t,i){let r=performance.now();if(this.autoPending||r-this.autoAt<Zr)return;if(this.autoAt=r,typeof VideoFrame=="function"){let f=null;try{f=new VideoFrame(e)}catch{f=null}if(f&&Qr.has(f.format)){this.autoPending=!0;let h=this.autoGen,d=f.visibleRect?f.visibleRect.width:f.displayWidth,m=f.visibleRect?f.visibleRect.height:f.displayHeight,u=new Uint8Array(f.allocationSize());f.copyTo(u).then(v=>{if(h!==this.autoGen)return;let y=performance.now(),b=Math.max(1,Math.ceil(d/2/Mn)),C=Vi(u,v[0].offset,v[0].stride,d,m,b);this._applyMeasurement(C.img,C.w,C.h,C.w/d,r,performance.now()-y,"videoframe")}).catch(()=>{h===this.autoGen&&this._applyMeasurement(null,0,0,1,r,0,"videoframe")}).finally(()=>{f.close(),this.autoPending=!1});return}f&&f.close()}let s=Math.min(1,Mn/(t/2)),o=Math.max(2,Math.round(t*s/2)*2),a=Math.max(2,Math.round(i*s));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let l=this.autoCanvas;(l.width!==o||l.height!==a)&&(l.width=o,l.height=a);let c=l.getContext("2d",{willReadFrequently:!0}),p=null;try{c.drawImage(e,0,0,o,a),p=Be(c.getImageData(0,0,o,a).data,o*a)}catch{p=null}this._applyMeasurement(p,o,a,o/t,r,performance.now()-r,"canvas")}_applyMeasurement(e,t,i,r,s,o,a){if(this.destroyed)return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,p=this.autoTrack.push(c?c.d/r:null);this.conv.measuredPx=p,this.autoStats.n++,this.autoStats.readMs+=o,this.autoStats.ms+=o+(performance.now()-l),this.autoStats.method=c?c.method:null,this.autoStats.via=a,c&&!this.autoLocked&&(this.autoLocked=!0,this.call.log("auto-converge",{peer:this.id,disparityPx:Math.round(p*10)/10,at:{x:Math.round(c.x/r),y:Math.round(c.y/r)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,clearTimeout(this.helloTimer),clearTimeout(this.layerTimer),clearTimeout(this.leaveTimer),clearTimeout(this.liftTimer),this._unregister(),this.video.srcObject=null,this.audio.srcObject=null,this.el.remove()}},ei=class{constructor(e,t){this.call=e,this.canvas=E("canvas"),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,E("div",{class:"dxr-call-talk"})]),t.appendChild(this.el),this.view=null,this.cam=null}get route(){return this.view?this.view.route:null}update(){let e=this.call.local,t=this.call.t,i=!e||!e.videoTrack;this.plate.textContent=i?this.call.camStatus==="busy"?t("cameraBusy"):this.call.camStatus==="pending"?"":t("noCamera"):this.call.camOff?t("cameraOffPlate"):"",W(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,r=this.call.woven?this.call.wall:{supported:!1};if(!i||i.state!=="live")return this.detach(),this._badge();this.view&&this.cam===i?this.view._reroute(e,r):(this.detach(),this.cam=i,this.view=Ht(r,this.canvas,i,{mirror:!0,autoConverge:!1,aspect:this.call.o.tileAspect})),this._badge()}_badge(){let e=this.call.t;this.badge.replaceChildren(E("b",{text:`${e("you")} \xB7 ${this.route==="woven-sbs"?e("badge3D"):e("badge2D")}`}))}onWallLost(){this.view?._onWallLost(),this._badge()}detach(){this.view&&this.view.remove(),this.view=null,this.cam=null}setSpeaking(e){this.el.classList.toggle("dxr-call-tile--speaking",e)}},ts="1.31",kn=new Set;function D(n,e,t){let i=()=>{kn.has(n)||(kn.add(n),console.warn(`${G} \`${n}\` is internal and leaves '@displayxr/inline3d/call' in ${ts} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(r,s,o){return i(),Reflect.apply(r,s,o)},construct(r,s){return i(),Reflect.construct(r,s)}}):t&&typeof t=="object"?new Proxy(t,{get(r,s,o){return typeof s=="string"&&i(),Reflect.get(r,s,o)}}):t}var oo=D("normalizeCallOptions","js/call/options.js",Xt),ao=D("newRoomId","js/call/wire.js",xt),lo=D("isValidRoomId","js/call/wire.js",le),co=D("buildInviteLink","js/call/wire.js",He),ho=D("normalizeHello","js/call/wire.js",St),fo=D("makeHello","js/call/wire.js",Mt),uo=D("routeFor","js/call/wire.js",Tt),po=D("badgeFor","js/call/wire.js",Ct),mo=D("createLiveGate","js/call/wire.js",Rt),go=D("convergenceShiftPx","js/camera/converge.js",je),_o=D("lowPass","js/camera/converge.js",Ne),vo=D("clampShift","js/camera/converge.js",We),yo=D("eyeCropRect","js/camera/geometry.js",X),wo=D("mirrorSwapOps","js/camera/geometry.js",oe),bo=D("mirrorSwapPixels","js/camera/geometry.js",yt),xo=D("maxBitrateKbps","js/call/wire.js",Ve),So=D("measureFocusDisparity","js/camera/disparity.js",It),Mo=D("preferVideoCodecs","js/call/sdp.js",Ee),Eo=D("sortCodecCapabilities","js/call/sdp.js",$e),ko=D("VIDEO_CODEC_ORDER","js/call/sdp.js",Me),To=D("MeshTransport","js/call/transport.js",ke),Co=D("clampMaxPeers","js/call/transport.js",Te),Ro=D("qrEncode","js/call/qr.js",Ut),Do=D("roomKey","js/call/signaling.js",Bt);var Lo=D("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:De.unreachable,cameraBusy:De.cameraBusy})),Ao=D("CALL_ACCENTS","js/call/ui.js",qt),Io=D("normalizeMono3D","js/call/lift.js",ye),Oo=D("resolveLift","js/call/lift.js",nt),Po=D("createLiftPool","js/call/lift.js",ot),Fo=D("createFrameWatch","js/call/lift.js",st),jo=D("liftConvergenceFor","js/call/lift.js",ve),Wo=D("liftPriorityFor","js/call/lift.js",Le),No=D("setLiftPriority","js/call/lift.js",rt),zo=D("defaultLiftSpecifier","js/call/lift.js",it),Ho=D("LIFT_PRIORITY","js/call/lift.js",_e);et();ii(()=>new URL("./lift.js",import.meta.url).href);export{Jt as CALL_EVENT_PREFIX,on as CAMERA_SDK,Qe as DXR_SIGNAL_DEFAULT,pe as DxrCallElement,Tn as addCall,Ht as addCameraView,Kt as attrsToOpts,Ti as createInline3D,et as defineCallElement,fe as dxrSignaling,Ei as inline3DAvailable,Ze as isStereoCamera,Yt as mountCall,zt as openCamera,Se as parseInviteLink,Pt as parseStereoXmp,Ji as readJpegStereoMeta,Ft as readJpegXmp,nn as readWebmStereoMeta,Fe as sharedInline3D,Ye as suggestedName};
|