@displayxr/inline3d 1.40.1 → 1.40.2

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 CHANGED
@@ -5,6 +5,18 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
5
5
  `./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
6
6
  which tier they touch, because that is what tells you whether an upgrade can move your pixels.
7
7
 
8
+ ## 1.40.2 — 2026-10-11
9
+
10
+ Touches the **preview tier** (`./call`, `./camera`) only; no API change.
11
+
12
+ ### Stereo-tile depth cursor: the margin is 2 mm on the glass
13
+
14
+ - The arrow now floats **2 mm** (of on-screen disparity) in front of content that comes out of the
15
+ screen, and hands back to the OS arrow under **0.3 mm** — the runtime's 0.03 / 0.005 of the eye
16
+ baseline, so a stereo tile's cursor and a lifted tile's (runtime #1908) sit identically. 1.40.1
17
+ used ~1–2 buffer px, which on a small tile was a fraction of a millimetre. Physical units come from
18
+ the tile's `displayMetrics()` (the panel's pixel pitch); before it answers, the CSS reference px.
19
+
8
20
  ## 1.40.1 — 2026-10-11
9
21
 
10
22
  Touches the **preview tier** (`./call`, `./camera`) only: how `cursor: 'depth'` looks and moves. No
package/dist/call.js CHANGED
@@ -1,8 +1,8 @@
1
- /* @displayxr/inline3d 1.40.1 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
2
- var or=Object.defineProperty;var Ae=(n,e)=>()=>(n&&(e=n(n=0)),e);var ar=(n,e)=>{for(var t in e)or(n,t,{get:e[t],enumerable:!0})};function Xe(n,e,t,i,r,s,o,a,l,c,f){if(s<0||s+a>t||o<0)return-1;let m=0,h=0,d=0,u=a*l;for(let v=0;v<l;v++){let b=(r+v)*e+i,R=(o+v)*e+t+s;for(let x=0;x<a;x++){let I=n[R+x];m+=I,h+=I*I,d+=n[b+x]*I}}let p=m/u,y=h/u-p*p;return y<1?-1:(d/u-c*p)/(f*Math.sqrt(y))}function is(n,e,t,i,r,s){let o=0,a=0;for(let f=0;f<s;f++){let m=(i+f)*e+t;for(let h=0;h<r;h++){let d=n[m+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 Re(n,e,t,i,r,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:f}={}){let m=e/2,{mean:h,std:d}=is(n,e,i,r,s,o);if(d<6)return null;let u=-2,p=0,y=0,v=new Map,b=(T,g,w,_,M)=>{for(let O=_;O<=M;O++){let S=r+O;if(!(S<0||S+o>t))for(let F=T;F<=g;F+=w){let H=Xe(n,e,m,i,r,i-F,S,s,o,h,d);H>(v.get(F)??-2)&&v.set(F,H),H>u&&(u=H,p=F,y=O)}}},R=l-a>8;if(b(a,l,R?2:1,-c,c),R&&u>-1){let T=p,g=y;b(Math.max(a,T-2),Math.min(l,T+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(u<-1)return null;let x=-2,I=T=>{let g=-2;for(let w=-c;w<=c;w++){let _=r+w;if(!(_<0||_+o>t))for(let M=T-1;M<=T+1;M++)g=Math.max(g,Xe(n,e,m,i,r,i-M,_,s,o,h,d))}return g};for(let[T,g]of v){if(Math.abs(T-p)<3||g<=x)continue;let _=g>=(v.get(T-2)??-2)&&g>=(v.get(T+2)??-2)&&g>0?I(T):g;_>x&&(x=_)}if(l-a>12&&x>-2&&u-x<(f??.08))return null;let C=Xe(n,e,m,i,r,i-(p-1),r+y,s,o,h,d),D=Xe(n,e,m,i,r,i-(p+1),r+y,s,o,h,d),P=0,A=C-2*u+D;return C>-1&&D>-1&&A<0&&(P=Math.max(-.5,Math.min(.5,.5*(C-D)/A))),{d:p+P,dy:y,c:u}}function ns(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)),f=Math.round(r*(i.roiX1??.85))-s,m=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let u=m;u<=h;u+=o)for(let p=c;p<=f;p+=o){let y=Re(n,e,t,p,u,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});y&&y.c>=(i.minNcc??.8)&&d.push({x:p,y:u,...y})}return d}function rs(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,f)=>c-f);return{d:l[l.length>>1],members:a}}}return null}function ss(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 $t(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",f=0,m=null;if(!l){let R=ns(n,e,t,{...i,block:s,dMax:o,dMin:a});f=R.length;let x=rs(R,i);if(!x)return null;l=ss(x.members,s),m=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),u=Math.round(Math.max(0,Math.min(r-h,l.x-h/2))),p=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),y=m===null?a:Math.max(a,Math.floor(m)-4),v=m===null?o:Math.min(o,Math.ceil(m)+4),b=Re(n,e,t,u,p,h,d,{dMin:y,dMax:v,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:f}:m!==null?{d:m,x:l.x,y:l.y,c:0,method:c,blocks:f}:null}function Ge(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 Je({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 rn(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 os(n,e,t,i,r,s,o,a,l,c){let f=e/2,m=r*s,h=0,d=0;for(let b=0;b<m;b++)h+=i[b],d+=i[b]*i[b];h/=m;let u=Math.sqrt(Math.max(1e-6,d/m-h*h)),p=-2,y=o,v=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let R=Math.max(0,o-l);R<=Math.min(f-r,o+l);R++){let x=0,I=0,C=0;for(let T=0;T<s;T++){let g=(b+T)*e+R;for(let w=0;w<r;w++){let _=n[g+w];x+=_,I+=_*_,C+=_*i[T*r+w]}}let D=x/m,P=I/m-D*D;if(P<1)continue;let A=(C/m-D*h)/(Math.sqrt(P)*u);A>p&&(p=A,y=R,v=b)}return{x:y,y:v,c:p}}function Te({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,f,m,h,d={}){let u=f/2,p=d.block||Math.max(8,Math.round(u/20)),y=Math.round(p*3),v=Math.round(p*1.5),b=null;if(o&&o.w===y&&o.h===v){let D=os(c,f,m,o.tpl,y,v,o.x,o.y,t,i);if(D.c>=r){let P=Re(c,f,m,D.x,D.y,y,v,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});P&&P.c>=.8&&(b={m:P,f:D})}}let R=({m:D,f:P})=>(o={...o,x:P.x,y:P.y,d:D.d,tpl:rn(c,f,P.x,P.y,y,v)},{d:D.d,x:P.x+y/2,y:P.y+v/2,c:D.c,method:"track",blocks:0});if(b&&h-o.at<n)return R(b);let x=$t(c,f,m,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let D=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!D?{d:x.d}:null,!D)return o.at=h,R(b)}else a=null;if(!x)return o=null,null;let I=Math.round(Math.max(0,Math.min(u-y,x.x-y/2))),C=Math.round(Math.max(0,Math.min(m-v,x.y-v/2)));return o={x:I,y:C,d:x.d,tpl:rn(c,f,I,C,y,v),w:y,h:v,at:h},x},reset(){o=null,a=null}}}function sn(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 u=0;u<a;u++){let p=0;for(let y=0;y<o;y++){let v=e+(d*o+y)*t+u*o;for(let b=0;b<o;b++)p+=n[v+b]}c[d*a+u]=p/h|0}return{img:c,w:a,h:l}}let f=o>>2,m=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+f)*t,u=e+(h*o+m)*t;for(let p=0;p<a;p++){let y=p*o+f,v=p*o+m;c[h*a+p]=n[d+y]+n[d+v]+n[u+y]+n[u+v]>>2}}return{img:c,w:a,h:l}}var Vt=Ae(()=>{"use strict"});function as(n,e="@displayxr/inline3d"){if(n==null||n===!1)return null;if(n==="depth"||n===!0)return{};if(typeof n!="object")throw new Error(`${e}: cursor ${JSON.stringify(n)} \u2014 expected 'depth' or { height, margin, anchor, pointerScope }.`);let t=Object.keys(n).filter(i=>!an.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${an.join(", ")}.`);if(n.anchor!==void 0&&!on.includes(n.anchor))throw new Error(`${e}: cursor.anchor "${n.anchor}" \u2014 expected ${on.join(", ")}.`);if(n.pointerScope!==void 0&&n.pointerScope!=="canvas"&&n.pointerScope!=="window")throw new Error(`${e}: cursor.pointerScope "${n.pointerScope}" \u2014 expected 'canvas' or 'window'.`);for(let i of["height","margin"])if(n[i]!==void 0&&!(typeof n[i]=="number"&&n[i]>0&&Number.isFinite(n[i])))throw new Error(`${e}: cursor.${i} must be a positive number.`);return{...n}}function Ye(n,e="@displayxr/inline3d"){let t=as(n,e);if(!t)return null;let i=Object.keys(t).filter(r=>!ln.includes(r));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${ln.join(", ")}.`);return t}var on,an,ln,Ut=Ae(()=>{"use strict";on=Object.freeze(["hybrid","screen","world"]),an=Object.freeze(["height","margin","anchor","pointerScope"]);ln=Object.freeze(["height","pointerScope"])});function Mn(n,e,t,i){if(!n.primed||i<n.last||i-n.last>e.stale)return n.primed=!0,n.disparity=t,n.last=i,t;if(i===n.last)return n.disparity;let r=i-n.last,s=t<n.disparity?e.riseTau:e.sinkTau,o=s>0?1-Math.exp(-r/s):1;return n.disparity+=o*(t-n.disparity),n.last=i,n.disparity}function ps(n){let e=globalThis.document;if(!(!e||!e.documentElement)){if(n&&!e.getElementById("inline3d-cursor-style")){let t=e.createElement("style");t.id="inline3d-cursor-style",t.textContent="html.inline3d-cursor-hidden, html.inline3d-cursor-hidden * { cursor: none !important; }",(e.head||e.documentElement).appendChild(t)}Jt=Math.max(0,Jt+(n?1:-1)),e.documentElement.classList.toggle("inline3d-cursor-hidden",Jt>0)}}function En(n,e,t,i){let r=.75*t,s=[[n,e]];for(let o=0;o<8;o++){let a=o*Math.PI/4;s.push([n+r*Math.cos(a)/i,e+r*Math.sin(a)])}return s}var Sn,et,Jt,So,Mo,Eo,Cn=Ae(()=>{"use strict";Sn=Object.freeze({margin:.005,minDisparity:-.6,maxDisparity:.6,riseTau:.03,sinkTau:.25,stale:.5});et=class{constructor(e,{scope:t="canvas"}={}){if(t!=="canvas"&&t!=="window")throw new Error(`@displayxr/inline3d: cursor pointerScope "${t}" \u2014 expected 'canvas' or 'window'.`);this.canvas=e,this.scope=t,this.uv=null,this._hidden=!1,this._prev="",this._onMove=i=>{let r=e.getBoundingClientRect();if(!(r.width>0&&r.height>0))return void(this.uv=null);let s=(i.clientX-r.left)/r.width,o=(i.clientY-r.top)/r.height;this.uv=s>=0&&s<=1&&o>=0&&o<=1?[s,o]:null},this._onLeave=()=>{this.uv=null},this._target=t==="window"?globalThis:e,this._target.addEventListener("pointermove",this._onMove),t==="window"?(this._onOut=i=>{i.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}set(e,t){this.uv=e==null?null:[e,t]}aspect(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.width/e.height:1}hideCss(e){e!==this._hidden&&(this.scope==="window"?ps(e):e?(this._prev=this.canvas.style.cursor||"",this.canvas.style.cursor="none"):this.canvas.style.cursor=this._prev,this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}},Jt=0;So=Object.freeze([[-.5,0,-.15,0],[.15,0,.5,0],[0,-.5,0,-.15],[0,.15,0,.5],[-.15,-.15,.15,-.15],[.15,-.15,.15,.15],[.15,.15,-.15,.15],[-.15,.15,-.15,-.15]]),Mo=Object.freeze([1,.84,.1,1]),Eo=Object.freeze([.04,.04,.06,.85])});var Kt={};ar(Kt,{PAIR_CURSOR_ARROW:()=>Ln,PAIR_CURSOR_CLAMP:()=>An,PAIR_CURSOR_CSS_PX:()=>kn,PAIR_CURSOR_HEIGHT:()=>Rn,PAIR_CURSOR_MARGIN:()=>Dn,PAIR_CURSOR_SHOW_PX:()=>Tn,PairCursor:()=>Yt,drawPairArrow:()=>Pn,pairCursorTarget:()=>In,pairFootprintDisparity:()=>On});function On(n,e,t,i,r,s){if(!n||!n.img||!e||!e.rL||!e.rR||!(e.outW>0))return null;let{img:o,w:a,h:l,scale:c}=n,f=a/2,m=Math.max(8,Math.round(f/20)),h=Math.round(f*.3),d=-Math.round(f*.05),{rL:u,rR:p}=e,y=e.outW/u.sw,v=null;for(let[b,R]of En(t+.3*r/s,i+.5*r,r,s)){if(!(b>=0&&b<=1&&R>=0&&R<=1))continue;let x=e.mirror?1-b:b,I=Math.round((u.sx+x*u.sw)*c-m/2),C=Math.round((u.sy+R*u.sh)*c-m/2);if(I<0||I+m>f||C<0||C+m>l)continue;let D=Re(o,a,l,I,C,m,m,{dMin:d,dMax:h,dyMax:2});if(!D||D.c<.8)continue;let P=(D.d/c-(u.sx-p.sx))*y;(v===null||P>v)&&(v=P)}return v}function In(n,e){return n===null||!Number.isFinite(n)||!(n>0)?0:Math.min(An*e,n+Dn*e)}function Pn(n,e,t,i,r,s,o){let a=r*t;for(let l of[0,1]){let c=l*e+i*e+(l===0?s/2:-s/2);n.save(),n.beginPath(),n.rect(l*e,0,e,t),n.clip(),n.beginPath(),Ln.forEach(([f,m],h)=>(h?n.lineTo:n.moveTo).call(n,c+f*o,a+m*o)),n.closePath(),n.fillStyle="#fff",n.fill(),n.lineWidth=Math.max(1,o/19),n.lineJoin="miter",n.strokeStyle="#000",n.stroke(),n.restore()}}var kn,Rn,Tn,Ln,Dn,An,Yt,Zt=Ae(()=>{"use strict";Cn();Vt();kn=19,Rn=.06,Tn=.5,Ln=Object.freeze([[0,0],[0,16/19],[4.2/19,12.4/19],[6.9/19,18.6/19],[9.5/19,17.5/19],[6.8/19,11.5/19],[11.7/19,11.5/19]]),Dn=.002,An=.08;Yt=class{constructor(e,{height:t,pointerScope:i="window"}={}){this.pointer=new et(e,{scope:i}),this.height=t>0?t:null,this.filter={},this._luma=null,this._uv=null,this._content=null,this.last=null}get hovering(){return!!this.pointer.uv}draw(e,t,i,r){let s=this.pointer.uv;if(!s)return this.idle();let[o,a]=s,l=this.height??this._osArrowFraction();(t!==this._luma||!this._uv||this._uv[0]!==o||this._uv[1]!==a)&&(this._content=On(t,i,o,a,l,i.outW/i.outH),this._luma=t,this._uv=s);let c=In(this._content,i.outW),f=-Mn(this.filter,Sn,-c,r),m=f>=Tn;return m&&Pn(e,i.outW,i.outH,o,a,f,l*i.outH),this.pointer.hideCss(m),this.last={contentPx:this._content,targetPx:c,disparityPx:m?f:0,drawn:m},this.last}_osArrowFraction(){let e=this.pointer.canvas.getBoundingClientRect?.();return e&&e.height>0?Math.min(.5,kn/e.height):Rn}idle(){return this.pointer.hideCss(!1),this.filter={},this._uv=null,this.last=null,null}dispose(){this.pointer.dispose()}}});var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),lr=["high","normal","low","paused"],cr=.02,hr=1e3/20,dr=3e3,ur=1e3/28;function ve(n){return typeof n=="function"?n:n===!1||n==="off"?"off":"auto"}function at(n=import.meta.url){return ge?typeof ge=="function"?ge():ge:new URL("../lift/index.js",n).href}var ge=null;function _i(n){ge=n||null}function fr(){return import(at())}async function lt(n,{importer:e=fr,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=ve(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 f=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,m=null;if(f){try{m=await f(r)}catch{m=null}let h=!!(m&&m.webFallback&&m.webFallback.webgpu);if(m&&!m.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(m&&m.native),provider:m&&m.provider||null}),{lift:c,capabilities:f,caps:m,source:"module",reason:null}}function ye(n){let e=Number.isFinite(+n)&&n!==null?Math.max(-1,Math.min(1,+n)):0;return Math.abs(e)<cr?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Oe({id:n,speakerId:e,visible:t=!0}){return t?n!=null&&n===e?_e.speaker:_e.other:_e.hidden}function ct(n,e){if(!n||!lr.includes(e)||typeof n.setPriority!="function")return!1;try{return n.setPriority(e)!==!1}catch{return!1}}function ht({degradedMs:n=hr,recoveredMs:e=ur,holdMs:t=dr,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 dt({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),f=(h,d)=>{if(!d.handle)return;let u=Oe({id:h,speakerId:o,visible:d.visible});if(u===d.priority)return;d.priority=u;let p=ct(d.handle,u);c("lift-priority",{peer:h,priority:u,applied:p})},m={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:u,visible:p=!0,onError:y}={}){let v=s.get(h);if(v)return v.pending||Promise.resolve(v.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,R=Oe({id:h,speakerId:o,visible:p}),x={gen:b,handle:null,visible:p,priority:R,pending:null};s.set(h,x);let I={quality:"auto",...r,mode:"live",wall:u,ui:"none",convergence:ye(a),priority:R};return c("lift-acquire",{peer:h,priority:R,convergence:I.convergence}),x.pending=Promise.resolve().then(()=>n(d,I)).then(C=>{if(s.get(h)!==x||x.gen!==b){try{C&&C.remove&&C.remove()}catch{}return null}return x.pending=null,x.handle=C||null,x.priority=null,f(h,x),C&&typeof C.setConvergence=="function"&&C.setConvergence(ye(a)),x.handle},C=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(C&&C.message||C).slice(0,200)}),y&&y(C),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()])m.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,u]of s)f(d,u)},setVisible(h,d){let u=s.get(h);!u||u.visible===!!d||(u.visible=!!d,f(h,u))},setDepth(h){a=h;let d=ye(h);for(let u of s.values())u.handle&&typeof u.handle.setConvergence=="function"&&u.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 m}var mr=null;function yi(n){mr=typeof n=="function"?n:null}var gr=new WeakMap;function vi(n,e){n&&(typeof n=="object"||typeof n=="function")&&gr.set(n,e)}var _r=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063});function wi(n,e,t=1){let i=_r,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])),f=n?.nominalViewerPosition?.z,m=Number.isFinite(f)&&f>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:m?f:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:r?"display":"default",viewer:m?"display":"default",eyeSeparation:"default"}}}var bi=new WeakMap,J;function xi(n){let e=null;for(let[t,i]of n)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function yr(n){if(!n||typeof n.getParameter!="function")return null;let e=bi.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=xi([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=xi([["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 bi.set(n,c),c}function Si(){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=yr(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function Mi(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,f=Math.min(l,c);if(!(f<1))return a;let m=l<=c,h=Math.max(1,Math.min(Math.floor(n*f+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*f+1e-9),Math.floor(t.maxH/r)));return{eyeW:h,eyeH:d,cols:i,scale:f,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*r,limitName:m?t.nameW:t.nameH,limitValue:m?t.valueW:t.valueH}}function ut(n){return Math.round(n*1e3)/1e3}function Ei(n,e,t){let i=typeof t=="number"?` (renderScale ${ut(t)} \u2192 ${ut(t*e.scale)})`:` (scale ${ut(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 Ci(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 ki(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 ne="smoothstep",pt=["linear","smoothstep","easeoutcubic"];function mt(n){if(typeof n!="string")return null;let e=n.toLowerCase().replace(/[-_\s]/g,"");return pt.includes(e)?e:null}function vr(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 ie="idle",Ri="rampDownThenFire",ft="fireThenRampUp",Ie=class{constructor(e,t){this._phase=ie,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=ne,(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=mt(t)||ne),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,f=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=f,a&&!l?(this._phase=Ri,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=ft,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=ft,this._to=a?f: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!==ie){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)*vr(this._easing,this._t),this._phase===ft?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=ie)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=ie)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==ie}value(){return this._cur}firePending(){return this._phase===Ri?this._fireAtEnd:this._firePending}cancel(){return this._phase=ie,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var B=null;yi(n=>{let e=B;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 wr=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Pe=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,gt=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},br=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Ni=["renderingmodechange","hardwaredisplaystatechange"],Et="trackingstatechange",zi=["unknown","tracking","searching"],Li=[...Ni,Et];function Fe(n){try{let e=n?n.trackingState:void 0;return zi.includes(e)?e:null}catch{return null}}var _t=()=>{if(!Q())return!1;try{let n=window.XRDisplayLayer.prototype;return br.every(e=>typeof n[e]=="function")}catch{return!1}},yt=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},se=null;function re(){if(se!==null)return se;if(!Q())return!1;try{let n=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof n=="boolean")return se=n}catch{}return!1}function xr(n){if(se!==null)return se;if(!n||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return se=!!n.occlusionByDrawOrder}catch{return null}}var Di=!1;function vt(){Di||(Di=!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 Hi(){return wr()&&Q()}function wt(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 Sr(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 Mr=16;function N(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Ct=1200,Er=new Set(["pending","woven","withheld"]),Ai=3,Cr=new Set(["getDisplayInfo","getRenderingModes","requestRenderingMode"]),kr=new Set(["getDisplayInfo","getRenderingModes"]);function Rr(n){return n==null||Array.isArray(n)&&n.length===0}function bt(){try{let n=typeof XRDisplayLayer=="function"?XRDisplayLayer:null;return!!(n&&n.prototype&&"wovenState"in n.prototype)}catch{return!1}}function We(n){try{let e=n?n.wovenState:null;return Er.has(e)?e:null}catch{return null}}function xt(n){try{let e=n?n.withheldReason:null;return typeof e=="string"&&e?e:null}catch{return null}}var Oi=!1;function Tr(n){if(n==null)return ne;let e=mt(n);return e||(Oi||(Oi=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(n)} } }) is not a curve this SDK knows (${pt.join(" / ")}); using '${ne}'.`)),ne)}var Ii=!1;function Lr(){Ii||(Ii=!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 kt(n){return n&&n.detail!==void 0&&n.detail!==null?n.detail:void 0}function $i(n){let e=kt(n);return e!==void 0?[e,n]:[n]}function Dr(n){for(let e of $i(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 Ar(n){for(let e of $i(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 Pi=!1;function Or(){Pi||(Pi=!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 Fi=!1;function Ir(){Fi||(Fi=!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 Vi(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(!Hi())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(f){return{supported:!1,trackingState:"unknown",error:f}}a!==void 0&&vi(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new Rt(l,c,{lazy:t,rootMargin:i,autoChrome:r,modeSwitch:s,untrackedFallback:o})}var we=null;function Ne(n={}){return B&&B._running?Promise.resolve(B):we||(we=Vi(n).finally(()=>{we=null}),we)}var Wi=.7,Pr=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Fr(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(Pr.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 St=4;function Mt(n){let e=typeof window<"u"&&window.devicePixelRatio||1,t="";if(typeof n.getBoundingClientRect=="function"){let i=n.getBoundingClientRect()||{},r=typeof window<"u"&&window.scrollX||0,s=typeof window<"u"&&window.scrollY||0;t=`+${Math.round((i.left??i.x??0)+r)},${Math.round((i.top??i.y??0)+s)}`}return`${n.clientWidth}x${n.clientHeight}@${e}${t}`}function ji(n){let e=typeof window<"u"&&window.devicePixelRatio||1;return{width:n.clientWidth||0,height:n.clientHeight||0,dpr:e}}function Wr(n){if(n==null||n===!1||n==="off")return null;if(n==="auto"||n===!0)return{color:"#000",snapshot:!0};if(typeof n=="object"){if(n.color!==void 0&&typeof n.color!="string")throw new TypeError("[inline3d] rectCover.color must be a CSS color string.");return{color:n.color||"#000",snapshot:n.snapshot!==!1}}throw new TypeError(`[inline3d] rectCover: expected 'auto', 'off' or { color?, snapshot? }; got ${JSON.stringify(n)}.`)}var Rt=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._claims=new Map,this._doubleWarned=new WeakSet,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 Ie((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,Tr(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Fe(e)!==null,this._trackingState=this._trackingSupported?Fe(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=yt()?{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,B&&B._running&&B!==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."),B=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))){re()&&vt(),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(re()||!this._autoChrome||!Pe()||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 Fr(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={}){this._warnDoubleAttach(e,"addImage",i._dxrClaim);let r=this._register(e,"image",i);return r.method="addImage",r.ready=Nr(t).then(s=>{r.img=s,r.repaint()}),this._handle(e,r)}addVideo(e,t,i={}){this._warnDoubleAttach(e,"addVideo",i._dxrClaim);let r=this._register(e,"video",i);return r.method="addVideo",r.video=t,this._handle(e,r)}addScene(e,t,i={}){this._warnDoubleAttach(e,"addScene",i._dxrClaim),i.viewRig&&i.virtualDisplayHeight!==void 0&&Ir();let r=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return r.method="addScene",r.onFrame=t,r.ownsBuffer=!1,i.bufferClamped===!0&&(r.warnedBufMismatch=!0),this._handle(e,r)}_liveRegistration(e,t){let i=this._claims.get(e);if(i&&i.token!==t)return i.method;let r=this._windows.get(e);return r?r.method||"add*":null}_warnDoubleAttach(e,t,i){let r=this._liveRegistration(e,i);!r||this._doubleWarned.has(e)||(this._doubleWarned.add(e),console.warn(`[inline3d] ${t}() on a canvas that is already registered on this inline-3D session (by ${r}(), not yet removed). This call is rebuilding the canvas's layer (a fresh 0.4-1.2 s identity gap) or putting a second renderer on its context. Change what is IN the canvas instead (setSource, your onFrame, a redrawn source canvas), or call handle.remove() on the first registration first. (Warned once per canvas.)`,e))}_attachGuard(e,t,i={}){let r=this._claims.get(e);if(i&&i._dxrClaim&&r&&r.token===i._dxrClaim)return{opts:i,own:()=>{}};this._warnDoubleAttach(e,t,null);let s={};return{opts:{...i,_dxrClaim:s},own:o=>this._claim(e,t,o,s)}}_claim(e,t,i,r){if(!this._running||!i||typeof i!="object")return;let s={token:r,method:t};this._claims.set(e,s);let o=i.remove,a=(...l)=>(this._claims.get(e)===s&&this._claims.delete(e),typeof o=="function"?o.apply(i,l):void 0);Object.defineProperty(i,"remove",{configurable:!0,enumerable:!0,get:()=>a,set:l=>{o=l}})}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:r=>{r&&(re()&&vt(),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 wi(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 wovenState(){return bt()?t.layer?We(t.layer):"pending":null},get withheldReason(){return!bt()||!t.layer?null:We(t.layer)==="withheld"?xt(t.layer):null},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?wt(e):null):(e.viewRig||(e.stereoSynthRig=!0),Sr(e.viewRig||wt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&Lr(),!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||wt(i);i.stereoSaved={ipdFactor:r.ipdFactor,parallaxFactor:r.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!gt())return Or(),!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(!_t())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 }.`));if(Cr.has(t)&&!e.layerFramed&&this._layerReadPending(e))return this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,r));let o;try{o=Promise.resolve(e.layer[t](...r))}catch(l){return Promise.reject(l)}if(!kr.has(t)||!this._layerReadPending(e))return o;let a=e.layer;return o.then(l=>e.layer!==a?l:Rr(l)?this._layerReadPending(e)?this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,r)):l:(e.lfAnswered=!0,l))}_layerFramedCap(e){return St*Math.max(e.fwHoldMs,Ct)}_layerReadPending(e){return!e.layer||e.lfAnswered||e.lfCapped?!1:N()-e.lfAt>=this._layerFramedCap(e)?(e.lfCapped=!0,!1):!0}_whenLayerFramed(e){return new Promise(t=>{let i=e.layer,r={resolve:t,timer:null},s=Math.max(0,this._layerFramedCap(e)-(N()-e.lfAt));r.timer=setTimeout(()=>{let o=e.framedWaiters.indexOf(r);o>=0&&e.framedWaiters.splice(o,1),e.layer===i&&(e.lfCapped=!0),t()},s),r.timer&&typeof r.timer.unref=="function"&&r.timer.unref(),e.framedWaiters.push(r)})}_tickLayerFramed(e){let t=e.wsLive?We(e.layer):null;(t?t==="woven":e.lfStereo)?this._noteLayerFramed(e,!0):e.framedWaiters.length&&!this._layerReadPending(e)&&this._noteLayerFramed(e,!1)}_noteLayerFramed(e,t=!0){t&&(e.layerFramed=!0);let i=e.framedWaiters.splice(0);for(let r of i)clearTimeout(r.timer),r.resolve()}_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||!gt())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=N(),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=N(),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=N(),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())},Mr))}_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"||_t()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=Ar(e),i=kt(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=kt(e),i=Dr(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(!Li.includes(e))throw new TypeError(`[inline3d] on() knows ${Li.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=Ni.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!yt())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,onResize:t==="scene"&&typeof i.onResize=="function"?i.onResize:null,resizeBox:null,inResize:!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:jr(i.firstWovenHoldMs),fwRegAt:N(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null,wsLive:!1,rc:null,layerFramed:!1,lfAnswered:!1,lfStereo:!1,lfAt:0,lfCapped:!1,framedWaiters:[]},s=Wr(i.rectCover);return s&&(r.rc={cfg:s,box:null,el:null,up:!1,snapped:!1,snapWanted:!1,waiting:null,w:0,h:0}),r.fwPromise=new Promise(o=>{r.fwResolve=o}),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"),this._dropCover(t))}_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=gt()?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=N(),e.fwStereo=!1),e.wsLive=bt(),e.layerFramed=!1,e.lfAnswered=!1,e.lfStereo=!1,e.lfCapped=!1,e.lfAt=N(),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&_t()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),yt()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),xr(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._noteLayerFramed(e,!1),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(re()||!e.layer||!Pe()||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(re())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Pe()))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&&vt()}_startOverlayScan(e){if(re()||!Pe()||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=Mi(r,s,Si(),{cols:t?2:1});return l.clamped&&(o*=l.scale,r=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(Ei("[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=Ci(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(ki("[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){if(typeof ResizeObserver=="function"&&!e.sizeObserver){if(e.kind==="scene"){if(!e.onResize)return;e.resizeBox=ji(e.canvas),e.sizeObserver=new ResizeObserver(()=>this._onSceneResize(e)),e.sizeObserver.observe(e.canvas);return}!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas))}}_onSceneResize(e){if(!e.layer||!e.onResize||e.inResize)return;let t=ji(e.canvas),i=e.resizeBox;if(!(i&&i.width===t.width&&i.height===t.height&&i.dpr===t.dpr)){e.resizeBox=t,e.inResize=!0;try{e.onResize(t)}catch(r){e.resizeThrewWarned||(e.resizeThrewWarned=!0,console.warn("[inline3d] a scene window's onResize threw; further throws from it are silent.",r))}finally{e.inResize=!1}}}_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:p,h:y}=this._eyeSize(e,e.sbs);(p!==e.eyeW||y!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let f=e.bufScale||1,m=e.cornerRadius*f,h=e.feather*f;if(o.clearRect(0,0,s.width,s.height),!e.sbs){je(o,r,0,0,a/2,l,0,0,s.width,s.height,m,h);return}let d=s.width/2,u=Math.min(this._stereoFactor,this._bakedStereo);if(u<1){je(o,r,0,0,a/2,l,0,0,d,s.height,m,h),zr(o,r,a/2,l,d,s.height,u,m,h);return}m>0||h>0?(je(o,r,0,0,a/2,l,0,0,d,s.height,m,h),je(o,r,a/2,0,a/2,l,d,0,d,s.height,m,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(Et,()=>{this._setTrackingState(Fe(e)||"unknown")})}_setTrackingState(e){let t=zi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:Et,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(Fe(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.rc&&this._rectCoverCheck(s),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.lfStereo=!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.lfStereo=!0,s.rw&&(s.rw.stereo=!0));s.rc&&s.rc.snapWanted&&this._rectCoverSnap(s),(!s.layerFramed||s.framedWaiters.length)&&this._tickLayerFramed(s),this._tickFirstWoven(s)}}_tickFirstWoven(e){let t=e.wsLive&&e.layer?We(e.layer):null;if(t){this._tickWovenState(e,t);return}if(e.rw){this._noteRewovenBox(e);let i=e.rw,r=N();i.stereo&&r-i.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):i.at>i.calledAt&&r-i.calledAt>=St*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||N()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_tickWovenState(e,t){let i=N(),r=St*Math.max(e.fwHoldMs,Ct);if(e.rw){this._noteRewovenBox(e);let s=e.rw;t!=="woven"?s.gap=!0:s.stereo&&(s.gap||s.boxFrame!==null&&this._frameCount-s.boxFrame>=Ai||s.boxFrame===null&&this._frameCount-s.callFrame>=Ai)&&this._settleRewoven(e,!0,"woven",!0),e.rw&&i-s.calledAt>=r&&(t==="woven"?this._settleRewoven(e,!0,"hold-capped",!0):this._settleRewoven(e,!1,xt(e.layer)||t,!0))}e.fwResult||e.fwLayerAt===null||(e.fwStereo&&t==="woven"?this._settleFirstWoven(e,!0,"woven",!0):i-e.fwLayerAt>=r&&(t==="woven"?this._settleFirstWoven(e,!0,"hold-capped",!0):this._settleFirstWoven(e,!1,xt(e.layer)||t,!0)))}_settleFirstWoven(e,t,i,r=!1){!t&&!r&&(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:r,reason:i,ms:Math.round(N()-e.fwRegAt)}),e.fwResolve(e.fwResult),e.fwResolve=null)}_rewoven(e){if(!e.fwResult)return e.fwPromise;if(!e.fwResult.woven&&!e.fwResult.confirmed)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=N();return e.rw={promise:i,resolve:t,calledAt:r,at:r,stereo:!1,box:Mt(e.canvas),gap:!1,boxFrame:null,callFrame:this._frameCount},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=Mt(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=N(),e.rw.stereo=!1,e.rw.gap=!1,e.rw.boxFrame=this._frameCount)}_settleRewoven(e,t,i,r=!1){let s=e.rw;s&&(e.rw=null,s.resolve(Object.freeze({woven:t,confirmed:r,reason:i,ms:Math.round(N()-s.calledAt)})))}_rectCoverCheck(e){let t=e.rc,i=Mt(e.canvas);if(i===t.box)return;let r=t.box===null,s=t.w,o=t.h;if(t.box=i,t.w=e.canvas.clientWidth||0,t.h=e.canvas.clientHeight||0,r)return;t.up&&this._placeCover(e);let a=e.fwResult;if(!a||e.rwGone||!(a.woven||a.confirmed))return;t.up||(t.snapped||(t.aspect=o>0?s/o:0),this._raiseCover(e)),t.cfg.snapshot&&!t.snapped&&t.w>0&&t.h>0&&(t.snapWanted=!0);let l;e.rw?(this._noteRewovenBox(e),l=e.rw.promise):(l=this._rewoven(e),e.rw&&(e.rw.boxFrame=this._frameCount)),t.waiting!==l&&(t.waiting=l,l.then(()=>{t.waiting===l&&(t.waiting=null,this._lowerCover(e))}))}_raiseCover(e){let t=e.rc;if(!t.el){if(typeof document>"u"||!document||typeof document.createElement!="function"||!e.canvas.parentElement)return;let i=document.createElement("canvas");i.setAttribute?.("aria-hidden","true"),i.dataset&&(i.dataset.inline3dCover="");let r=i.style;r.position="absolute",r.pointerEvents="none",r.margin="0",r.border="0",r.padding="0",r.background=t.cfg.color,r.display="none";try{let s=typeof getComputedStyle=="function"?getComputedStyle(e.canvas).zIndex:"auto";s&&s!=="auto"&&(r.zIndex=s)}catch{}t.el=i}this._placeCover(e),t.el.style.display="block",t.up=!0,this._fullTileWarned.add(t.el),this._applyExclusion(e,t.el)}_placeCover(e){let i=e.rc.el,r=e.canvas;if(!i)return;let s=r.parentElement;s&&(i.parentElement!==s||i.previousSibling!==r)&&s.insertBefore(i,r.nextSibling);let o=i.style;if(r.offsetParent)o.position="absolute",o.left=`${r.offsetLeft}px`,o.top=`${r.offsetTop}px`,o.width=`${r.offsetWidth}px`,o.height=`${r.offsetHeight}px`;else{let a=r.getBoundingClientRect();o.position="fixed",o.left=`${a.left??a.x??0}px`,o.top=`${a.top??a.y??0}px`,o.width=`${a.width}px`,o.height=`${a.height}px`}}_rectCoverSnap(e){let t=e.rc;t.snapWanted=!1;let i=t.el,r=e.canvas;if(!i||!t.up||!(r.width>1)||!(r.height>0))return;let s=Math.max(1,Math.round(t.w)),o=Math.max(1,Math.round(t.h)),a=s/o,l=t.aspect>0?t.aspect:r.width/2/r.height,c=1,f=1;a>l?f=l/a:c=a/l;let m=r.width/2*c,h=r.height*f,d=(r.width/2-m)/2,u=(r.height-h)/2;try{i.width=s,i.height=o;let p=i.getContext("2d");if(!p)return;p.drawImage(r,d,u,m,h,0,0,s,o),t.snapped=!0}catch{}}_lowerCover(e){let t=e.rc;t&&(t.up=!1,t.snapped=!1,t.snapWanted=!1,t.el&&(t.el.style.display="none",this._dropExclusion(e,t.el)))}_dropCover(e){let t=e.rc;t&&(t.waiting=null,this._lowerCover(e),t.el&&t.el.parentElement&&t.el.parentElement.removeChild(t.el),t.el=null)}_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,B===this&&(B=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._dropCover(e),this._noteLayerFramed(e,!1)}this._windows.clear(),this._claims.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function jr(n){return typeof n=="number"&&Number.isFinite(n)&&n>=0?n:Ct}function Nr(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 je(n,e,t,i,r,s,o,a,l,c,f,m){f>0&&n.roundRect?(n.save(),n.beginPath(),n.roundRect(o,a,l,c,f),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),m>0&&Ui(n,o,a,l,c,m)}function zr(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&&Ui(n,r,0,r,s,l)}function Ui(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,f,m,h,d]of a){let u=n.createLinearGradient(h[0],h[1],d[0],d[1]);u.addColorStop(0,"rgba(0,0,0,1)"),u.addColorStop(1,"rgba(0,0,0,0)"),n.fillStyle=u,n.fillRect(l,c,f,m)}n.restore()}function oe(n,e){return n>0&&e>0&&n/e>2.5}function V(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 ae(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 Tt(n,e,t){let i=new n.constructor(n.length);for(let r of ae(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 Bi(n,e){return!(n>0)||!(e>0)||e>=180?null:n/2/Math.tan(e/2*Math.PI/180)}function ze({eyeWidthPx:n,hfovDeg:e,baselineMm:t,subjectZmm:i}){let r=Bi(n,e);return r===null||!(t>0)||!(i>0)?0:r*t/(2*i)}function He(n,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,n||0))}function $e(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?ze({eyeWidthPx:e,hfovDeg:n.hello.hfovDeg,baselineMm:n.hello.baselineMm,subjectZmm:n.subjectZmm}):0;return He(t+n.depth*.05*e,e)},step(e){return n.current=$e(n.current,n.target(e)),n.current}};return n}var Ve=1,Lt="inline3d-call/1",qi=Object.freeze(["sbs","mono"]),le=4,Xi=4,Dt=5,Hr=150,$r=5e3,Vr=/^[A-Za-z0-9_-]{16,64}$/,Ur=16;function At(n){let e=new Uint8Array(Ur);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ji(e)}function Gi(n){let e=new Uint8Array(8);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Ji(e)}function Ji(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 ce(n){return typeof n=="string"&&Vr.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 ce(r)?r:null}return null}function Ue(n,e){if(!ce(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(n||"").split("#")[0]}#room=${e}`}function Ot(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:Ve,format:qi.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 It({format:n,width:e,height:t,baselineMm:i,hfovDeg:r,rectified:s}={}){let o={type:"hello",v:Ve,format:qi.includes(n)?n:"mono",width:e||0,height:t||0,rectified:!!s,sdk:Lt};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(r)&&(o.hfovDeg=r),o}function Pt(n){if(!n||n.type!=="hint")return null;let e=n.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=Hr&&e<=$r?{type:"hint",subjectZmm:e}:null}function Yi(n){return!n||n.type!=="state"?null:{type:"state",muted:n.muted===!0,cameraOff:n.cameraOff===!0,speaking:n.speaking===!0}}function Ft(n){let e=1e3/n,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function Wt({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 jt(n){return n==="woven-sbs"?"3D":n==="lifted"?"2D\u21923D":"2D"}function Nt({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 Be(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 q(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 qr(n,e=Me){let t=e.indexOf(String(n||"").toUpperCase());return t<0?e.length:t}function qe(n,e=Me){let t=i=>qr(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.40.2 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
2
+ var cn=Object.defineProperty;var Ae=(r,e)=>()=>(r&&(e=r(r=0)),e);var hn=(r,e)=>{for(var t in e)cn(r,t,{get:e[t],enumerable:!0})};function Xe(r,e,t,i,n,s,o,a,l,c,p){if(s<0||s+a>t||o<0)return-1;let m=0,h=0,d=0,u=a*l;for(let v=0;v<l;v++){let b=(n+v)*e+i,k=(o+v)*e+t+s;for(let x=0;x<a;x++){let P=r[k+x];m+=P,h+=P*P,d+=r[b+x]*P}}let f=m/u,y=h/u-f*f;return y<1?-1:(d/u-c*f)/(p*Math.sqrt(y))}function ss(r,e,t,i,n,s){let o=0,a=0;for(let p=0;p<s;p++){let m=(i+p)*e+t;for(let h=0;h<n;h++){let d=r[m+h];o+=d,a+=d*d}}let l=n*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function ke(r,e,t,i,n,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:p}={}){let m=e/2,{mean:h,std:d}=ss(r,e,i,n,s,o);if(d<6)return null;let u=-2,f=0,y=0,v=new Map,b=(T,g,w,_,M)=>{for(let O=_;O<=M;O++){let S=n+O;if(!(S<0||S+o>t))for(let F=T;F<=g;F+=w){let H=Xe(r,e,m,i,n,i-F,S,s,o,h,d);H>(v.get(F)??-2)&&v.set(F,H),H>u&&(u=H,f=F,y=O)}}},k=l-a>8;if(b(a,l,k?2:1,-c,c),k&&u>-1){let T=f,g=y;b(Math.max(a,T-2),Math.min(l,T+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(u<-1)return null;let x=-2,P=T=>{let g=-2;for(let w=-c;w<=c;w++){let _=n+w;if(!(_<0||_+o>t))for(let M=T-1;M<=T+1;M++)g=Math.max(g,Xe(r,e,m,i,n,i-M,_,s,o,h,d))}return g};for(let[T,g]of v){if(Math.abs(T-f)<3||g<=x)continue;let _=g>=(v.get(T-2)??-2)&&g>=(v.get(T+2)??-2)&&g>0?P(T):g;_>x&&(x=_)}if(l-a>12&&x>-2&&u-x<(p??.08))return null;let C=Xe(r,e,m,i,n,i-(f-1),n+y,s,o,h,d),D=Xe(r,e,m,i,n,i-(f+1),n+y,s,o,h,d),I=0,A=C-2*u+D;return C>-1&&D>-1&&A<0&&(I=Math.max(-.5,Math.min(.5,.5*(C-D)/A))),{d:f+I,dy:y,c:u}}function os(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.step||Math.round(s*1.5),a=i.dMax??Math.round(n*.3),l=i.dMin??-Math.round(n*.05),c=Math.round(n*(i.roiX0??.15)),p=Math.round(n*(i.roiX1??.85))-s,m=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let u=m;u<=h;u+=o)for(let f=c;f<=p;f+=o){let y=ke(r,e,t,f,u,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});y&&y.c>=(i.minNcc??.8)&&d.push({x:f,y:u,...y})}return d}function as(r,{tol:e=2,minFrac:t=.12,minBlocks:i=3}={}){if(!r.length)return null;let n=Math.max(i,Math.ceil(r.length*t)),s=r.map(o=>o.d).sort((o,a)=>a-o);for(let o of s){let a=r.filter(l=>Math.abs(l.d-o)<=e);if(a.length>=n){let l=a.map(c=>c.d).sort((c,p)=>c-p);return{d:l[l.length>>1],members:a}}}return null}function ls(r,e){let t=Math.min(...r.map(l=>l.y)),n=r.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...n),o=Math.max(...n)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function $t(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.dMax??Math.round(n*.3),a=i.dMin??-Math.round(n*.05),l=i.focus||null,c="focus",p=0,m=null;if(!l){let k=os(r,e,t,{...i,block:s,dMax:o,dMin:a});p=k.length;let x=as(k,i);if(!x)return null;l=ls(x.members,s),m=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),u=Math.round(Math.max(0,Math.min(n-h,l.x-h/2))),f=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),y=m===null?a:Math.max(a,Math.floor(m)-4),v=m===null?o:Math.min(o,Math.ceil(m)+4),b=ke(r,e,t,u,f,h,d,{dMin:y,dMax:v,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}:m!==null?{d:m,x:l.x,y:l.y,c:0,method:c,blocks:p}:null}function Ge(r,e){let t=new Uint8Array(e);for(let i=0,n=0;i<e;i++,n+=4)t[i]=r[n]*77+r[n+1]*150+r[n+2]*29>>8;return t}function Je({n:r=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>r&&e.shift();let n=[...e].sort((s,o)=>s-o);return t.value=n[n.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function rr(r,e,t,i,n,s){let o=new Float32Array(n*s);for(let a=0;a<s;a++)for(let l=0;l<n;l++)o[a*n+l]=r[(i+a)*e+t+l];return o}function cs(r,e,t,i,n,s,o,a,l,c){let p=e/2,m=n*s,h=0,d=0;for(let b=0;b<m;b++)h+=i[b],d+=i[b]*i[b];h/=m;let u=Math.sqrt(Math.max(1e-6,d/m-h*h)),f=-2,y=o,v=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let k=Math.max(0,o-l);k<=Math.min(p-n,o+l);k++){let x=0,P=0,C=0;for(let T=0;T<s;T++){let g=(b+T)*e+k;for(let w=0;w<n;w++){let _=r[g+w];x+=_,P+=_*_,C+=_*i[T*n+w]}}let D=x/m,I=P/m-D*D;if(I<1)continue;let A=(C/m-D*h)/(Math.sqrt(I)*u);A>f&&(f=A,y=k,v=b)}return{x:y,y:v,c:f}}function Te({fullEveryMs:r=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:n=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,p,m,h,d={}){let u=p/2,f=d.block||Math.max(8,Math.round(u/20)),y=Math.round(f*3),v=Math.round(f*1.5),b=null;if(o&&o.w===y&&o.h===v){let D=cs(c,p,m,o.tpl,y,v,o.x,o.y,t,i);if(D.c>=n){let I=ke(c,p,m,D.x,D.y,y,v,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});I&&I.c>=.8&&(b={m:I,f:D})}}let k=({m:D,f:I})=>(o={...o,x:I.x,y:I.y,d:D.d,tpl:rr(c,p,I.x,I.y,y,v)},{d:D.d,x:I.x+y/2,y:I.y+v/2,c:D.c,method:"track",blocks:0});if(b&&h-o.at<r)return k(b);let x=$t(c,p,m,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let D=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!D?{d:x.d}:null,!D)return o.at=h,k(b)}else a=null;if(!x)return o=null,null;let P=Math.round(Math.max(0,Math.min(u-y,x.x-y/2))),C=Math.round(Math.max(0,Math.min(m-v,x.y-v/2)));return o={x:P,y:C,d:x.d,tpl:rr(c,p,P,C,y,v),w:y,h:v,at:h},x},reset(){o=null,a=null}}}function nr(r,e,t,i,n,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(n/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let d=0;d<l;d++)for(let u=0;u<a;u++){let f=0;for(let y=0;y<o;y++){let v=e+(d*o+y)*t+u*o;for(let b=0;b<o;b++)f+=r[v+b]}c[d*a+u]=f/h|0}return{img:c,w:a,h:l}}let p=o>>2,m=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+p)*t,u=e+(h*o+m)*t;for(let f=0;f<a;f++){let y=f*o+p,v=f*o+m;c[h*a+f]=r[d+y]+r[d+v]+r[u+y]+r[u+v]>>2}}return{img:c,w:a,h:l}}var Vt=Ae(()=>{"use strict"});function hs(r,e="@displayxr/inline3d"){if(r==null||r===!1)return null;if(r==="depth"||r===!0)return{};if(typeof r!="object")throw new Error(`${e}: cursor ${JSON.stringify(r)} \u2014 expected 'depth' or { height, margin, anchor, pointerScope }.`);let t=Object.keys(r).filter(i=>!or.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${or.join(", ")}.`);if(r.anchor!==void 0&&!sr.includes(r.anchor))throw new Error(`${e}: cursor.anchor "${r.anchor}" \u2014 expected ${sr.join(", ")}.`);if(r.pointerScope!==void 0&&r.pointerScope!=="canvas"&&r.pointerScope!=="window")throw new Error(`${e}: cursor.pointerScope "${r.pointerScope}" \u2014 expected 'canvas' or 'window'.`);for(let i of["height","margin"])if(r[i]!==void 0&&!(typeof r[i]=="number"&&r[i]>0&&Number.isFinite(r[i])))throw new Error(`${e}: cursor.${i} must be a positive number.`);return{...r}}function Ye(r,e="@displayxr/inline3d"){let t=hs(r,e);if(!t)return null;let i=Object.keys(t).filter(n=>!ar.includes(n));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${ar.join(", ")}.`);return t}var sr,or,ar,Ut=Ae(()=>{"use strict";sr=Object.freeze(["hybrid","screen","world"]),or=Object.freeze(["height","margin","anchor","pointerScope"]);ar=Object.freeze(["height","pointerScope"])});function Sr(r,e,t,i){if(!r.primed||i<r.last||i-r.last>e.stale)return r.primed=!0,r.disparity=t,r.last=i,t;if(i===r.last)return r.disparity;let n=i-r.last,s=t<r.disparity?e.riseTau:e.sinkTau,o=s>0?1-Math.exp(-n/s):1;return r.disparity+=o*(t-r.disparity),r.last=i,r.disparity}function _s(r){let e=globalThis.document;if(!(!e||!e.documentElement)){if(r&&!e.getElementById("inline3d-cursor-style")){let t=e.createElement("style");t.id="inline3d-cursor-style",t.textContent="html.inline3d-cursor-hidden, html.inline3d-cursor-hidden * { cursor: none !important; }",(e.head||e.documentElement).appendChild(t)}Jt=Math.max(0,Jt+(r?1:-1)),e.documentElement.classList.toggle("inline3d-cursor-hidden",Jt>0)}}function Mr(r,e,t,i){let n=.75*t,s=[[r,e]];for(let o=0;o<8;o++){let a=o*Math.PI/4;s.push([r+n*Math.cos(a)/i,e+n*Math.sin(a)])}return s}var xr,et,Jt,Co,Ro,ko,Er=Ae(()=>{"use strict";xr=Object.freeze({margin:.005,minDisparity:-.6,maxDisparity:.6,riseTau:.03,sinkTau:.25,stale:.5});et=class{constructor(e,{scope:t="canvas"}={}){if(t!=="canvas"&&t!=="window")throw new Error(`@displayxr/inline3d: cursor pointerScope "${t}" \u2014 expected 'canvas' or 'window'.`);this.canvas=e,this.scope=t,this.uv=null,this._hidden=!1,this._prev="",this._onMove=i=>{let n=e.getBoundingClientRect();if(!(n.width>0&&n.height>0))return void(this.uv=null);let s=(i.clientX-n.left)/n.width,o=(i.clientY-n.top)/n.height;this.uv=s>=0&&s<=1&&o>=0&&o<=1?[s,o]:null},this._onLeave=()=>{this.uv=null},this._target=t==="window"?globalThis:e,this._target.addEventListener("pointermove",this._onMove),t==="window"?(this._onOut=i=>{i.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}set(e,t){this.uv=e==null?null:[e,t]}aspect(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.width/e.height:1}hideCss(e){e!==this._hidden&&(this.scope==="window"?_s(e):e?(this._prev=this.canvas.style.cursor||"",this.canvas.style.cursor="none"):this.canvas.style.cursor=this._prev,this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}},Jt=0;Co=Object.freeze([[-.5,0,-.15,0],[.15,0,.5,0],[0,-.5,0,-.15],[0,.15,0,.5],[-.15,-.15,.15,-.15],[.15,-.15,.15,.15],[.15,.15,-.15,.15],[-.15,.15,-.15,-.15]]),Ro=Object.freeze([1,.84,.1,1]),ko=Object.freeze([.04,.04,.06,.85])});var Kt={};hn(Kt,{PAIR_CURSOR_ARROW:()=>Lr,PAIR_CURSOR_CLAMP:()=>Or,PAIR_CURSOR_CSS_PX:()=>Cr,PAIR_CURSOR_CSS_PX_M:()=>Ar,PAIR_CURSOR_HEIGHT:()=>Rr,PAIR_CURSOR_MARGIN_M:()=>Dr,PAIR_CURSOR_SHOW_M:()=>kr,PAIR_CURSOR_SHOW_MIN_PX:()=>Tr,PairCursor:()=>Yt,drawPairArrow:()=>Wr,pairCursorScale:()=>Fr,pairCursorTarget:()=>Ir,pairFootprintDisparity:()=>Pr});function Pr(r,e,t,i,n,s){if(!r||!r.img||!e||!e.rL||!e.rR||!(e.outW>0))return null;let{img:o,w:a,h:l,scale:c}=r,p=a/2,m=Math.max(8,Math.round(p/20)),h=Math.round(p*.3),d=-Math.round(p*.05),{rL:u,rR:f}=e,y=e.outW/u.sw,v=null;for(let[b,k]of Mr(t+.3*n/s,i+.5*n,n,s)){if(!(b>=0&&b<=1&&k>=0&&k<=1))continue;let x=e.mirror?1-b:b,P=Math.round((u.sx+x*u.sw)*c-m/2),C=Math.round((u.sy+k*u.sh)*c-m/2);if(P<0||P+m>p||C<0||C+m>l)continue;let D=ke(o,a,l,P,C,m,m,{dMin:d,dMax:h,dyMax:2});if(!D||D.c<.8)continue;let I=(D.d/c-(u.sx-f.sx))*y;(v===null||I>v)&&(v=I)}return v}function Ir(r,e,t){return r===null||!Number.isFinite(r)||!(r>0)?0:Math.min(Or*e,r+t)}function Fr(r,e,t){let i=t>0&&Number.isFinite(t)?t:Ar;return e>0?r/e/i:r/(1e3*i)}function Wr(r,e,t,i,n,s,o){let a=n*t;for(let l of[0,1]){let c=l*e+i*e+(l===0?s/2:-s/2);r.save(),r.beginPath(),r.rect(l*e,0,e,t),r.clip(),r.beginPath(),Lr.forEach(([p,m],h)=>(h?r.lineTo:r.moveTo).call(r,c+p*o,a+m*o)),r.closePath(),r.fillStyle="#fff",r.fill(),r.lineWidth=Math.max(1,o/19),r.lineJoin="miter",r.strokeStyle="#000",r.stroke(),r.restore()}}var Cr,Rr,kr,Tr,Lr,Dr,Ar,Or,Yt,Zt=Ae(()=>{"use strict";Er();Vt();Cr=19,Rr=.06,kr=3e-4,Tr=.5,Lr=Object.freeze([[0,0],[0,16/19],[4.2/19,12.4/19],[6.9/19,18.6/19],[9.5/19,17.5/19],[6.8/19,11.5/19],[11.7/19,11.5/19]]),Dr=.002,Ar=.0254/96,Or=.08;Yt=class{constructor(e,{height:t,pointerScope:i="window"}={}){this.pointer=new et(e,{scope:i}),this.height=t>0?t:null,this.filter={},this._luma=null,this._uv=null,this._content=null,this._metricsFor=null,this.metersPerCssPx=null,this.last=null}get hovering(){return!!this.pointer.uv}draw(e,t,i,n){let s=this.pointer.uv;if(!s)return this.idle();let[o,a]=s,l=this.height??this._osArrowFraction();(t!==this._luma||!this._uv||this._uv[0]!==o||this._uv[1]!==a)&&(this._content=Pr(t,i,o,a,l,i.outW/i.outH),this._luma=t,this._uv=s),this._askMetrics(i.handle);let c=this.pointer.canvas.getBoundingClientRect?.(),p=Fr(i.outW,c&&c.width,this.metersPerCssPx),m=Ir(this._content,i.outW,Dr*p),h=-Sr(this.filter,xr,-m,n),d=h>=Math.max(Tr,kr*p);return d&&Wr(e,i.outW,i.outH,o,a,h,l*i.outH),this.pointer.hideCss(d),this.last={contentPx:this._content,targetPx:m,disparityPx:d?h:0,drawn:d},this.last}_askMetrics(e){!e||e===this._metricsFor||typeof e.displayMetrics!="function"||(this._metricsFor=e,Promise.resolve(e.displayMetrics()).then(t=>{this._metricsFor===e&&t&&t.metersPerCssPx>0&&(this.metersPerCssPx=t.metersPerCssPx)}).catch(()=>{}))}_osArrowFraction(){let e=this.pointer.canvas.getBoundingClientRect?.();return e&&e.height>0?Math.min(.5,Cr/e.height):Rr}idle(){return this.pointer.hideCss(!1),this.filter={},this._uv=null,this.last=null,null}dispose(){this.pointer.dispose()}}});var _e=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),dn=["high","normal","low","paused"],un=.02,fn=1e3/20,pn=3e3,mn=1e3/28;function ve(r){return typeof r=="function"?r:r===!1||r==="off"?"off":"auto"}function at(r=import.meta.url){return ge?typeof ge=="function"?ge():ge:new URL("../lift/index.js",r).href}var ge=null;function _i(r){ge=r||null}function gn(){return import(at())}async function lt(r,{importer:e=gn,nav:t=globalThis.navigator,log:i=null,capsOpts:n={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=ve(r);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,m=null;if(p){try{m=await p(n)}catch{m=null}let h=!!(m&&m.webFallback&&m.webFallback.webgpu);if(m&&!m.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(m&&m.native),provider:m&&m.provider||null}),{lift:c,capabilities:p,caps:m,source:"module",reason:null}}function ye(r){let e=Number.isFinite(+r)&&r!==null?Math.max(-1,Math.min(1,+r)):0;return Math.abs(e)<un?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Oe({id:r,speakerId:e,visible:t=!0}){return t?r!=null&&r===e?_e.speaker:_e.other:_e.hidden}function ct(r,e){if(!r||!dn.includes(e)||typeof r.setPriority!="function")return!1;try{return r.setPriority(e)!==!1}catch{return!1}}function ht({degradedMs:r=fn,recoveredMs:e=mn,holdMs:t=pn,alpha:i=.1}={}){let n=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(n=n===null?a:n+i*(a-n),o){if(n<e)return o=!1,s=0,"recovered"}else if(s=n>r?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){n=null,s=0,o=!1},get frameMs(){return n},get degraded(){return o}}}function dt({lift:r,max:e=4,log:t=null,options:i=null}={}){let n=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 u=Oe({id:h,speakerId:o,visible:d.visible});if(u===d.priority)return;d.priority=u;let f=ct(d.handle,u);c("lift-priority",{peer:h,priority:u,applied:f})},m={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:u,visible:f=!0,onError:y}={}){let v=s.get(h);if(v)return v.pending||Promise.resolve(v.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,k=Oe({id:h,speakerId:o,visible:f}),x={gen:b,handle:null,visible:f,priority:k,pending:null};s.set(h,x);let P={quality:"auto",...n,mode:"live",wall:u,ui:"none",convergence:ye(a),priority:k};return c("lift-acquire",{peer:h,priority:k,convergence:P.convergence}),x.pending=Promise.resolve().then(()=>r(d,P)).then(C=>{if(s.get(h)!==x||x.gen!==b){try{C&&C.remove&&C.remove()}catch{}return null}return x.pending=null,x.handle=C||null,x.priority=null,p(h,x),C&&typeof C.setConvergence=="function"&&C.setConvergence(ye(a)),x.handle},C=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(C&&C.message||C).slice(0,200)}),y&&y(C),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()])m.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,u]of s)p(d,u)},setVisible(h,d){let u=s.get(h);!u||u.visible===!!d||(u.visible=!!d,p(h,u))},setDepth(h){a=h;let d=ye(h);for(let u of s.values())u.handle&&typeof u.handle.setConvergence=="function"&&u.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 m}var yn=null;function yi(r){yn=typeof r=="function"?r:null}var vn=new WeakMap;function vi(r,e){r&&(typeof r=="object"||typeof r=="function")&&vn.set(r,e)}var wn=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063});function wi(r,e,t=1){let i=wn,n=!!r&&r.displayWidthMeters>0&&r.displayHeightMeters>0&&r.displayPixelWidth>0&&r.displayPixelHeight>0,s=n?[r.displayWidthMeters,r.displayHeightMeters]:[...i.displaySizeM],o=n?[r.displayPixelWidth,r.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=n?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),p=r?.nominalViewerPosition?.z,m=Number.isFinite(p)&&p>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:m?p:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:n?"display":"default",viewer:m?"display":"default",eyeSeparation:"default"}}}var bi=new WeakMap,J;function xi(r){let e=null;for(let[t,i]of r)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function bn(r){if(!r||typeof r.getParameter!="function")return null;let e=bi.get(r);if(e)return e;let t,i,n;try{t=r.getParameter(r.MAX_TEXTURE_SIZE??3379),i=r.getParameter(r.MAX_RENDERBUFFER_SIZE??34024),n=r.getParameter(r.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=n&&n.length>=2?n[0]:0,o=n&&n.length>=2?n[1]:0,a=xi([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=xi([["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 bi.set(r,c),c}function Si(){if(J!==void 0)return J;J=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return J;let r=document.createElement("canvas"),e=r.getContext("webgl2")||r.getContext("webgl");if(!e)return J;J=bn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function Mi(r,e,t,{cols:i=2,rows:n=1}={}){let s=r*i,o=e*n,a={eyeW:r,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(r>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 m=l<=c,h=Math.max(1,Math.min(Math.floor(r*p+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*p+1e-9),Math.floor(t.maxH/n)));return{eyeW:h,eyeH:d,cols:i,scale:p,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*n,limitName:m?t.nameW:t.nameH,limitValue:m?t.valueW:t.valueH}}function ut(r){return Math.round(r*1e3)/1e3}function Ei(r,e,t){let i=typeof t=="number"?` (renderScale ${ut(t)} \u2192 ${ut(t*e.scale)})`:` (scale ${ut(e.scale)})`;return`${r} ${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 Ci(r,e){let t=r?.width||0,i=r?.height||0,n=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?n/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:n,h:s,mismatch:o!==1||a!==1}}function Ri(r,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${r} 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 re="smoothstep",pt=["linear","smoothstep","easeoutcubic"];function mt(r){if(typeof r!="string")return null;let e=r.toLowerCase().replace(/[-_\s]/g,"");return pt.includes(e)?e:null}function xn(r,e){if(e<=0)return 0;if(e>=1)return 1;if(r==="linear")return e;if(r==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var ie="idle",ki="rampDownThenFire",ft="fireThenRampUp",Pe=class{constructor(e,t){this._phase=ie,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=re,(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=mt(t)||re),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:n,current:s,steady:o=1}={}){let a=!(t>1),l=!(n>1),c=Number.isFinite(o)?o:1,p=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=p,a&&!l?(this._phase=ki,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=ft,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=ft,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!==ie){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)*xn(this._easing,this._t),this._phase===ft?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=ie)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=ie)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==ie}value(){return this._cur}firePending(){return this._phase===ki?this._fireAtEnd:this._firePending}cancel(){return this._phase=ie,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var B=null;yi(r=>{let e=B;if(!e||!e._running||!r)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===r&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof r.contains=="function"&&r.contains(i.canvas))return t(i);for(let i of e._windows.values()){let n=i.canvas.parentElement;if(i.layer&&n&&typeof n.contains=="function"&&n.contains(r))return t(i)}return null});var Sn=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Ie=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,gt=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Mn=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Ni=["renderingmodechange","hardwaredisplaystatechange"],Et="trackingstatechange",zi=["unknown","tracking","searching"],Li=[...Ni,Et];function Fe(r){try{let e=r?r.trackingState:void 0;return zi.includes(e)?e:null}catch{return null}}var _t=()=>{if(!Q())return!1;try{let r=window.XRDisplayLayer.prototype;return Mn.every(e=>typeof r[e]=="function")}catch{return!1}},yt=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},se=null;function ne(){if(se!==null)return se;if(!Q())return!1;try{let r=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof r=="boolean")return se=r}catch{}return!1}function En(r){if(se!==null)return se;if(!r||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return se=!!r.occlusionByDrawOrder}catch{return null}}var Di=!1;function vt(){Di||(Di=!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 Hi(){return Sn()&&Q()}function wt(r){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:r.virtualDisplayHeight>0?r.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function Cn(r,e){let t=Number.isFinite(r.ipdFactor)?r.ipdFactor:1,i=Number.isFinite(r.parallaxFactor)?r.parallaxFactor:1;return{...r,ipdFactor:t*e,parallaxFactor:i*e}}var Rn=16;function N(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Ct=1200,kn=new Set(["pending","woven","withheld"]),Ai=3,Tn=new Set(["getDisplayInfo","getRenderingModes","requestRenderingMode"]),Ln=new Set(["getDisplayInfo","getRenderingModes"]);function Dn(r){return r==null||Array.isArray(r)&&r.length===0}function bt(){try{let r=typeof XRDisplayLayer=="function"?XRDisplayLayer:null;return!!(r&&r.prototype&&"wovenState"in r.prototype)}catch{return!1}}function We(r){try{let e=r?r.wovenState:null;return kn.has(e)?e:null}catch{return null}}function xt(r){try{let e=r?r.withheldReason:null;return typeof e=="string"&&e?e:null}catch{return null}}var Oi=!1;function An(r){if(r==null)return re;let e=mt(r);return e||(Oi||(Oi=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(r)} } }) is not a curve this SDK knows (${pt.join(" / ")}); using '${re}'.`)),re)}var Pi=!1;function On(){Pi||(Pi=!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 Rt(r){return r&&r.detail!==void 0&&r.detail!==null?r.detail:void 0}function $i(r){let e=Rt(r);return e!==void 0?[e,r]:[r]}function Pn(r){for(let e of $i(r)){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 In(r){for(let e of $i(r)){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 Ii=!1;function Fn(){Ii||(Ii=!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 Fi=!1;function Wn(){Fi||(Fi=!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 Vi(r={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:n=!0,modeSwitch:s=null,untrackedFallback:o="none",viewerEase:a}=r;if(!Hi())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&&vi(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new kt(l,c,{lazy:t,rootMargin:i,autoChrome:n,modeSwitch:s,untrackedFallback:o})}var we=null;function Ne(r={}){return B&&B._running?Promise.resolve(B):we||(we=Vi(r).finally(()=>{we=null}),we)}var Wi=.7,jn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Nn(r){let e=[],t=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(jn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let n of i.childNodes)if(n.nodeType===Node.TEXT_NODE&&n.nodeValue.trim()){e.push(i);break}}return e}var St=4;function Mt(r){let e=typeof window<"u"&&window.devicePixelRatio||1,t="";if(typeof r.getBoundingClientRect=="function"){let i=r.getBoundingClientRect()||{},n=typeof window<"u"&&window.scrollX||0,s=typeof window<"u"&&window.scrollY||0;t=`+${Math.round((i.left??i.x??0)+n)},${Math.round((i.top??i.y??0)+s)}`}return`${r.clientWidth}x${r.clientHeight}@${e}${t}`}function ji(r){let e=typeof window<"u"&&window.devicePixelRatio||1;return{width:r.clientWidth||0,height:r.clientHeight||0,dpr:e}}function zn(r){if(r==null||r===!1||r==="off")return null;if(r==="auto"||r===!0)return{color:"#000",snapshot:!0};if(typeof r=="object"){if(r.color!==void 0&&typeof r.color!="string")throw new TypeError("[inline3d] rectCover.color must be a CSS color string.");return{color:r.color||"#000",snapshot:r.snapshot!==!1}}throw new TypeError(`[inline3d] rectCover: expected 'auto', 'off' or { color?, snapshot? }; got ${JSON.stringify(r)}.`)}var kt=class{constructor(e,t,{lazy:i,rootMargin:n,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._claims=new Map,this._doubleWarned=new WeakSet,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 Pe((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,An(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Fe(e)!==null,this._trackingState=this._trackingSupported?Fe(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=yt()?{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:n}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,B&&B._running&&B!==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."),B=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()&&vt(),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,n=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of n){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 Nn(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={}){this._warnDoubleAttach(e,"addImage",i._dxrClaim);let n=this._register(e,"image",i);return n.method="addImage",n.ready=$n(t).then(s=>{n.img=s,n.repaint()}),this._handle(e,n)}addVideo(e,t,i={}){this._warnDoubleAttach(e,"addVideo",i._dxrClaim);let n=this._register(e,"video",i);return n.method="addVideo",n.video=t,this._handle(e,n)}addScene(e,t,i={}){this._warnDoubleAttach(e,"addScene",i._dxrClaim),i.viewRig&&i.virtualDisplayHeight!==void 0&&Wn();let n=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return n.method="addScene",n.onFrame=t,n.ownsBuffer=!1,i.bufferClamped===!0&&(n.warnedBufMismatch=!0),this._handle(e,n)}_liveRegistration(e,t){let i=this._claims.get(e);if(i&&i.token!==t)return i.method;let n=this._windows.get(e);return n?n.method||"add*":null}_warnDoubleAttach(e,t,i){let n=this._liveRegistration(e,i);!n||this._doubleWarned.has(e)||(this._doubleWarned.add(e),console.warn(`[inline3d] ${t}() on a canvas that is already registered on this inline-3D session (by ${n}(), not yet removed). This call is rebuilding the canvas's layer (a fresh 0.4-1.2 s identity gap) or putting a second renderer on its context. Change what is IN the canvas instead (setSource, your onFrame, a redrawn source canvas), or call handle.remove() on the first registration first. (Warned once per canvas.)`,e))}_attachGuard(e,t,i={}){let n=this._claims.get(e);if(i&&i._dxrClaim&&n&&n.token===i._dxrClaim)return{opts:i,own:()=>{}};this._warnDoubleAttach(e,t,null);let s={};return{opts:{...i,_dxrClaim:s},own:o=>this._claim(e,t,o,s)}}_claim(e,t,i,n){if(!this._running||!i||typeof i!="object")return;let s={token:n,method:t};this._claims.set(e,s);let o=i.remove,a=(...l)=>(this._claims.get(e)===s&&this._claims.delete(e),typeof o=="function"?o.apply(i,l):void 0);Object.defineProperty(i,"remove",{configurable:!0,enumerable:!0,get:()=>a,set:l=>{o=l}})}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:n=>{n&&(ne()&&vt(),t.excluded.add(n),this._applyExclusion(t,n))},unexclude:n=>{!n||!t.excluded.delete(n)||this._dropExclusion(t,n)},get trackingState(){return i._trackingState},setViewRig:n=>(t.viewRig=n||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let n=null;try{n=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return wi(n,e.getBoundingClientRect(),globalThis.devicePixelRatio||1)},getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:n=>this._requestRenderingModeEased(n,t),setStereoEnabled:n=>this._setStereoEnabled(n,t),on:(n,s)=>this.on(n,s),off:(n,s)=>this.off(n,s),onDisplayModeChange:n=>this._onDisplayModeChange(n),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get wovenState(){return bt()?t.layer?We(t.layer):"pending":null},get withheldReason(){return!bt()||!t.layer?null:We(t.layer)==="withheld"?xt(t.layer):null},get firstWoven(){return t.fwPromise},onFirstWoven:n=>{if(typeof n!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{n(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?wt(e):null):(e.viewRig||(e.stereoSynthRig=!0),Cn(e.viewRig||wt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&On(),!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 n=i.viewRig||wt(i);i.stereoSaved={ipdFactor:n.ipdFactor,parallaxFactor:n.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!gt())return Fn(),!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,n=[]){if(!_t())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 }.`));if(Tn.has(t)&&!e.layerFramed&&this._layerReadPending(e))return this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n));let o;try{o=Promise.resolve(e.layer[t](...n))}catch(l){return Promise.reject(l)}if(!Ln.has(t)||!this._layerReadPending(e))return o;let a=e.layer;return o.then(l=>e.layer!==a?l:Dn(l)?this._layerReadPending(e)?this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n)):l:(e.lfAnswered=!0,l))}_layerFramedCap(e){return St*Math.max(e.fwHoldMs,Ct)}_layerReadPending(e){return!e.layer||e.lfAnswered||e.lfCapped?!1:N()-e.lfAt>=this._layerFramedCap(e)?(e.lfCapped=!0,!1):!0}_whenLayerFramed(e){return new Promise(t=>{let i=e.layer,n={resolve:t,timer:null},s=Math.max(0,this._layerFramedCap(e)-(N()-e.lfAt));n.timer=setTimeout(()=>{let o=e.framedWaiters.indexOf(n);o>=0&&e.framedWaiters.splice(o,1),e.layer===i&&(e.lfCapped=!0),t()},s),n.timer&&typeof n.timer.unref=="function"&&n.timer.unref(),e.framedWaiters.push(n)})}_tickLayerFramed(e){let t=e.wsLive?We(e.layer):null;(t?t==="woven":e.lfStereo)?this._noteLayerFramed(e,!0):e.framedWaiters.length&&!this._layerReadPending(e)&&this._noteLayerFramed(e,!1)}_noteLayerFramed(e,t=!0){t&&(e.layerFramed=!0);let i=e.framedWaiters.splice(0);for(let n of i)clearTimeout(n.timer),n.resolve()}_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 n=i.find(s=>s.isActive);return n&&(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.viewCount,(n.viewCount===1||n.viewCount===2)&&this._setStereoCollapsed(n.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||!gt())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 n=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=n&&Number.isFinite(n.viewCount)?n.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((n,s)=>{i.resolve=n,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=N(),this._armModeSwitchTick(),i.promise}_requestThenRampUp(e,t){let n=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=n?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=N(),this._armModeSwitchTick()}_settlePendingDown(e,t){let i=this._msFire;if(!i)return;this._msFire=null;let n=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.`);n.name=e,i.reject(n)}_advanceModeSwitch(){if(!this._modeSwitch.active()){this._msLastMs=null,this._disarmModeSwitchTick();return}let e=N(),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 n of this._windows.values())this._pushViewRig(n)}if(i.fire&&this._msFire){let n=this._msFire;this._msFire=null,this._requestRenderingMode(n.modeIndex,n.win).then(s=>n.resolve(s),s=>{this._startUpRamp(),n.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())},Rn))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,n=await this._getRenderingModes(t),s=Array.isArray(n)?n:[],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"||_t()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=In(e),i=Rt(e),n=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&n(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;n(c)}}).catch(()=>{t||n(null)})}async _onRenderingModeChange(e){let t=Rt(e),i=Pn(e),n=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];n=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}n?(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.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:n,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let n=t||[e];for(let s of[...i])try{s(...n)}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(!Li.includes(e))throw new TypeError(`[inline3d] on() knows ${Li.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=Ni.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!yt())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 n={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,onResize:t==="scene"&&typeof i.onResize=="function"?i.onResize:null,resizeBox:null,inResize:!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(n,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:Hn(i.firstWovenHoldMs),fwRegAt:N(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null,wsLive:!1,rc:null,layerFramed:!1,lfAnswered:!1,lfStereo:!1,lfAt:0,lfCapped:!1,framedWaiters:[]},s=zn(i.rectCover);return s&&(n.rc={cfg:s,box:null,el:null,up:!1,snapped:!1,snapWanted:!1,waiting:null,w:0,h:0}),n.fwPromise=new Promise(o=>{n.fwResolve=o}),this._windows.set(e,n),this._lazy&&this._observer?this._observer.observe(n.observeEl):this._activate(n),n}_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"),this._dropCover(t))}_onIntersect(e){for(let t of e){let i=null;for(let n of this._windows.values())if(n.observeEl===t.target){i=n;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=gt()?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=N(),e.fwStereo=!1),e.wsLive=bt(),e.layerFramed=!1,e.lfAnswered=!1,e.lfStereo=!1,e.lfCapped=!1,e.lfAt=N(),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&_t()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),yt()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),En(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._noteLayerFramed(e,!1),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(),n=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=n.width*n.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,n.right)-Math.max(i.left,n.left),l=Math.min(i.bottom,n.bottom)-Math.max(i.top,n.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||!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 n=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=n,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&&vt()}_startOverlayScan(e){if(ne()||!Ie()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let n=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)n.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of n)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),n=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/n,a.h/s);c<1&&(o=c,n=Math.max(1,Math.round(n*c)),s=Math.max(1,Math.round(s*c)))}let l=Mi(n,s,Si(),{cols:t?2:1});return l.clamped&&(o*=l.scale,n=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(Ei("[inline3d]",l)))),e.bufScale=o,{w:n,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,n=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(n>0)?null:{w:i/2,h:n}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let n=null;try{n=t.getContext("webgl2")||t.getContext("webgl")}catch{n=null}e.sceneGl=n&&typeof n.drawingBufferWidth=="number"?n:null}if(!e.sceneGl)return;let i=Ci(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(Ri("[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:n}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=n,e.canvas.width=t?i*2:i,e.canvas.height=n,e.sbs=t}_startSizeWatch(e){if(typeof ResizeObserver=="function"&&!e.sizeObserver){if(e.kind==="scene"){if(!e.onResize)return;e.resizeBox=ji(e.canvas),e.sizeObserver=new ResizeObserver(()=>this._onSceneResize(e)),e.sizeObserver.observe(e.canvas);return}!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas))}}_onSceneResize(e){if(!e.layer||!e.onResize||e.inResize)return;let t=ji(e.canvas),i=e.resizeBox;if(!(i&&i.width===t.width&&i.height===t.height&&i.dpr===t.dpr)){e.resizeBox=t,e.inResize=!0;try{e.onResize(t)}catch(n){e.resizeThrewWarned||(e.resizeThrewWarned=!0,console.warn("[inline3d] a scene window's onResize threw; further throws from it are silent.",n))}finally{e.inResize=!1}}}_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:n}=this._eyeSize(e);i===e.eyeW&&n===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 n=e.kind==="video"?e.video:e.img;if(!n)return;if(e.kind==="video"&&(n.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=n.videoWidth||n.naturalWidth||n.width,l=n.videoHeight||n.naturalHeight||n.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:y}=this._eyeSize(e,e.sbs);(f!==e.eyeW||y!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let p=e.bufScale||1,m=e.cornerRadius*p,h=e.feather*p;if(o.clearRect(0,0,s.width,s.height),!e.sbs){je(o,n,0,0,a/2,l,0,0,s.width,s.height,m,h);return}let d=s.width/2,u=Math.min(this._stereoFactor,this._bakedStereo);if(u<1){je(o,n,0,0,a/2,l,0,0,d,s.height,m,h),Vn(o,n,a/2,l,d,s.height,u,m,h);return}m>0||h>0?(je(o,n,0,0,a/2,l,0,0,d,s.height,m,h),je(o,n,a/2,0,a/2,l,d,0,d,s.height,m,h)):o.drawImage(n,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(Et,()=>{this._setTrackingState(Fe(e)||"unknown")})}_setTrackingState(e){let t=zi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:Et,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(Fe(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,n=this._bakedTarget;if(i===n)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=n>i?Math.min(n,i+s):Math.max(n,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,n)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,n))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,n=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.rc&&this._rectCoverCheck(s),s.kind==="scene"){if(n&&s.onFrame){if(s.frames++,n.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(n,s.layer,t),n.length>=2&&(s.fwStereo=!0,s.lfStereo=!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,n),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.lfStereo=!0,s.rw&&(s.rw.stereo=!0));s.rc&&s.rc.snapWanted&&this._rectCoverSnap(s),(!s.layerFramed||s.framedWaiters.length)&&this._tickLayerFramed(s),this._tickFirstWoven(s)}}_tickFirstWoven(e){let t=e.wsLive&&e.layer?We(e.layer):null;if(t){this._tickWovenState(e,t);return}if(e.rw){this._noteRewovenBox(e);let i=e.rw,n=N();i.stereo&&n-i.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):i.at>i.calledAt&&n-i.calledAt>=St*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||N()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_tickWovenState(e,t){let i=N(),n=St*Math.max(e.fwHoldMs,Ct);if(e.rw){this._noteRewovenBox(e);let s=e.rw;t!=="woven"?s.gap=!0:s.stereo&&(s.gap||s.boxFrame!==null&&this._frameCount-s.boxFrame>=Ai||s.boxFrame===null&&this._frameCount-s.callFrame>=Ai)&&this._settleRewoven(e,!0,"woven",!0),e.rw&&i-s.calledAt>=n&&(t==="woven"?this._settleRewoven(e,!0,"hold-capped",!0):this._settleRewoven(e,!1,xt(e.layer)||t,!0))}e.fwResult||e.fwLayerAt===null||(e.fwStereo&&t==="woven"?this._settleFirstWoven(e,!0,"woven",!0):i-e.fwLayerAt>=n&&(t==="woven"?this._settleFirstWoven(e,!0,"hold-capped",!0):this._settleFirstWoven(e,!1,xt(e.layer)||t,!0)))}_settleFirstWoven(e,t,i,n=!1){!t&&!n&&(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:n,reason:i,ms:Math.round(N()-e.fwRegAt)}),e.fwResolve(e.fwResult),e.fwResolve=null)}_rewoven(e){if(!e.fwResult)return e.fwPromise;if(!e.fwResult.woven&&!e.fwResult.confirmed)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}),n=N();return e.rw={promise:i,resolve:t,calledAt:n,at:n,stereo:!1,box:Mt(e.canvas),gap:!1,boxFrame:null,callFrame:this._frameCount},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=Mt(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=N(),e.rw.stereo=!1,e.rw.gap=!1,e.rw.boxFrame=this._frameCount)}_settleRewoven(e,t,i,n=!1){let s=e.rw;s&&(e.rw=null,s.resolve(Object.freeze({woven:t,confirmed:n,reason:i,ms:Math.round(N()-s.calledAt)})))}_rectCoverCheck(e){let t=e.rc,i=Mt(e.canvas);if(i===t.box)return;let n=t.box===null,s=t.w,o=t.h;if(t.box=i,t.w=e.canvas.clientWidth||0,t.h=e.canvas.clientHeight||0,n)return;t.up&&this._placeCover(e);let a=e.fwResult;if(!a||e.rwGone||!(a.woven||a.confirmed))return;t.up||(t.snapped||(t.aspect=o>0?s/o:0),this._raiseCover(e)),t.cfg.snapshot&&!t.snapped&&t.w>0&&t.h>0&&(t.snapWanted=!0);let l;e.rw?(this._noteRewovenBox(e),l=e.rw.promise):(l=this._rewoven(e),e.rw&&(e.rw.boxFrame=this._frameCount)),t.waiting!==l&&(t.waiting=l,l.then(()=>{t.waiting===l&&(t.waiting=null,this._lowerCover(e))}))}_raiseCover(e){let t=e.rc;if(!t.el){if(typeof document>"u"||!document||typeof document.createElement!="function"||!e.canvas.parentElement)return;let i=document.createElement("canvas");i.setAttribute?.("aria-hidden","true"),i.dataset&&(i.dataset.inline3dCover="");let n=i.style;n.position="absolute",n.pointerEvents="none",n.margin="0",n.border="0",n.padding="0",n.background=t.cfg.color,n.display="none";try{let s=typeof getComputedStyle=="function"?getComputedStyle(e.canvas).zIndex:"auto";s&&s!=="auto"&&(n.zIndex=s)}catch{}t.el=i}this._placeCover(e),t.el.style.display="block",t.up=!0,this._fullTileWarned.add(t.el),this._applyExclusion(e,t.el)}_placeCover(e){let i=e.rc.el,n=e.canvas;if(!i)return;let s=n.parentElement;s&&(i.parentElement!==s||i.previousSibling!==n)&&s.insertBefore(i,n.nextSibling);let o=i.style;if(n.offsetParent)o.position="absolute",o.left=`${n.offsetLeft}px`,o.top=`${n.offsetTop}px`,o.width=`${n.offsetWidth}px`,o.height=`${n.offsetHeight}px`;else{let a=n.getBoundingClientRect();o.position="fixed",o.left=`${a.left??a.x??0}px`,o.top=`${a.top??a.y??0}px`,o.width=`${a.width}px`,o.height=`${a.height}px`}}_rectCoverSnap(e){let t=e.rc;t.snapWanted=!1;let i=t.el,n=e.canvas;if(!i||!t.up||!(n.width>1)||!(n.height>0))return;let s=Math.max(1,Math.round(t.w)),o=Math.max(1,Math.round(t.h)),a=s/o,l=t.aspect>0?t.aspect:n.width/2/n.height,c=1,p=1;a>l?p=l/a:c=a/l;let m=n.width/2*c,h=n.height*p,d=(n.width/2-m)/2,u=(n.height-h)/2;try{i.width=s,i.height=o;let f=i.getContext("2d");if(!f)return;f.drawImage(n,d,u,m,h,0,0,s,o),t.snapped=!0}catch{}}_lowerCover(e){let t=e.rc;t&&(t.up=!1,t.snapped=!1,t.snapWanted=!1,t.el&&(t.el.style.display="none",this._dropExclusion(e,t.el)))}_dropCover(e){let t=e.rc;t&&(t.waiting=null,this._lowerCover(e),t.el&&t.el.parentElement&&t.el.parentElement.removeChild(t.el),t.el=null)}_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,B===this&&(B=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._dropCover(e),this._noteLayerFramed(e,!1)}this._windows.clear(),this._claims.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function Hn(r){return typeof r=="number"&&Number.isFinite(r)&&r>=0?r:Ct}function $n(r){return typeof r!="string"?Promise.resolve(r):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=r})}function je(r,e,t,i,n,s,o,a,l,c,p,m){p>0&&r.roundRect?(r.save(),r.beginPath(),r.roundRect(o,a,l,c,p),r.clip(),r.drawImage(e,t,i,n,s,o,a,l,c),r.restore()):r.drawImage(e,t,i,n,s,o,a,l,c),m>0&&Ui(r,o,a,l,c,m)}function Vn(r,e,t,i,n,s,o,a,l){r.save(),a>0&&r.roundRect&&(r.beginPath(),r.roundRect(n,0,n,s,a),r.clip()),r.drawImage(e,0,0,t,i,n,0,n,s),o>0&&(r.globalAlpha=o,r.drawImage(e,t,0,t,i,n,0,n,s)),r.restore(),l>0&&Ui(r,n,0,n,s,l)}function Ui(r,e,t,i,n,s){let o=Math.min(s,Math.floor(Math.min(i,n)/2));if(o<=0)return;r.save(),r.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+n-o,i,o,[e,t+n],[e,t+n-o]],[e,t,o,n,[e,t],[e+o,t]],[e+i-o,t,o,n,[e+i,t],[e+i-o,t]]];for(let[l,c,p,m,h,d]of a){let u=r.createLinearGradient(h[0],h[1],d[0],d[1]);u.addColorStop(0,"rgba(0,0,0,1)"),u.addColorStop(1,"rgba(0,0,0,0)"),r.fillStyle=u,r.fillRect(l,c,p,m)}r.restore()}function oe(r,e){return r>0&&e>0&&r/e>2.5}function V(r,e,t,i,n){let s=Math.abs(i||0),o=Math.min(r-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(r-o)/2+(n===0?i:-i);return{sx:Math.max(0,Math.min(r-o,l)),sy:(e-a)/2,sw:o,sh:a}}function be(r,e,t){let i=Math.min(r,e*t),n=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(n/2)*2)}}function ae(r,e){let t=r/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 Tt(r,e,t){let i=new r.constructor(r.length);for(let n of ae(e,t))for(let s=0;s<t;s++)for(let o=0;o<n.dw;o++){let a=n.sx+(n.sw-1-o);i[s*e+n.dx+o]=r[s*e+a]}return i}function Bi(r,e){return!(r>0)||!(e>0)||e>=180?null:r/2/Math.tan(e/2*Math.PI/180)}function ze({eyeWidthPx:r,hfovDeg:e,baselineMm:t,subjectZmm:i}){let n=Bi(r,e);return n===null||!(t>0)||!(i>0)?0:n*t/(2*i)}function He(r,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,r||0))}function $e(r,e,t=.2){let i=r+t*(e-r);return Math.abs(e-i)<.05?e:i}function xe(){let r={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=r.measuredPx!==null?r.measuredPx/2:r.hello&&r.subjectZmm?ze({eyeWidthPx:e,hfovDeg:r.hello.hfovDeg,baselineMm:r.hello.baselineMm,subjectZmm:r.subjectZmm}):0;return He(t+r.depth*.05*e,e)},step(e){return r.current=$e(r.current,r.target(e)),r.current}};return r}var Ve=1,Lt="inline3d-call/1",qi=Object.freeze(["sbs","mono"]),le=4,Xi=4,Dt=5,Un=150,Bn=5e3,qn=/^[A-Za-z0-9_-]{16,64}$/,Xn=16;function At(r){let e=new Uint8Array(Xn);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),Ji(e)}function Gi(r){let e=new Uint8Array(8);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),Ji(e)}function Ji(r){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<r.length;i+=3){let s=r[i]<<16|r[i+1]<<8|r[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let n=r.length-i;if(n===1){let s=r[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(n===2){let s=r[i]<<16|r[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function ce(r){return typeof r=="string"&&qn.test(r)}function Se(r){if(!r)return null;let e="";if(typeof r=="object")e=r.hash||r.href&&String(r.href).split("#")[1]||"";else{let t=String(r),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 n=decodeURIComponent(t.slice(i+1));return ce(n)?n:null}return null}function Ue(r,e){if(!ce(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(r||"").split("#")[0]}#room=${e}`}function Ot(r){if(!r||typeof r!="object"||r.type!=="hello")return null;let e=(t,i,n)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=n?t:null;return{type:"hello",v:typeof r.v=="number"?r.v:Ve,format:qi.includes(r.format)?r.format:"mono",width:e(r.width,1,16384),height:e(r.height,1,16384),baselineMm:e(r.baselineMm,1,1e3),hfovDeg:e(r.hfovDeg,5,170),rectified:r.rectified===!0,sdk:typeof r.sdk=="string"?r.sdk.slice(0,64):null}}function Pt({format:r,width:e,height:t,baselineMm:i,hfovDeg:n,rectified:s}={}){let o={type:"hello",v:Ve,format:qi.includes(r)?r:"mono",width:e||0,height:t||0,rectified:!!s,sdk:Lt};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(n)&&(o.hfovDeg=n),o}function It(r){if(!r||r.type!=="hint")return null;let e=r.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=Un&&e<=Bn?{type:"hint",subjectZmm:e}:null}function Yi(r){return!r||r.type!=="state"?null:{type:"state",muted:r.muted===!0,cameraOff:r.cameraOff===!0,speaking:r.speaking===!0}}function Ft(r){let e=1e3/r,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function Wt({format:r,woven:e,mono3D:t="auto",lift:i=!1,overBudget:n=!1,failed:s=!1}){return(r==="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"}:n?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function jt(r){return r==="woven-sbs"?"3D":r==="lifted"?"2D\u21923D":"2D"}function Nt({need:r=10,needNoPose:e=30}={}){let t=0,i=0,n=!1;return{feed(s){return n?!0:(i++,s===null?n=i>=e:(t=s>=1?t+1:0,n=t>=r),n)},get live(){return n}}}function Be(r,e){let t=Math.max(1,e|0),n=r==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return n[Math.min(t,n.length)-1]}function q(r,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let n=Math.min(t,e*Math.pow(2,Math.max(0,r)));return Math.round(n*(.8+.4*i()))}var Me=Object.freeze(["VP9","VP8","AV1"]);function Jn(r,e=Me){let t=e.indexOf(String(r||"").toUpperCase());return t<0?e.length:t}function qe(r,e=Me){let t=i=>Jn(String(i.mimeType||"").split("/")[1],e);return r.map((i,n)=>({c:i,i:n,r:t(i)})).sort((i,n)=>i.r-n.r||i.i-n.i).map(i=>i.c)}function Ee(r,e=Me){if(!r)return r;let t=r.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,u)=>u>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 u=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);u&&a.set(u[1],u[2].toUpperCase());let p=d.match(/^a=fmtp:(\d+) apt=(\d+)/);p&&(l.has(p[2])||l.set(p[2],[]),l.get(p[2]).push(p[1]))}let c=i[r].split(" "),f=c.slice(3),m=[];for(let d of e)for(let u of f)if(a.get(u)===d&&!m.includes(u)){m.push(u);for(let p of l.get(u)||[])f.includes(p)&&!m.includes(p)&&m.push(p)}if(!m.length)return n;let h=f.filter(d=>!m.includes(d));return i[r]=[...c.slice(0,3),...m,...h].join(" "),i.join(t)}var Ki=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),Gr=4e3,Jr=1e4,Yr=2e4,Kr=8e3,Zr=1e4;function ke(n){let e=Number.isInteger(n)?n:le;return Math.max(2,Math.min(Xi,e))}function Zi(n,e){return n<e}var Ce=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:r,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:Zr,this.signaling=e,this.id=t,this.maxPeers=ke(i),this.pageIce=r||null,this.iceServers=r||Ki,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:f,onGhost:m}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:f,onGhost:m};let h=p=>(...y)=>this.ready?p(...y):this._pending.push(()=>p(...y));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(p=>this._onPeerJoined(p)),onPeerLeft:h(p=>this._onPeerLeftSignaling(p)),onSignal:h((p,y)=>this._onSignal(p,y)),onDisconnect:p=>f?.(p?"closed":"reconnecting",p),onPeerUnreachable:h(p=>m?.(p,!0)),onPeerReachable:h(p=>m?.(p,!1)),onReconnect:h(p=>{f?.("connected");for(let y of p)this._onPeerJoined(y)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Ki,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let p=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw p.code="room-full",p}this.ready=!0;for(let p of d)this._onPeerJoined(p);let u=this._pending;this._pending=[];for(let p of u)p();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"&&Zi(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),Kr)}_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:Zi(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(f=>f.kind==="audio"),a=s.find(f=>f.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,Yr,()=>{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(qe(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,Gr,()=>{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,Jr,()=>{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=q(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,q(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=Be(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 Qi={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},zt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},Qr=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function es(n){return!!n&&(n.name==="NotReadableError"||n.name==="TrackStartError"||/in use|busy/i.test(n.message||""))}function ts(n){return!!n&&(n.name==="NotAllowedError"||n.name==="PermissionDeniedError"||n.name==="SecurityError")}function en(n){return n.length&&n.every(e=>e.busy)?"camera-busy":n.some(e=>e.denied)?"permission-denied":"no-camera"}function Ht(n){return/stereo|\b3d\b|\bsbs\b|dual/i.test(n||"")}async function tn(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 u=n.getVideoTracks()[0],p=u?u.getSettings():{},y=e.format==="sbs"?"sbs":"mono";return{stream:n,format:y,width:p.width||0,height:p.height||0,deviceId:p.deviceId||null,label:u?u.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 u=>{let p=await t.getUserMedia({video:u,audio:!1}),y=p.getVideoTracks()[0],v=y?y.getSettings():{};if(!y||y.readyState==="ended"||!(v.width>0)||!(v.height>0))throw p.getTracks().forEach(R=>R.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=v.displayxrStereo&&v.displayxrStereo.layout==="side-by-side"?v.displayxrStereo:null;return{stream:p,track:y,width:v.width,height:v.height,deviceId:v.deviceId||null,label:y.label||"",stereo:b}},a=(u,p)=>{r.push({label:u,error:`${p.name}: ${p.message}`,busy:es(p),denied:ts(p)}),i("camera-skip",{label:u,error:p.name})},l=u=>u&&u.stream.getTracks().forEach(p=>p.stop()),c=(u,p)=>({stream:u.stream,format:p,width:u.width,height:u.height,deviceId:u.deviceId,label:u.label,owned:!0,skipped:r,calibration:{rectified:!1,...p==="sbs"&&u.stereo?{rectified:!!u.stereo.rectified,...u.stereo.baselineMm>0?{baselineMm:u.stereo.baselineMm}:{},...u.stereo.horizontalFovDeg>0?{hfovDeg:u.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof n=="string"&&!["auto","stereo","mono"].includes(n)){let u;try{u=await o({deviceId:{exact:n},...zt})}catch(p){throw a(n,p),Object.assign(new Error(`camera unavailable: ${p.message}`),{code:en(r),skipped:r})}return oe(u.width,u.height)?c(u,"sbs"):(l(u),c(await o({deviceId:{exact:n},...Qi}),"mono"))}let f=new Set;if(n!=="mono"){let u=[];try{u=(await t.enumerateDevices()).filter(p=>p.kind==="videoinput"&&p.deviceId&&Ht(p.label))}catch{}for(let p of u){f.add(p.deviceId);let y=null;try{y=await o({deviceId:{exact:p.deviceId},...zt})}catch(v){a(p.label,v);continue}if(oe(y.width,y.height))return i("camera-sbs",{label:y.label,width:y.width,height:y.height,direct:!0}),c(y,"sbs");l(y)}}let m=null;try{m=await o(Qi)}catch(u){a("default",u)}if(n==="mono"&&m)return c(m,"mono");if(m&&oe(m.width,m.height))return c(m,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput")}catch{}h.sort((u,p)=>Number(Ht(p.label))-Number(Ht(u.label)));for(let u of h){if(!u.deviceId||m&&u.deviceId===m.deviceId||f.has(u.deviceId))continue;let p=null;try{p=await o({deviceId:{exact:u.deviceId},...zt})}catch(y){a(u.label,y);continue}if(oe(p.width,p.height))return l(m),i("camera-sbs",{label:p.label,width:p.width,height:p.height}),c(p,"sbs");l(p)}if(m)return n==="stereo"&&i("camera-no-stereo",{fallback:m.label}),c(m,"mono");let d=en(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 nn(n={}){let e=n.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...Qr},video:!1})).getAudioTracks()[0]||null}catch(t){return(n.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Vt();Ut();var cn="http://displayxr.org/ns/stereo/1.0/",Ke="http://ns.adobe.com/xap/1.0/\0";function Qe(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 ls=n=>String(n).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),de=n=>Math.round(n*1e3)/1e3;function hn(n){let e=Qe(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}="${ls(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="${cn}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function qt(n){if(typeof n!="string"||!n.includes(cn))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 Qe({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(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&amp;/g,"&")})}var Ze=n=>new TextEncoder().encode(n),Bt=n=>new TextDecoder().decode(n),dn=n=>n.length>4&&n[0]===255&&n[1]===216;function*un(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 fn(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 pn(n,e){if(!dn(n))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Ze(Ke),...Ze(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 f of un(n)){if(f.marker===225&&fn(f.data,Ke)){o=f;break}if(f.marker===224||f.marker===225)s=f.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 Xt(n){if(!dn(n))return null;for(let e of un(n))if(e.marker===225&&fn(e.data,Ke))return Bt(e.data.subarray(Ke.length));return null}var mn=n=>qt(Xt(n)),$={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},cs=n=>n.length>4&&n[0]===26&&n[1]===69&&n[2]===223&&n[3]===163;function gn(n){let e=[];for(let t=n;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function _n(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 Gt(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 Le(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 he(n,e){return[...gn(n),..._n(e.length),...e]}function hs(n){let e=[];for(let[i,r]of Object.entries(n))r!=null&&e.push(...he($.SimpleTag,[...he($.TagName,[...Ze(String(i))]),...he($.TagString,[...Ze(String(r))])]));let t=he($.Tag,[...he($.Targets,[]),...e]);return new Uint8Array(he($.Tags,t))}function yn(n){let e=Qe(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 ds(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 Qe({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 vn(n){if(!cs(n))return null;let e=Le(n,4);if(!e)return null;let t=4+e.width+e.size;for(;t<n.length;){let i=Gt(n,t);if(!i)return null;let r=Le(n,t+i.width);if(!r)return null;let s=t+i.width+r.width;if(i.id===$.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 wn(n,e){let t=vn(n);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=hs(e);if(t.unknown){let f=new Uint8Array(n.length+i.length);return f.set(n,0),f.set(i,n.length),f}let r=Math.min(n.length,t.dataStart+t.size),s=r-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=_n(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 bn(n,e,t){let i={},r=(s,o,a)=>{let l=s;for(;l<o;){let c=Gt(n,l);if(!c)return;let f=Le(n,l+c.width);if(!f||f.unknown)return;let m=l+c.width+f.width;a(c.id,m,Math.min(o,m+f.size)),l=m+f.size}};return r(e,t,(s,o,a)=>{s===$.Tag&&r(o,a,(l,c,f)=>{if(l!==$.SimpleTag)return;let m=null,h=null;r(c,f,(d,u,p)=>{d===$.TagName?m=Bt(n.subarray(u,p)):d===$.TagString&&(h=Bt(n.subarray(u,p)))}),m!==null&&(i[m]=h??"")})}),i}function us(n){let e=vn(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=Gt(n,r);if(!s)break;let o=Le(n,r+s.width);if(!o)break;let a=r+s.width+o.width;if(s.id===$.Tags&&!o.unknown&&(i={...i||{},...bn(n,a,Math.min(t,a+o.size))}),o.unknown){i=i||fs(n,t);break}r=a+o.size}return i}function fs(n,e){let t=gn($.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=Le(n,i+4);if(r&&!r.unknown&&i+4+r.width+r.size===e)return bn(n,i+4+r.width,e)}return null}var xn=n=>ds(us(n));var ee="[inline3d/camera]",jn="inline3d-camera/1",gs=200,_s=240,ys=66,vs=4e3,ws=4,bs=1500,xs=2e4,Ss=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],tt=()=>typeof document<"u"&&document&&typeof document.createElement=="function",Fn=()=>{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())}`},Ms=n=>/jpe?g/.test(n)?"jpg":/png/.test(n)?"png":/webp/.test(n)?"webp":/mp4/.test(n)?"mp4":/webm/.test(n)?"webm":"bin";function it(n,e,t){return`${String(n||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${Ms(t)}`}var Y=(n,e,t={})=>Object.assign(new Error(`${ee} ${n}`),{code:e,...t});function Wn(n,e=vs){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(Y("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(Y("no video element (no document?)","no-frame"))}function Nn(n,e,t=_s){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:Ge(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var Qt=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,tt()&&(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(`${ee} 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(`${ee} '${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||!tt())return null;try{await Wn(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=Nn(this.video,this._scratch);if(!e)return null;let t=Te().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:jn}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:r}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(!this.video||!tt())throw Y("capturePhoto needs a document","no-frame");await Wn(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,u)=>l.toBlob(p=>p?d(p):u(Y("toBlob produced nothing","encode-failed")),e,t)),f=this._meta(a,s,o),m=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(m=hn(f),c=new Blob([pn(new Uint8Array(await c.arrayBuffer()),m)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:it(i||`photo-${Fn()}`,this.format,c.type||e),xmp:m};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 Y("the camera is closed","closed");if(typeof MediaRecorder!="function")throw Y("MediaRecorder is not available here","unsupported");let l=e||Ss.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw Y(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],f=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...f);let m=new MediaStream(c),h={...l?{mimeType:l}:{},...r?{videoBitsPerSecond:r}:{}},d=new MediaRecorder(m,h),u=[];d.ondataavailable=g=>g.data&&g.data.size&&u.push(g.data);let p=null,y=[],v=null,b=0,R=!!t&&this.format==="sbs"&&tt()&&this.video;if(R){v=document.createElement("canvas");let g=()=>{b=requestAnimationFrame(g);let _=this.video,M=_.videoWidth,O=_.videoHeight;!M||!O||(_.readyState||0)<2||((v.width!==M/2||v.height!==O)&&(v.width=M/2,v.height=O),v.getContext("2d").drawImage(_,0,0,M/2,O,0,0,M/2,O))};g();let w=v.captureStream(a);for(let _ of f)w.addTrack(_);p=new MediaRecorder(w,h),p.ondataavailable=_=>_.data&&_.data.size&&y.push(_.data)}let x=performance.now(),I=[],C=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),p?.start(s),this.log("record-start",{mimeType:l,mono:R,audio:f.length});let D=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),P=o||`clip-${Fn()}`,A=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),p&&p.state==="recording"&&p.pause()},resume(){d.state==="paused"&&d.resume(),p&&p.state==="paused"&&p.resume()},async stop(){clearInterval(C),b&&cancelAnimationFrame(b);let[g,w]=await Promise.all([D(d,u),D(p,y)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",M=[...I].sort((me,U)=>me-U),O=M.length?M[Math.floor(M.length/2)]:null,S=A._meta(O),F=/webm|matroska/.test(_),H=async(me,U)=>{let Z=new Blob(me,{type:_});if(F&&Z.size)try{Z=new Blob([wn(new Uint8Array(await Z.arrayBuffer()),yn({...S,layout:U}))],{type:_})}catch(gi){A.log("record-tag-failed",{message:String(gi&&gi.message)})}return Z},k=await H(g,A.format),W={blob:k,type:_,layout:A.format,durationMs:Math.round(performance.now()-x),convergencePx:O,stereo:A.stereo,suggestedName:it(P,A.format,_),tagged:F&&k.size>0};return p&&(W.mono=await H(w,"mono"),W.monoSuggestedName=it(P,"mono",_)),A.log("record-stop",{bytes:k.size,mono:W.mono?W.mono.size:null,ms:W.durationMs,convergencePx:O,name:W.suggestedName}),W}}}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 ti(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(`${ee} ${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 tn(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 Qt(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 nt=n=>!!n&&typeof n=="object"&&typeof n.capturePhoto=="function"&&typeof n.record=="function"&&n.stream&&typeof n.stream.getVideoTracks=="function";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 ii(n,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${ee} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!nt(t))throw new TypeError(`${ee} addCameraView: cam must be a StereoCamera from openCamera()`);let r=new ei(n,e,t,i);return t._views?.add(r),r}var ei=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.fallbackReason=null,this._fw=null,this._onRouteChange=typeof r.onRouteChange=="function"?r.onRouteChange:null,this._layerFails=0,this._layerTimer=0,this.buffer=null,this.removed=!1,this._raf=0,this._loop=r._loop!==!1,this._autoAt=0,this._track=Je(),this._focus=Te(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=Ye(r.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(Zt(),Kt)).then(s=>{this.removed||(this.cursor=new s.PairCursor(this.canvas,this._cursorOpt))}),this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}weaveState(){return{route:this.route,woven:this.woven,reason:this.fallbackReason,firstWoven:this.route==="woven-sbs"?this._fw?{...this._fw}:"pending":null,layerRetries:this._layerFails}}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;e&&this.fallbackReason&&(this.fallbackReason=null,clearTimeout(this._layerTimer),this._layerTimer=0);let i=this.cam,r=i.state==="live"&&i.video,o=i.format==="sbs"&&r&&this.wall&&this.wall.supported&&!this.fallbackReason?"woven-sbs":i.format==="sbs"?"flat-left":"flat";if(!e&&o===this.route)return;let a=this.route;this._unregister(),this.route=o,o==="woven-sbs"&&this._registerWoven(),o!==a&&this._routeChanged()}_registerWoven(){this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven();let e=this.wall.addImage(this.canvas,this.buffer);this.handle=e,this._fw=null;let t=e&&e.firstWoven;!t||typeof t.then!="function"||t.then(i=>{this.handle!==e||this.removed||!i||(this._fw={woven:!!i.woven,confirmed:!!i.confirmed,reason:i.reason||null,ms:i.ms},this.cam.log?.("view-first-woven",{woven:!!i.woven,reason:i.reason||null}),i.woven?(this._layerFails=0,this._routeChanged()):i.reason!=="removed"&&this._layerLost(i.reason||"layer-failed"))})}_layerLost(e){if(this.fallbackReason=e,this._reroute(!1),e!=="layer-failed"||this._layerFails>=ws)return;let t=Math.min(xs,bs*Math.pow(2,this._layerFails++));this.cam.log?.("view-layer-retry",{attempt:this._layerFails,inMs:t}),clearTimeout(this._layerTimer),this._layerTimer=setTimeout(()=>{this._layerTimer=0,!(this.removed||this.fallbackReason!==e)&&this._reroute(!0)},t)}_routeChanged(){if(this._onRouteChange)try{this._onRouteChange(this.route,this.weaveState())}catch(e){console.error(`${ee} onRouteChange threw`,e)}}_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(this.cursor?.idle(),!Es(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=V(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);let c=!!(this.cursor&&this.cursor.hovering);(this.autoConverge||c)&&this._sample(e,c);let f=this.conv.step(r),m=l.getContext("2d");if(this.mirror)for(let h of ae(t,i)){let d=h.src==="L"?0:1,u=V(r,i,s,f,d),p=h.dx===0?0:o;m.save(),m.translate(p+o,0),m.scale(-1,1),m.drawImage(e,h.sx+u.sx,u.sy,u.sw,u.sh,0,0,o,a),m.restore()}else for(let h of[0,1]){let d=V(r,i,s,f,h);m.drawImage(e,h*r+d.sx,d.sy,d.sw,d.sh,h*o,0,o,a)}if(this.cursor){let h={rL:V(r,i,s,f,0),rR:V(r,i,s,f,1),outW:o,outH:a,mirror:this.mirror};this.cursor.draw(m,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?ys:gs))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let r=Nn(e,this._scratch);if(r&&(this._luma=r),!this.autoConverge)return;let s=r?this._focus.measure(r.img,r.w,r.h,i):null,o=this._track.push(s?s.d/r.scale:null);this.conv.measuredPx=o,this.disparityPx=o}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,clearTimeout(this._layerTimer),this._layerTimer=0,this._unregister(),this.cursor?.dispose(),this.cursor=null,this.cam._views?.delete(this))}};var Hn=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],$n=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Cs=[1,0],ni=10;function Vn(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 zn=(n,e)=>Math.floor(Vn(n)/8)-Hn[e][n]*$n[e][n];function ri(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 ks(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]=ri(e[r],t),r+1<e.length&&(e[r]^=e[r+1]);t=ri(t,2)}return e}function Rs(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]^=ri(s,r))}return t}function si(n,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(n))],r=1;for(;r<=ni&&!(4+(r<=9?8:16)+i.length*8<=zn(r,t)*8);r++);if(r>ni)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${ni} 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=zn(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=$n[t][r],f=Hn[t][r],m=Math.floor(Vn(r)/8),h=c-m%c,d=Math.floor(m/c),u=ks(f),p=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-f+(g<h?0:1));w+=_.length;let M=Rs(_,u);g<h&&_.push(0),p.push(_.concat(M))}let y=[];for(let g=0;g<p[0].length;g++)for(let w=0;w<p.length;w++)(g!==d-f||w>=h)&&y.push(p[w][g]);let v=r*4+17,b=Array.from({length:v},()=>new Array(v).fill(!1)),R=Array.from({length:v},()=>new Array(v).fill(!1)),x=(g,w,_)=>{b[w][g]=_,R[w][g]=!0};for(let g=0;g<v;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 O=Math.max(Math.abs(M),Math.abs(_)),S=g+M,F=w+_;S>=0&&S<v&&F>=0&&F<v&&x(S,F,O!==2&&O!==4)}};I(3,3),I(v-4,3),I(3,v-4);let C=[];if(r>1){let g=Math.floor(r/7)+2,w=Math.ceil((r*4+4)/(g*2-2))*2;C.push(6);for(let _=v-7;C.length<g;_-=w)C.splice(1,0,_)}for(let g=0;g<C.length;g++)for(let w=0;w<C.length;w++)if(!(g===0&&w===0||g===0&&w===C.length-1||g===C.length-1&&w===0))for(let _=-2;_<=2;_++)for(let M=-2;M<=2;M++)x(C[g]+M,C[w]+_,Math.max(Math.abs(M),Math.abs(_))!==1);let D=g=>{let w=Cs[t]<<3|g,_=w;for(let S=0;S<10;S++)_=_<<1^(_>>>9)*1335;let M=(w<<10|_)^21522,O=S=>(M>>>S&1)!==0;for(let S=0;S<=5;S++)x(8,S,O(S));x(8,7,O(6)),x(8,8,O(7)),x(7,8,O(8));for(let S=9;S<15;S++)x(14-S,8,O(S));for(let S=0;S<8;S++)x(v-1-S,8,O(S));for(let S=8;S<15;S++)x(8,v-15+S,O(S));x(8,v-8,!0)};if(D(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,O=v-11+_%3,S=Math.floor(_/3);x(O,S,M),x(S,O,M)}}let P=0;for(let g=v-1;g>=1;g-=2){g===6&&(g=5);for(let w=0;w<v;w++)for(let _=0;_<2;_++){let M=g-_,S=(g+1&2)===0?v-1-w:w;!R[S][M]&&P<y.length*8&&(b[S][M]=(y[P>>>3]>>>7-(P&7)&1)!==0,P++)}}let A=g=>{for(let w=0;w<v;w++)for(let _=0;_<v;_++){if(R[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][_])}},T=Number.isInteger(e.mask)?e.mask:-1;if(T<0){let g=1/0;for(let w=0;w<8;w++){A(w),D(w);let _=Ts(b,v);_<g&&(g=_,T=w),A(w)}}return A(T),D(T),{version:r,size:v,mask:T,modules:b}}function Ts(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 f=l.indexOf(c);f>=0;f=l.indexOf(c,f+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 Un(n,e,{px:t=4,dark:i="#000",light:r="#fff",ecl:s="M"}={}){let o=si(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 f=0;f<o.size;f++)o.modules[c][f]&&l.fillRect((f+4)*t,(c+4)*t,t,t);return o}function K(n,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=n,t}async function oi(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 rt="wss://signal.displayxr.org",Bn=Object.freeze([rt,"wss://dxr-signal.displayxr.workers.dev"]),qn=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function ue(n=rt,e={}){if(!n||typeof n!="string")throw K("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):Bn.includes(i)?[...Bn]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,f){let h=`k=${await oi(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=A=>`${a[A]}/v1/connect?${h}`,u=null,p=!1,y=0,v=null,b=new Set,R=[],x=A=>I(A,a.length),I=(A,T)=>new Promise((g,w)=>{let _=!1,M=!1,O=!1,S=new r(d(l));u=S;let F=H=>{if(!_){_=!0;try{S.close()}catch{}w(H)}};S.onopen=()=>{O=!0,S.send(JSON.stringify({t:"join",v:1,room:c,id:f.id,max:f.maxPeers}))},S.onmessage=H=>{let k;try{k=JSON.parse(typeof H.data=="string"?H.data:String(H.data))}catch{return}switch(k.t){case"welcome":{y=0;let W=Array.isArray(k.peers)?k.peers.filter(U=>typeof U=="string"):[];clearInterval(v),v=setInterval(()=>C({t:"ping"}),s);let me=R;R=[];for(let U of me)C(U);if(A){let U=new Set(W);for(let Z of b)U.has(Z)||f.onPeerLeft?.(Z);b=U,f.onReconnect?.(W)}else b=new Set(W);_=!0,M=!0,g({id:k.id,peers:W,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":p=!0,F(K("room-full",`this call is full (${k.max} participants)`));break;case"expired":{p=!0,clearInterval(v);let W=K("expired","this room has reached its lifetime on the signalling server");_?f.onDisconnect?.(W):F(W);break}case"error":if(!_&&qn.includes(k.code))p=!0,F(K(k.code,k.message||k.code));else if(!_&&(k.code==="rate-limited"||k.code==="quota")){let W=K(k.code,k.message||k.code);W.retryMs=k.retryMs>0?k.retryMs:0,F(W)}else!_&&k.code==="id-taken"&&F(K("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof k.id=="string"&&!b.has(k.id)&&(b.add(k.id),f.onPeerJoined?.(k.id));break;case"peer-left":typeof k.id=="string"&&(b.delete(k.id),f.onPeerLeft?.(k.id));break;case"signal":typeof k.from=="string"&&f.onSignal?.(k.from,k.data);break}},S.onerror=()=>{if(!O&&!_&&T>1){_=!0,l=(l+1)%a.length,I(A,T-1).then(g,w);return}F(K("signaling-unreachable",`cannot reach ${a[l]}`))},S.onclose=()=>{clearInterval(v),F(K("signaling-closed","signalling closed before joining")),M&&!p&&u===S&&D()}}),C=A=>{u&&u.readyState===1?u.send(JSON.stringify(A)):p||R.push(A)},D=()=>{f.onDisconnect?.();let A=()=>{p||x(!0).catch(T=>{if(p||T&&(T.code==="room-full"||qn.includes(T.code))){f.onDisconnect?.(T);return}setTimeout(A,Math.max(q(y++,{baseMs:500,maxMs:15e3}),T&&T.retryMs||0))})};setTimeout(A,q(y++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(A,T)=>C({t:"signal",to:A,data:T}),leave:()=>{if(!p){p=!0,clearInterval(v);try{u&&u.readyState===1&&u.send(JSON.stringify({t:"leave"})),u&&u.close(1e3,"leave")}catch{}}}}}}}var ai=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),Gn=n=>typeof n=="string"&&ai[n.toLowerCase()]||n,Jn=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 Yn(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 Xn="dxr-call-style",As=`
5
+ `,i=r.split(t),n=i.findIndex(d=>d.startsWith("m=video"));if(n<0)return r;let s=i.findIndex((d,u)=>u>n&&d.startsWith("m="));s<0&&(s=i.length);let o=i.slice(n,s),a=new Map,l=new Map;for(let d of o){let u=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);u&&a.set(u[1],u[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[n].split(" "),p=c.slice(3),m=[];for(let d of e)for(let u of p)if(a.get(u)===d&&!m.includes(u)){m.push(u);for(let f of l.get(u)||[])p.includes(f)&&!m.includes(f)&&m.push(f)}if(!m.length)return r;let h=p.filter(d=>!m.includes(d));return i[n]=[...c.slice(0,3),...m,...h].join(" "),i.join(t)}var Ki=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),Kn=4e3,Zn=1e4,Qn=2e4,es=8e3,ts=1e4;function Re(r){let e=Number.isInteger(r)?r:le;return Math.max(2,Math.min(Xi,e))}function Zi(r,e){return r<e}var Ce=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:n,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:ts,this.signaling=e,this.id=t,this.maxPeers=Re(i),this.pageIce=n||null,this.iceServers=n||Ki,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:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:m}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:m};let h=f=>(...y)=>this.ready?f(...y):this._pending.push(()=>f(...y));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,y)=>this._onSignal(f,y)),onDisconnect:f=>p?.(f?"closed":"reconnecting",f),onPeerUnreachable:h(f=>m?.(f,!0)),onPeerReachable:h(f=>m?.(f,!1)),onReconnect:h(f=>{p?.("connected");for(let y of f)this._onPeerJoined(y)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Ki,...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 u=this._pending;this._pending=[];for(let f of u)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"&&Zi(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),es)}_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:Zi(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 n=i.createDataChannel("dxr-call",{negotiated:!0,id:0,ordered:!0});if(this._wireDc(e,n),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,Qn,()=>{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,n=await i.createOffer(t?{iceRestart:!0}:void 0);this._canPreferCodecs||(n.sdp=Ee(n.sdp)),await i.setLocalDescription(n),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 n=t.gen|0;try{switch(t.kind){case"offer":{if(i.offerer||(clearTimeout(i.waitTimer),n<i.gen))return;i.offerAt=Date.now(),(n>i.gen||!i.pc)&&this._build(i,n);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||n!==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(n!==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 n of t.getTransceivers()){let s=n.receiver&&n.receiver.track?n.receiver.track.kind:null;if(!s||n.sender.track)continue;let o=i.find(a=>a.kind===s);o&&(n.sender.replaceTrack(o).catch(()=>{}),this.localStream&&n.sender.setStreams&&n.sender.setStreams(this.localStream)),n.direction="sendrecv",s==="video"&&this._preferCodecs(n)}}_preferCodecs(e){let t=globalThis.RTCRtpReceiver&&RTCRtpReceiver.getCapabilities&&RTCRtpReceiver.getCapabilities("video");if(this._canPreferCodecs=!!(e&&e.setCodecPreferences&&t),!!this._canPreferCodecs)try{e.setCodecPreferences(qe(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,Kn,()=>{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,Zn,()=>{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=q(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,q(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 n=setTimeout(()=>{e.timers.delete(n),i()},t);e.timers.add(n)}_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 n;try{n=JSON.parse(i.data)}catch{return}if(n&&n.type==="bye")return this._drop(e,"left");this.cb.onMessage?.(e.id,n)}}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 n of this.peers.values())if(n.pc)for(let s of n.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=Be(this.sendFormat,e);for(let i of this.peers.values())if(i.pc){for(let n of i.pc.getSenders())if(!(!n.track||n.track.kind!=="video"))try{let s=n.getParameters();s.degradationPreference="maintain-resolution",(!s.encodings||!s.encodings.length)&&(s.encodings=[{}]),s.encodings[0].maxBitrate=t*1e3,await n.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 Qi={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},zt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},is=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function rs(r){return!!r&&(r.name==="NotReadableError"||r.name==="TrackStartError"||/in use|busy/i.test(r.message||""))}function ns(r){return!!r&&(r.name==="NotAllowedError"||r.name==="PermissionDeniedError"||r.name==="SecurityError")}function er(r){return r.length&&r.every(e=>e.busy)?"camera-busy":r.some(e=>e.denied)?"permission-denied":"no-camera"}function Ht(r){return/stereo|\b3d\b|\bsbs\b|dual/i.test(r||"")}async function tr(r="auto",e={}){let t=e.mediaDevices||globalThis.navigator&&navigator.mediaDevices,i=e.log||(()=>{}),n=[],s=e.calibration||{};if(r&&typeof r=="object"&&typeof r.getVideoTracks=="function"){let u=r.getVideoTracks()[0],f=u?u.getSettings():{},y=e.format==="sbs"?"sbs":"mono";return{stream:r,format:y,width:f.width||0,height:f.height||0,deviceId:f.deviceId||null,label:u?u.label:"",owned:!1,skipped:n,calibration:s}}if(!t||!t.getUserMedia)throw Object.assign(new Error("getUserMedia is not available (insecure context?)"),{code:"no-camera"});let o=async u=>{let f=await t.getUserMedia({video:u,audio:!1}),y=f.getVideoTracks()[0],v=y?y.getSettings():{};if(!y||y.readyState==="ended"||!(v.width>0)||!(v.height>0))throw f.getTracks().forEach(k=>k.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=v.displayxrStereo&&v.displayxrStereo.layout==="side-by-side"?v.displayxrStereo:null;return{stream:f,track:y,width:v.width,height:v.height,deviceId:v.deviceId||null,label:y.label||"",stereo:b}},a=(u,f)=>{n.push({label:u,error:`${f.name}: ${f.message}`,busy:rs(f),denied:ns(f)}),i("camera-skip",{label:u,error:f.name})},l=u=>u&&u.stream.getTracks().forEach(f=>f.stop()),c=(u,f)=>({stream:u.stream,format:f,width:u.width,height:u.height,deviceId:u.deviceId,label:u.label,owned:!0,skipped:n,calibration:{rectified:!1,...f==="sbs"&&u.stereo?{rectified:!!u.stereo.rectified,...u.stereo.baselineMm>0?{baselineMm:u.stereo.baselineMm}:{},...u.stereo.horizontalFovDeg>0?{hfovDeg:u.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof r=="string"&&!["auto","stereo","mono"].includes(r)){let u;try{u=await o({deviceId:{exact:r},...zt})}catch(f){throw a(r,f),Object.assign(new Error(`camera unavailable: ${f.message}`),{code:er(n),skipped:n})}return oe(u.width,u.height)?c(u,"sbs"):(l(u),c(await o({deviceId:{exact:r},...Qi}),"mono"))}let p=new Set;if(r!=="mono"){let u=[];try{u=(await t.enumerateDevices()).filter(f=>f.kind==="videoinput"&&f.deviceId&&Ht(f.label))}catch{}for(let f of u){p.add(f.deviceId);let y=null;try{y=await o({deviceId:{exact:f.deviceId},...zt})}catch(v){a(f.label,v);continue}if(oe(y.width,y.height))return i("camera-sbs",{label:y.label,width:y.width,height:y.height,direct:!0}),c(y,"sbs");l(y)}}let m=null;try{m=await o(Qi)}catch(u){a("default",u)}if(r==="mono"&&m)return c(m,"mono");if(m&&oe(m.width,m.height))return c(m,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput")}catch{}h.sort((u,f)=>Number(Ht(f.label))-Number(Ht(u.label)));for(let u of h){if(!u.deviceId||m&&u.deviceId===m.deviceId||p.has(u.deviceId))continue;let f=null;try{f=await o({deviceId:{exact:u.deviceId},...zt})}catch(y){a(u.label,y);continue}if(oe(f.width,f.height))return l(m),i("camera-sbs",{label:f.label,width:f.width,height:f.height}),c(f,"sbs");l(f)}if(m)return r==="stereo"&&i("camera-no-stereo",{fallback:m.label}),c(m,"mono");let d=er(n);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:n})}async function ir(r={}){let e=r.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...is},video:!1})).getAudioTracks()[0]||null}catch(t){return(r.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Vt();Ut();var lr="http://displayxr.org/ns/stereo/1.0/",Ke="http://ns.adobe.com/xap/1.0/\0";function Qe(r={}){let e=i=>typeof i=="number"&&Number.isFinite(i)?i:null,t=r.layout==="sbs"||r.layout==="side-by-side"?"sbs":"mono";return{layout:t,columns:t==="sbs"?2:1,rows:1,convergencePx:e(r.convergencePx),baselineMm:e(r.baselineMm),horizontalFovDeg:e(r.horizontalFovDeg),rectified:r.rectified===!0?!0:r.rectified===!1?!1:null,eyeWidth:e(r.eyeWidth),eyeHeight:e(r.eyeHeight),software:typeof r.software=="string"&&r.software?r.software:null}}var ds=r=>String(r).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),de=r=>Math.round(r*1e3)/1e3;function cr(r){let e=Qe(r),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,n])=>` dxr:${i}="${ds(n)}"`).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="${lr}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function qt(r){if(typeof r!="string"||!r.includes(lr))return null;let e=o=>{let a=new RegExp(`\\bdxr:${o}="([^"]*)"`).exec(r);if(a)return a[1];let l=new RegExp(`<dxr:${o}>([^<]*)</dxr:${o}>`).exec(r);return l?l[1]:null},t=o=>{let a=e(o);return a===null||a===""||!Number.isFinite(+a)?null:+a},i=e("Rectified"),n=e("Layout"),s=e("Software");return Qe({layout:n==="side-by-side"||n==="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(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&amp;/g,"&")})}var Ze=r=>new TextEncoder().encode(r),Bt=r=>new TextDecoder().decode(r),hr=r=>r.length>4&&r[0]===255&&r[1]===216;function*dr(r){let e=2;for(;e+4<=r.length;){if(r[e]!==255)return;let t=r[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=r[e+2]<<8|r[e+3];if(i<2||e+2+i>r.length)return;yield{marker:t,start:e,end:e+2+i,data:r.subarray(e+4,e+2+i)},e+=2+i}}function ur(r,e){if(r.length<e.length)return!1;for(let t=0;t<e.length;t++)if(r[t]!==e.charCodeAt(t))return!1;return!0}function fr(r,e){if(!hr(r))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Ze(Ke),...Ze(e)]),i=t.length+2;if(i>65535)throw new RangeError("jpegWithXmp: XMP packet too large for one APP1 segment");let n=new Uint8Array(4+t.length);n[0]=255,n[1]=225,n[2]=i>>8,n[3]=i&255,n.set(t,4);let s=2,o=null;for(let p of dr(r)){if(p.marker===225&&ur(p.data,Ke)){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(r.length-(l-a)+n.length);return c.set(r.subarray(0,a),0),c.set(n,a),c.set(r.subarray(l),a+n.length),c}function Xt(r){if(!hr(r))return null;for(let e of dr(r))if(e.marker===225&&ur(e.data,Ke))return Bt(e.data.subarray(Ke.length));return null}var pr=r=>qt(Xt(r)),$={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},us=r=>r.length>4&&r[0]===26&&r[1]===69&&r[2]===223&&r[3]===163;function mr(r){let e=[];for(let t=r;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function gr(r,e=0){let t=e;if(!t)for(t=1;t<8&&r>2**(7*t)-2;t++);let i=new Array(t).fill(0),n=r;for(let s=t-1;s>=1;s--)i[s]=n%256,n=Math.floor(n/256);return i[0]=128>>t-1|n,i}function Gt(r,e){let t=r[e],i=t>=128?1:t>=64?2:t>=32?3:t>=16?4:0;if(!i||e+i>r.length)return null;let n=0;for(let s=0;s<i;s++)n=n*256+r[e+s];return{id:n,width:i}}function Le(r,e){let t=r[e],i=1;for(;i<=8&&!(t&128>>i-1);)i++;if(i>8||e+i>r.length)return null;let n=t&255>>i,s=n===127>>i-1;for(let o=1;o<i;o++)n=n*256+r[e+o],r[e+o]!==255&&(s=!1);return{size:n,width:i,unknown:s}}function he(r,e){return[...mr(r),...gr(e.length),...e]}function fs(r){let e=[];for(let[i,n]of Object.entries(r))n!=null&&e.push(...he($.SimpleTag,[...he($.TagName,[...Ze(String(i))]),...he($.TagString,[...Ze(String(n))])]));let t=he($.Tag,[...he($.Targets,[]),...e]);return new Uint8Array(he($.Tags,t))}function _r(r){let e=Qe(r);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 ps(r){if(!r||!("DXR_LAYOUT"in r))return null;let e=t=>r[t]===void 0||r[t]===""||!Number.isFinite(+r[t])?null:+r[t];return Qe({layout:r.DXR_LAYOUT==="side-by-side"?"sbs":"mono",convergencePx:e("DXR_CONVERGENCE_PX"),baselineMm:e("DXR_BASELINE_MM"),horizontalFovDeg:e("DXR_HFOV_DEG"),rectified:r.DXR_RECTIFIED===void 0?null:r.DXR_RECTIFIED==="true",eyeWidth:e("DXR_EYE_WIDTH"),eyeHeight:e("DXR_EYE_HEIGHT"),software:r.DXR_SOFTWARE??null})}function yr(r){if(!us(r))return null;let e=Le(r,4);if(!e)return null;let t=4+e.width+e.size;for(;t<r.length;){let i=Gt(r,t);if(!i)return null;let n=Le(r,t+i.width);if(!n)return null;let s=t+i.width+n.width;if(i.id===$.Segment)return{sizeAt:t+i.width,sizeWidth:n.width,unknown:n.unknown,dataStart:s,size:n.size};if(n.unknown)return null;t=s+n.size}return null}function vr(r,e){let t=yr(r);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=fs(e);if(t.unknown){let p=new Uint8Array(r.length+i.length);return p.set(r,0),p.set(i,r.length),p}let n=Math.min(r.length,t.dataStart+t.size),s=n-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=gr(s,o?t.sizeWidth:8),l=new Uint8Array(t.sizeAt+a.length+(n-t.dataStart)+i.length+(r.length-n));l.set(r.subarray(0,t.sizeAt),0),l.set(a,t.sizeAt);let c=t.sizeAt+a.length;return l.set(r.subarray(t.dataStart,n),c),c+=n-t.dataStart,l.set(i,c),c+=i.length,l.set(r.subarray(n),c),l}function wr(r,e,t){let i={},n=(s,o,a)=>{let l=s;for(;l<o;){let c=Gt(r,l);if(!c)return;let p=Le(r,l+c.width);if(!p||p.unknown)return;let m=l+c.width+p.width;a(c.id,m,Math.min(o,m+p.size)),l=m+p.size}};return n(e,t,(s,o,a)=>{s===$.Tag&&n(o,a,(l,c,p)=>{if(l!==$.SimpleTag)return;let m=null,h=null;n(c,p,(d,u,f)=>{d===$.TagName?m=Bt(r.subarray(u,f)):d===$.TagString&&(h=Bt(r.subarray(u,f)))}),m!==null&&(i[m]=h??"")})}),i}function ms(r){let e=yr(r);if(!e)return null;let t=e.unknown?r.length:Math.min(r.length,e.dataStart+e.size),i=null,n=e.dataStart;for(;n<t;){let s=Gt(r,n);if(!s)break;let o=Le(r,n+s.width);if(!o)break;let a=n+s.width+o.width;if(s.id===$.Tags&&!o.unknown&&(i={...i||{},...wr(r,a,Math.min(t,a+o.size))}),o.unknown){i=i||gs(r,t);break}n=a+o.size}return i}function gs(r,e){let t=mr($.Tags);for(let i=e-t.length-1;i>=0;i--){if(r[i]!==t[0]||r[i+1]!==t[1]||r[i+2]!==t[2]||r[i+3]!==t[3])continue;let n=Le(r,i+4);if(n&&!n.unknown&&i+4+n.width+n.size===e)return wr(r,i+4+n.width,e)}return null}var br=r=>ps(ms(r));var ee="[inline3d/camera]",zr="inline3d-camera/1",vs=200,ws=240,bs=66,xs=4e3,Ss=4,Ms=1500,Es=2e4,Cs=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],tt=()=>typeof document<"u"&&document&&typeof document.createElement=="function",jr=()=>{let r=new Date,e=t=>String(t).padStart(2,"0");return`${r.getFullYear()}${e(r.getMonth()+1)}${e(r.getDate())}-${e(r.getHours())}${e(r.getMinutes())}${e(r.getSeconds())}`},Rs=r=>/jpe?g/.test(r)?"jpg":/png/.test(r)?"png":/webp/.test(r)?"webp":/mp4/.test(r)?"mp4":/webm/.test(r)?"webm":"bin";function it(r,e,t){return`${String(r||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${Rs(t)}`}var Y=(r,e,t={})=>Object.assign(new Error(`${ee} ${r}`),{code:e,...t});function Nr(r,e=xs){return r?(r.readyState||0)>=2&&r.videoWidth?Promise.resolve():new Promise((t,i)=>{let n=!1,s=()=>{n||(r.readyState||0)<2||!r.videoWidth||(n=!0,clearTimeout(o),r.removeEventListener("loadeddata",s),r.removeEventListener("playing",s),r.removeEventListener("resize",s),t())},o=setTimeout(()=>{n||(n=!0,i(Y("the camera delivered no frame in time","no-frame")))},e);r.addEventListener("loadeddata",s),r.addEventListener("playing",s),r.addEventListener("resize",s),r.play?.().catch(()=>{})}):Promise.reject(Y("no video element (no document?)","no-frame"))}function Hr(r,e,t=ws){let i=r.videoWidth,n=r.videoHeight;if(!i||!n||(r.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(n*s));(e.width!==o||e.height!==a)&&(e.width=o,e.height=a);let l=e.getContext("2d",{willReadFrequently:!0});try{return l.drawImage(r,0,0,o,a),{img:Ge(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var Qt=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,tt()&&(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 n of this.stream.getVideoTracks())n.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(`${ee} 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(n){console.error(`${ee} '${e}' listener threw`,n)}}_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||!tt())return null;try{await Nr(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=Hr(this.video,this._scratch);if(!e)return null;let t=Te().measure(e.img,e.w,e.h,0);return t?t.d/e.scale:null}_meta(e,t=this.width,i=this.height){let n=this.stereo;return{layout:this.format,convergencePx:e,baselineMm:n?n.baselineMm:null,horizontalFovDeg:n?n.horizontalFovDeg:null,rectified:n?n.rectified:null,eyeWidth:this.format==="sbs"?t/2:t,eyeHeight:i,software:zr}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:n}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(!this.video||!tt())throw Y("capturePhoto needs a document","no-frame");await Nr(this.video);let s=this.video.videoWidth,o=this.video.videoHeight,a=typeof n=="number"&&Number.isFinite(n)?n: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,u)=>l.toBlob(f=>f?d(f):u(Y("toBlob produced nothing","encode-failed")),e,t)),p=this._meta(a,s,o),m=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(m=cr(p),c=new Blob([fr(new Uint8Array(await c.arrayBuffer()),m)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:it(i||`photo-${jr()}`,this.format,c.type||e),xmp:m};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:n,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(typeof MediaRecorder!="function")throw Y("MediaRecorder is not available here","unsupported");let l=e||Cs.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw Y(`${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 m=new MediaStream(c),h={...l?{mimeType:l}:{},...n?{videoBitsPerSecond:n}:{}},d=new MediaRecorder(m,h),u=[];d.ondataavailable=g=>g.data&&g.data.size&&u.push(g.data);let f=null,y=[],v=null,b=0,k=!!t&&this.format==="sbs"&&tt()&&this.video;if(k){v=document.createElement("canvas");let g=()=>{b=requestAnimationFrame(g);let _=this.video,M=_.videoWidth,O=_.videoHeight;!M||!O||(_.readyState||0)<2||((v.width!==M/2||v.height!==O)&&(v.width=M/2,v.height=O),v.getContext("2d").drawImage(_,0,0,M/2,O,0,0,M/2,O))};g();let w=v.captureStream(a);for(let _ of p)w.addTrack(_);f=new MediaRecorder(w,h),f.ondataavailable=_=>_.data&&_.data.size&&y.push(_.data)}let x=performance.now(),P=[],C=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&P.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&P.push(g)),d.start(s),f?.start(s),this.log("record-start",{mimeType:l,mono:k,audio:p.length});let D=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),I=o||`clip-${jr()}`,A=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(C),b&&cancelAnimationFrame(b);let[g,w]=await Promise.all([D(d,u),D(f,y)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",M=[...P].sort((me,U)=>me-U),O=M.length?M[Math.floor(M.length/2)]:null,S=A._meta(O),F=/webm|matroska/.test(_),H=async(me,U)=>{let Z=new Blob(me,{type:_});if(F&&Z.size)try{Z=new Blob([vr(new Uint8Array(await Z.arrayBuffer()),_r({...S,layout:U}))],{type:_})}catch(gi){A.log("record-tag-failed",{message:String(gi&&gi.message)})}return Z},R=await H(g,A.format),W={blob:R,type:_,layout:A.format,durationMs:Math.round(performance.now()-x),convergencePx:O,stereo:A.stereo,suggestedName:it(I,A.format,_),tagged:F&&R.size>0};return f&&(W.mono=await H(w,"mono"),W.monoSuggestedName=it(I,"mono",_)),A.log("record-stop",{bytes:R.size,mono:W.mono?W.mono.size:null,ms:W.durationMs,convergencePx:O,name:W.suggestedName}),W}}}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 ti(r={}){let e=typeof r=="string"||r&&typeof r.getVideoTracks=="function"?{prefer:r}:r||{},t=e.prefer===void 0||e.prefer===null?"auto":e.prefer,i=typeof e.log=="function"?e.log:e.debug?(a,l)=>console.log(`${ee} ${a} ${JSON.stringify(l)}`):null,n=e.calibration&&typeof e.calibration=="object"?{...e.calibration}:{};n.horizontalFovDeg>0&&!(n.hfovDeg>0)&&(n.hfovDeg=n.horizontalFovDeg),delete n.horizontalFovDeg;let s=await tr(t,{format:e.format,calibration:n,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 Qt(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 rt=r=>!!r&&typeof r=="object"&&typeof r.capturePhoto=="function"&&typeof r.record=="function"&&r.stream&&typeof r.stream.getVideoTracks=="function";function ks(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function ii(r,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${ee} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!rt(t))throw new TypeError(`${ee} addCameraView: cam must be a StereoCamera from openCamera()`);let n=new ei(r,e,t,i);return t._views?.add(n),n}var ei=class{constructor(e,t,i,n){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=n.mirror===void 0?!0:!!n.mirror,this.aspect=typeof n.aspect=="number"&&n.aspect>.3&&n.aspect<4?n.aspect:16/9,this.autoConverge=!!n.autoConverge,this.conv=xe(),this.conv.depth=0,this.setDepth(n.depth),this.route=null,this.handle=null,this.fallbackReason=null,this._fw=null,this._onRouteChange=typeof n.onRouteChange=="function"?n.onRouteChange:null,this._layerFails=0,this._layerTimer=0,this.buffer=null,this.removed=!1,this._raf=0,this._loop=n._loop!==!1,this._autoAt=0,this._track=Je(),this._focus=Te(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=Ye(n.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(Zt(),Kt)).then(s=>{this.removed||(this.cursor=new s.PairCursor(this.canvas,this._cursorOpt))}),this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}weaveState(){return{route:this.route,woven:this.woven,reason:this.fallbackReason,firstWoven:this.route==="woven-sbs"?this._fw?{...this._fw}:"pending":null,layerRetries:this._layerFails}}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;e&&this.fallbackReason&&(this.fallbackReason=null,clearTimeout(this._layerTimer),this._layerTimer=0);let i=this.cam,n=i.state==="live"&&i.video,o=i.format==="sbs"&&n&&this.wall&&this.wall.supported&&!this.fallbackReason?"woven-sbs":i.format==="sbs"?"flat-left":"flat";if(!e&&o===this.route)return;let a=this.route;this._unregister(),this.route=o,o==="woven-sbs"&&this._registerWoven(),o!==a&&this._routeChanged()}_registerWoven(){this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven();let e=this.wall.addImage(this.canvas,this.buffer);this.handle=e,this._fw=null;let t=e&&e.firstWoven;!t||typeof t.then!="function"||t.then(i=>{this.handle!==e||this.removed||!i||(this._fw={woven:!!i.woven,confirmed:!!i.confirmed,reason:i.reason||null,ms:i.ms},this.cam.log?.("view-first-woven",{woven:!!i.woven,reason:i.reason||null}),i.woven?(this._layerFails=0,this._routeChanged()):i.reason!=="removed"&&this._layerLost(i.reason||"layer-failed"))})}_layerLost(e){if(this.fallbackReason=e,this._reroute(!1),e!=="layer-failed"||this._layerFails>=Ss)return;let t=Math.min(Es,Ms*Math.pow(2,this._layerFails++));this.cam.log?.("view-layer-retry",{attempt:this._layerFails,inMs:t}),clearTimeout(this._layerTimer),this._layerTimer=setTimeout(()=>{this._layerTimer=0,!(this.removed||this.fallbackReason!==e)&&this._reroute(!0)},t)}_routeChanged(){if(this._onRouteChange)try{this._onRouteChange(this.route,this.weaveState())}catch(e){console.error(`${ee} onRouteChange threw`,e)}}_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(this.cursor?.idle(),!ks(this.canvas))return;let t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2)return;let n=this.canvas.getContext("2d"),s=this.route==="flat-left"?t/2:t,o=V(s,i,this.canvas.width/this.canvas.height,0,0);n.save(),this.mirror&&(n.translate(this.canvas.width,0),n.scale(-1,1)),n.drawImage(e,o.sx,o.sy,o.sw,o.sh,0,0,this.canvas.width,this.canvas.height),n.restore()}_paintWoven(){let e=this.cam.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.buffer)return;let n=t/2,s=this.aspect,{w:o,h:a}=be(n,i,s),l=this.buffer;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.autoConverge||c)&&this._sample(e,c);let p=this.conv.step(n),m=l.getContext("2d");if(this.mirror)for(let h of ae(t,i)){let d=h.src==="L"?0:1,u=V(n,i,s,p,d),f=h.dx===0?0:o;m.save(),m.translate(f+o,0),m.scale(-1,1),m.drawImage(e,h.sx+u.sx,u.sy,u.sw,u.sh,0,0,o,a),m.restore()}else for(let h of[0,1]){let d=V(n,i,s,p,h);m.drawImage(e,h*n+d.sx,d.sy,d.sw,d.sh,h*o,0,o,a)}if(this.cursor){let h={rL:V(n,i,s,p,0),rR:V(n,i,s,p,1),outW:o,outH:a,mirror:this.mirror,handle:this.handle};this.cursor.draw(m,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?bs:vs))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let n=Hr(e,this._scratch);if(n&&(this._luma=n),!this.autoConverge)return;let s=n?this._focus.measure(n.img,n.w,n.h,i):null,o=this._track.push(s?s.d/n.scale:null);this.conv.measuredPx=o,this.disparityPx=o}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,clearTimeout(this._layerTimer),this._layerTimer=0,this._unregister(),this.cursor?.dispose(),this.cursor=null,this.cam._views?.delete(this))}};var Vr=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],Ur=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Ts=[1,0],ri=10;function Br(r){let e=(16*r+128)*r+64;if(r>=2){let t=Math.floor(r/7)+2;e-=(25*t-10)*t-55,r>=7&&(e-=36)}return e}var $r=(r,e)=>Math.floor(Br(r)/8)-Vr[e][r]*Ur[e][r];function ni(r,e){let t=0;for(let i=7;i>=0;i--)t=t<<1^(t>>>7)*285,t^=(e>>>i&1)*r;return t}function Ls(r){let e=new Array(r-1).fill(0);e.push(1);let t=1;for(let i=0;i<r;i++){for(let n=0;n<e.length;n++)e[n]=ni(e[n],t),n+1<e.length&&(e[n]^=e[n+1]);t=ni(t,2)}return e}function Ds(r,e){let t=e.map(()=>0);for(let i of r){let n=i^t.shift();t.push(0),e.forEach((s,o)=>t[o]^=ni(s,n))}return t}function si(r,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(r))],n=1;for(;n<=ri&&!(4+(n<=9?8:16)+i.length*8<=$r(n,t)*8);n++);if(n>ri)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${ri} code`);let s=[],o=(g,w)=>{for(let _=w-1;_>=0;_--)s.push(g>>>_&1)};o(4,4),o(i.length,n<=9?8:16);for(let g of i)o(g,8);let a=$r(n,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=Ur[t][n],p=Vr[t][n],m=Math.floor(Br(n)/8),h=c-m%c,d=Math.floor(m/c),u=Ls(p),f=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-p+(g<h?0:1));w+=_.length;let M=Ds(_,u);g<h&&_.push(0),f.push(_.concat(M))}let y=[];for(let g=0;g<f[0].length;g++)for(let w=0;w<f.length;w++)(g!==d-p||w>=h)&&y.push(f[w][g]);let v=n*4+17,b=Array.from({length:v},()=>new Array(v).fill(!1)),k=Array.from({length:v},()=>new Array(v).fill(!1)),x=(g,w,_)=>{b[w][g]=_,k[w][g]=!0};for(let g=0;g<v;g++)x(6,g,g%2===0),x(g,6,g%2===0);let P=(g,w)=>{for(let _=-4;_<=4;_++)for(let M=-4;M<=4;M++){let O=Math.max(Math.abs(M),Math.abs(_)),S=g+M,F=w+_;S>=0&&S<v&&F>=0&&F<v&&x(S,F,O!==2&&O!==4)}};P(3,3),P(v-4,3),P(3,v-4);let C=[];if(n>1){let g=Math.floor(n/7)+2,w=Math.ceil((n*4+4)/(g*2-2))*2;C.push(6);for(let _=v-7;C.length<g;_-=w)C.splice(1,0,_)}for(let g=0;g<C.length;g++)for(let w=0;w<C.length;w++)if(!(g===0&&w===0||g===0&&w===C.length-1||g===C.length-1&&w===0))for(let _=-2;_<=2;_++)for(let M=-2;M<=2;M++)x(C[g]+M,C[w]+_,Math.max(Math.abs(M),Math.abs(_))!==1);let D=g=>{let w=Ts[t]<<3|g,_=w;for(let S=0;S<10;S++)_=_<<1^(_>>>9)*1335;let M=(w<<10|_)^21522,O=S=>(M>>>S&1)!==0;for(let S=0;S<=5;S++)x(8,S,O(S));x(8,7,O(6)),x(8,8,O(7)),x(7,8,O(8));for(let S=9;S<15;S++)x(14-S,8,O(S));for(let S=0;S<8;S++)x(v-1-S,8,O(S));for(let S=8;S<15;S++)x(8,v-15+S,O(S));x(8,v-8,!0)};if(D(0),n>=7){let g=n;for(let _=0;_<12;_++)g=g<<1^(g>>>11)*7973;let w=n<<12|g;for(let _=0;_<18;_++){let M=(w>>>_&1)!==0,O=v-11+_%3,S=Math.floor(_/3);x(O,S,M),x(S,O,M)}}let I=0;for(let g=v-1;g>=1;g-=2){g===6&&(g=5);for(let w=0;w<v;w++)for(let _=0;_<2;_++){let M=g-_,S=(g+1&2)===0?v-1-w:w;!k[S][M]&&I<y.length*8&&(b[S][M]=(y[I>>>3]>>>7-(I&7)&1)!==0,I++)}}let A=g=>{for(let w=0;w<v;w++)for(let _=0;_<v;_++){if(k[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][_])}},T=Number.isInteger(e.mask)?e.mask:-1;if(T<0){let g=1/0;for(let w=0;w<8;w++){A(w),D(w);let _=As(b,v);_<g&&(g=_,T=w),A(w)}}return A(T),D(T),{version:n,size:v,mask:T,modules:b}}function As(r,e){let t=0,i=[];for(let o=0;o<e;o++)i.push(r[o]);for(let o=0;o<e;o++)i.push(r.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 n=0;for(let o=0;o<e;o++)for(let a=0;a<e;a++)if(r[o][a]&&n++,a<e-1&&o<e-1){let l=r[o][a];l===r[o][a+1]&&l===r[o+1][a]&&l===r[o+1][a+1]&&(t+=3)}let s=e*e;return t+=Math.floor(Math.abs(n*20-s*10)/s)*10,t}function qr(r,e,{px:t=4,dark:i="#000",light:n="#fff",ecl:s="M"}={}){let o=si(e,{ecl:s}),a=o.size+8;r.width=r.height=a*t;let l=r.getContext("2d");l.fillStyle=n,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 K(r,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=r,t}async function oi(r){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(String(r)));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}var nt="wss://signal.displayxr.org",Xr=Object.freeze([nt,"wss://dxr-signal.displayxr.workers.dev"]),Gr=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function ue(r=nt,e={}){if(!r||typeof r!="string")throw K("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(r),n=e.WebSocket||globalThis.WebSocket,s=e.pingMs||2e4,o=Array.isArray(e.aliases)?e.aliases.filter(c=>typeof c=="string"&&c).map(t):Xr.includes(i)?[...Xr]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,p){let h=`k=${await oi(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=A=>`${a[A]}/v1/connect?${h}`,u=null,f=!1,y=0,v=null,b=new Set,k=[],x=A=>P(A,a.length),P=(A,T)=>new Promise((g,w)=>{let _=!1,M=!1,O=!1,S=new n(d(l));u=S;let F=H=>{if(!_){_=!0;try{S.close()}catch{}w(H)}};S.onopen=()=>{O=!0,S.send(JSON.stringify({t:"join",v:1,room:c,id:p.id,max:p.maxPeers}))},S.onmessage=H=>{let R;try{R=JSON.parse(typeof H.data=="string"?H.data:String(H.data))}catch{return}switch(R.t){case"welcome":{y=0;let W=Array.isArray(R.peers)?R.peers.filter(U=>typeof U=="string"):[];clearInterval(v),v=setInterval(()=>C({t:"ping"}),s);let me=k;k=[];for(let U of me)C(U);if(A){let U=new Set(W);for(let Z of b)U.has(Z)||p.onPeerLeft?.(Z);b=U,p.onReconnect?.(W)}else b=new Set(W);_=!0,M=!0,g({id:R.id,peers:W,iceServers:Array.isArray(R.iceServers)?R.iceServers:void 0,max:R.max,tier:R.tier==="key"?"key":"anon",key:typeof R.key=="string"?R.key:void 0,turn:R.turn&&typeof R.turn=="object"?R.turn:void 0});break}case"full":f=!0,F(K("room-full",`this call is full (${R.max} participants)`));break;case"expired":{f=!0,clearInterval(v);let W=K("expired","this room has reached its lifetime on the signalling server");_?p.onDisconnect?.(W):F(W);break}case"error":if(!_&&Gr.includes(R.code))f=!0,F(K(R.code,R.message||R.code));else if(!_&&(R.code==="rate-limited"||R.code==="quota")){let W=K(R.code,R.message||R.code);W.retryMs=R.retryMs>0?R.retryMs:0,F(W)}else!_&&R.code==="id-taken"&&F(K("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof R.id=="string"&&!b.has(R.id)&&(b.add(R.id),p.onPeerJoined?.(R.id));break;case"peer-left":typeof R.id=="string"&&(b.delete(R.id),p.onPeerLeft?.(R.id));break;case"signal":typeof R.from=="string"&&p.onSignal?.(R.from,R.data);break}},S.onerror=()=>{if(!O&&!_&&T>1){_=!0,l=(l+1)%a.length,P(A,T-1).then(g,w);return}F(K("signaling-unreachable",`cannot reach ${a[l]}`))},S.onclose=()=>{clearInterval(v),F(K("signaling-closed","signalling closed before joining")),M&&!f&&u===S&&D()}}),C=A=>{u&&u.readyState===1?u.send(JSON.stringify(A)):f||k.push(A)},D=()=>{p.onDisconnect?.();let A=()=>{f||x(!0).catch(T=>{if(f||T&&(T.code==="room-full"||Gr.includes(T.code))){p.onDisconnect?.(T);return}setTimeout(A,Math.max(q(y++,{baseMs:500,maxMs:15e3}),T&&T.retryMs||0))})};setTimeout(A,q(y++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(A,T)=>C({t:"signal",to:A,data:T}),leave:()=>{if(!f){f=!0,clearInterval(v);try{u&&u.readyState===1&&u.send(JSON.stringify({t:"leave"})),u&&u.close(1e3,"leave")}catch{}}}}}}}var ai=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),Yr=r=>typeof r=="string"&&ai[r.toLowerCase()]||r,Kr=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 Zr(r){let e={...De,...r&&typeof r=="object"?r:{}};return(t,i)=>{let n=typeof e[t]=="string"?e[t]:De[t]||t;if(i)for(let[s,o]of Object.entries(i))n=n.split(`{${s}}`).join(String(o));return n}}var Jr="dxr-call-style",Is=`
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 or=Object.defineProperty;var Ae=(n,e)=>()=>(n&&(e=n(n=0)),e);var ar=(n,e)=>{
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 Kn(n=document){if(n.getElementById(Xn))return;let e=n.createElement("style");e.id=Xn,e.textContent=As,(n.head||n.documentElement).appendChild(e)}var te=n=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${n}"/></svg>`,X={mic:te("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:te("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:te("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:te("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:te("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:te("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:te("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 j=(n,e)=>n&&n.classList.toggle("dxr-call-hidden",!e);Ut();var Qn="[inline3d/call]",Os="https://github.com/DisplayXR/displayxr-browser",er=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"}),Zn=new Set;function Is(n){Zn.has(n)||(Zn.add(n),console.warn(`${Qn} option \`${n}\` is deprecated (removed in 1.31) \u2014 use ${er[n]}`))}function li(n={}){for(let y of Object.keys(er))n[y]!==void 0&&Is(y);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"&&!ce(l)){let y=Se(l);if(!y)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=y}let c=n.liftOptions&&typeof n.liftOptions=="object"?{...n.liftOptions}:null,f=c&&c.max!==void 0?c.max:n.maxLifted;c&&delete c.max;let m=e.accent!==void 0?e.accent:n.accent,h={};for(let[y,v]of Object.entries(Jn)){let b=y==="accent"?m:e[y];typeof b=="string"&&b?h[v]=y==="accent"?Gn(b):b:typeof b=="number"&&y==="radius"&&(h[v]=`${b}px`)}let d=t.base!==void 0?t.base:n.inviteBase,u=t.updateUrl!==void 0?t.updateUrl:n.updateUrl,p=i.browserUrl!==void 0?i.browserUrl:n.browserUrl;return{room:l,signaling:n.signaling||ue(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,cursor:Ye(n.cursor,"@displayxr/inline3d/call"),mono3D:ve(n.mono3D),maxPeers:ke(n.maxPeers===void 0?le:n.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+f)&&f!==null&&f!==void 0?Math.max(0,Math.min(le,Math.floor(+f))):le,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:u===void 0?s:!!u},landing:{browserUrl:typeof p=="string"?p:Os,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!n.debug,log:typeof n.log=="function"?n.log:n.debug?(y,v)=>console.log(`${Qn} ${y} ${JSON.stringify(v)}`):null,_liftImporter:typeof n._liftImporter=="function"?n._liftImporter:void 0}}var Uo=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 hi="dxr-call:",Ps=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],ci="[inline3d/call] <dxr-call>",fe=n=>n!=null&&!/^(false|0|off|no)$/i.test(String(n).trim()),tr=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},z=n=>n==null||String(n).trim()===""?void 0:String(n).trim();function di(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",z(e("room")));let r=z(e("signaling"));r&&(t.signaling=ue(r,z(e("key"))?{key:z(e("key"))}:{})),i("key",z(e("key"))),i("camera",z(e("camera"))),i("layout",z(e("layout"))),i("maxPeers",tr(e("max-peers")));let s=z(e("ui"));fe(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),fe(e("auto-join"))&&(t.autoJoin=!0);let o=z(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),fe(e("no-audio"))&&(t.audio=!1),fe(e("no-self-view"))&&(t.selfView=!1),fe(e("no-auto-converge"))&&(t.autoConverge=!1),z(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:z(e("accent")),tileAspect:tr(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),z(e("invite-base"))&&(t.invite={base:z(e("invite-base"))}),z(e("browser-url"))&&(t.landing={browserUrl:z(e("browser-url"))}),fe(e("debug"))&&(t.debug=!0),t}var Fs=typeof HTMLElement=="function"?HTMLElement:class{},pe=class n extends Fs{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={...di(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||n.mount||ui;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=Ps.map(s=>r.on(s,o=>this._dispatch(s,o))),this._off.push(r.on("error",s=>console.warn(`${ci} ${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(`${ci} 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(hi+e,{detail:t,bubbles:!0,composed:!0}))}};function st(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(`${ci} <${n}> is already defined by another class; leaving it`),!1):(e.define(n,pe),!0)}var G="[inline3d/call]",Ws=2e3,js=2500,Ns=500,fi=.02,zs=4,Hs=2,$s=200,ir=240,Vs=66,Us=new Set(["I420","I420A","I422","I444","NV12"]);async function sr(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=li(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 pi(n,e,i);return await r._init(),r.handle}async function ui(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 Ne(i.wallOptions);return sr(r,n,i)}var pi=class{constructor(e,t,i){this.o=i,this.t=Yn(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=Gi(),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=Ft(Dt),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=ht(),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=nt(e)?e:null;try{if(s=a||await ti({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 nn({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 f=new MediaStream([c,l].filter(Boolean)),m=this.local;return this.local={stream:f,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!==m?.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}),m&&m.owned&&m.cam&&m.cam!==s&&m.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return It({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=At(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",Ue(location.href,this.room))}catch{}this._setState("joining");let e=new Ce({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 ot(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 ot(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()},js))}_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=Ot(t);if(r)return i.setHello(r);let s=Pt(t);if(s)return i.setHint(s);let o=Yi(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return Ue(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=Pt({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=Nt(),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 Ne()}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)},q(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=lt(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(r=>(this.liftApi=r,r.lift?(this.liftPool=dt({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),Ns)}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 f={};c.forEach(d=>{d.type==="codec"&&(f[d.id]=d.mimeType)});let m={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 u=a._prevIn;m.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:f[d.codecId]||null,kbps:u?Math.round((d.bytesReceived-u.bytes)*8/(d.timestamp-u.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 u=a._prevOut;m.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:f[d.codecId]||null,kbps:u?Math.round((d.bytesSent-u.bytes)*8/(d.timestamp-u.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(m.in||m.out)&&(a.quality=m,this.emit("quality",{id:o,...m}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>fi||a.remote.speaking),h>fi&&(!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>fi;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;Kn(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||j(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new mi(this,i.selfSlot):j(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"),X.mic,()=>this.mute()),e.cam=i(t("cameraOff"),X.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"),X.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),X.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?X.micOff:X.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?X.camOff:X.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{Un(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),j(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),j(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,f]of this.tiles)f.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){j(a,!0),a.replaceChildren();let c=this.local,f=!!this.room,m=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(f?"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),u=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,p=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(f?"join":"start")});p.addEventListener("click",()=>this.join().catch(()=>{}));let y=E("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(y),y.addEventListener("change",()=>this.setCamera(y.value).catch(b=>this.error("camera-failed",b.message,b)));let v=!c||!c.videoTrack?E("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;v?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(E("h3",{text:m}),E("p",{text:u}),E("div",{class:"dxr-call-row"},[this.state==="full"?null:p,v,y]))}else this.state==="in-call"&&s===0?(j(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(j(a,!0),a.replaceChildren(E("p",{text:i("joining")}))):j(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),j(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:Lt,wire:Ve,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()),self:this.self?this.self.diag():null,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),j(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 Bs(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 nr(n,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Bs(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=V(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 ot=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=Je(),this.autoFocus=Te(),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.luma=null,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=Ft(Dt),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||j(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(Zt(),Kt)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return jt(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,cursor:this.cursor?this.cursor.last:null,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())},Ws)}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||"",j(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",X.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"}:Wt({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(),j(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(j(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++>=Hs)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},q(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++>=zs)return;let e=q(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(j(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.cursor?.idle(),this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||nr(this.canvas,this.video):nr(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);let c=!!(this.cursor&&this.cursor.hovering);(this.call.o.autoConverge||c)&&this._sampleDisparity(e,t,i,c);let f=this.conv.step(r),m=l.getContext("2d"),h=[];for(let d of[0,1]){let u=h[d]=V(r,i,s,f,d);m.drawImage(e,d*r+u.sx,u.sy,u.sw,u.sh,d*o,0,o,a)}this.cursor&&this.cursor.draw(m,this.luma,{rL:h[0],rR:h[1],outW:o,outH:a},performance.now()/1e3)}_sampleDisparity(e,t,i,r=!1){let s=performance.now();if(this.autoPending||s-this.autoAt<(r?Vs:$s))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&Us.has(h.format)){this.autoPending=!0;let d=this.autoGen,u=h.visibleRect?h.visibleRect.width:h.displayWidth,p=h.visibleRect?h.visibleRect.height:h.displayHeight,y=new Uint8Array(h.allocationSize());h.copyTo(y).then(v=>{if(d!==this.autoGen)return;let b=performance.now(),R=Math.max(1,Math.ceil(u/2/ir)),x=sn(y,v[0].offset,v[0].stride,u,p,R);this._applyMeasurement(x.img,x.w,x.h,x.w/u,s,performance.now()-b,"videoframe")}).catch(()=>{d===this.autoGen&&this._applyMeasurement(null,0,0,1,s,0,"videoframe")}).finally(()=>{h.close(),this.autoPending=!1});return}h&&h.close()}let o=Math.min(1,ir/(t/2)),a=Math.max(2,Math.round(t*o/2)*2),l=Math.max(2,Math.round(i*o));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let c=this.autoCanvas;(c.width!==a||c.height!==l)&&(c.width=a,c.height=l);let f=c.getContext("2d",{willReadFrequently:!0}),m=null;try{f.drawImage(e,0,0,a,l),m=Ge(f.getImageData(0,0,a,l).data,a*l)}catch{m=null}this._applyMeasurement(m,a,l,a/t,s,performance.now()-s,"canvas")}_applyMeasurement(e,t,i,r,s,o,a){if(this.destroyed||(e&&(this.luma={img:e,w:t,h:i,scale:r}),!this.call.o.autoConverge))return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,f=this.autoTrack.push(c?c.d/r:null);this.conv.measuredPx=f,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(f*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.luma=null,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,this.cursor?.dispose(),this.cursor=null,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()}},mi=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"):"",j(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=ii(r,this.canvas,i,{mirror:!0,autoConverge:!!this.call.o.autoConverge,cursor:this.call.o.cursor||void 0,aspect:this.call.o.tileAspect,onRouteChange:(s,o)=>{this.cam===i&&(this.call.log("self-route",{route:s,woven:o.woven,reason:o.reason}),this._badge())}})),this._badge()}_badge(){let e=this.call.t,t=!!(this.view&&this.view.woven);this.badge.replaceChildren(E("b",{text:`${e("you")} \xB7 ${e(t?"badge3D":"badge2D")}`})),this.badge.dataset.route=this.route||""}diag(){return this.view?this.view.weaveState():{route:null,woven:!1,reason:"no-camera",firstWoven:null,layerRetries:0}}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)}},qs="1.31",rr=new Set;function L(n,e,t){let i=()=>{rr.has(n)||(rr.add(n),console.warn(`${G} \`${n}\` is internal and leaves '@displayxr/inline3d/call' in ${qs} \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 la=L("normalizeCallOptions","js/call/options.js",li),ca=L("newRoomId","js/call/wire.js",At),ha=L("isValidRoomId","js/call/wire.js",ce),da=L("buildInviteLink","js/call/wire.js",Ue),ua=L("normalizeHello","js/call/wire.js",Ot),fa=L("makeHello","js/call/wire.js",It),pa=L("routeFor","js/call/wire.js",Wt),ma=L("badgeFor","js/call/wire.js",jt),ga=L("createLiveGate","js/call/wire.js",Nt),_a=L("convergenceShiftPx","js/camera/converge.js",ze),ya=L("lowPass","js/camera/converge.js",$e),va=L("clampShift","js/camera/converge.js",He),wa=L("eyeCropRect","js/camera/geometry.js",V),ba=L("mirrorSwapOps","js/camera/geometry.js",ae),xa=L("mirrorSwapPixels","js/camera/geometry.js",Tt),Sa=L("maxBitrateKbps","js/call/wire.js",Be),Ma=L("measureFocusDisparity","js/camera/disparity.js",$t),Ea=L("preferVideoCodecs","js/call/sdp.js",Ee),Ca=L("sortCodecCapabilities","js/call/sdp.js",qe),ka=L("VIDEO_CODEC_ORDER","js/call/sdp.js",Me),Ra=L("MeshTransport","js/call/transport.js",Ce),Ta=L("clampMaxPeers","js/call/transport.js",ke),La=L("qrEncode","js/call/qr.js",si),Da=L("roomKey","js/call/signaling.js",oi);var Aa=L("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:De.unreachable,cameraBusy:De.cameraBusy})),Oa=L("CALL_ACCENTS","js/call/ui.js",ai),Ia=L("normalizeMono3D","js/call/lift.js",ve),Pa=L("resolveLift","js/call/lift.js",lt),Fa=L("createLiftPool","js/call/lift.js",dt),Wa=L("createFrameWatch","js/call/lift.js",ht),ja=L("liftConvergenceFor","js/call/lift.js",ye),Na=L("liftPriorityFor","js/call/lift.js",Oe),za=L("setLiftPriority","js/call/lift.js",ct),Ha=L("defaultLiftSpecifier","js/call/lift.js",at),$a=L("LIFT_PRIORITY","js/call/lift.js",_e);st();_i(()=>new URL("./lift.js",import.meta.url).href);export{hi as CALL_EVENT_PREFIX,jn as CAMERA_SDK,rt as DXR_SIGNAL_DEFAULT,pe as DxrCallElement,sr as addCall,ii as addCameraView,di as attrsToOpts,Vi as createInline3D,st as defineCallElement,ue as dxrSignaling,Hi as inline3DAvailable,nt as isStereoCamera,ui as mountCall,ti as openCamera,Se as parseInviteLink,qt as parseStereoXmp,mn as readJpegStereoMeta,Xt as readJpegXmp,xn as readWebmStereoMeta,Ne as sharedInline3D,it as suggestedName};
86
+ `;function Qr(r=document){if(r.getElementById(Jr))return;let e=r.createElement("style");e.id=Jr,e.textContent=Is,(r.head||r.documentElement).appendChild(e)}var te=r=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${r}"/></svg>`,X={mic:te("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:te("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:te("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:te("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:te("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:te("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:te("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(r,e={},t=[]){let i=document.createElement(r);for(let[n,s]of Object.entries(e))s!=null&&(n==="class"?i.className=s:n==="html"?i.innerHTML=s:n==="text"?i.textContent=s:n.startsWith("on")&&typeof s=="function"?i.addEventListener(n.slice(2),s):n in i&&typeof s!="string"?i[n]=s:i.setAttribute(n,s));for(let n of[].concat(t))n&&i.appendChild(typeof n=="string"?document.createTextNode(n):n);return i}var j=(r,e)=>r&&r.classList.toggle("dxr-call-hidden",!e);Ut();var tn="[inline3d/call]",Fs="https://github.com/DisplayXR/displayxr-browser",rn=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"}),en=new Set;function Ws(r){en.has(r)||(en.add(r),console.warn(`${tn} option \`${r}\` is deprecated (removed in 1.31) \u2014 use ${rn[r]}`))}function li(r={}){for(let y of Object.keys(rn))r[y]!==void 0&&Ws(y);let e=r.theme&&typeof r.theme=="object"?r.theme:{},t=r.invite&&typeof r.invite=="object"?r.invite:{},i=r.landing&&typeof r.landing=="object"?r.landing:{},n=r.ui===void 0?!0:r.ui==="tiles"?"tiles":!!r.ui,s=n===!0,o=e.tileAspect!==void 0?e.tileAspect:r.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=r.room===void 0||r.room===null?"auto":r.room;if(l!=="auto"&&!ce(l)){let y=Se(l);if(!y)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=y}let c=r.liftOptions&&typeof r.liftOptions=="object"?{...r.liftOptions}:null,p=c&&c.max!==void 0?c.max:r.maxLifted;c&&delete c.max;let m=e.accent!==void 0?e.accent:r.accent,h={};for(let[y,v]of Object.entries(Kr)){let b=y==="accent"?m:e[y];typeof b=="string"&&b?h[v]=y==="accent"?Yr(b):b:typeof b=="number"&&y==="radius"&&(h[v]=`${b}px`)}let d=t.base!==void 0?t.base:r.inviteBase,u=t.updateUrl!==void 0?t.updateUrl:r.updateUrl,f=i.browserUrl!==void 0?i.browserUrl:r.browserUrl;return{room:l,signaling:r.signaling||ue(void 0,typeof r.key=="string"&&r.key?{key:r.key}:{}),iceServers:Array.isArray(r.iceServers)?r.iceServers:void 0,camera:r.camera===void 0?"auto":r.camera,format:r.format==="sbs"?"sbs":r.format==="mono"?"mono":void 0,calibration:r.calibration&&typeof r.calibration=="object"?{...r.calibration}:{},rectify:typeof r.rectify=="function"?r.rectify:null,audio:r.audio===void 0?!0:!!r.audio,autoConverge:r.autoConverge===void 0?!0:!!r.autoConverge,cursor:Ye(r.cursor,"@displayxr/inline3d/call"),mono3D:ve(r.mono3D),maxPeers:Re(r.maxPeers===void 0?le:r.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+p)&&p!==null&&p!==void 0?Math.max(0,Math.min(le,Math.floor(+p))):le,layout:r.layout==="speaker"?"speaker":r.layout==="none"?"none":"grid",ui:n,chrome:s,autoJoin:r.autoJoin===void 0?!s:!!r.autoJoin,selfView:r.selfView===void 0?!0:!!r.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:u===void 0?s:!!u},landing:{browserUrl:typeof f=="string"?f:Fs,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!r.debug,log:typeof r.log=="function"?r.log:r.debug?(y,v)=>console.log(`${tn} ${y} ${JSON.stringify(v)}`):null,_liftImporter:typeof r._liftImporter=="function"?r._liftImporter:void 0}}var Xo=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 hi="dxr-call:",js=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],ci="[inline3d/call] <dxr-call>",fe=r=>r!=null&&!/^(false|0|off|no)$/i.test(String(r).trim()),nn=r=>{if(r==null||String(r).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(r)),t=e?+e[1]/+e[2]:+r;return Number.isFinite(t)?t:void 0},z=r=>r==null||String(r).trim()===""?void 0:String(r).trim();function di(r){let e=typeof r=="function"?r:l=>r&&typeof r.getAttribute=="function"?r.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",z(e("room")));let n=z(e("signaling"));n&&(t.signaling=ue(n,z(e("key"))?{key:z(e("key"))}:{})),i("key",z(e("key"))),i("camera",z(e("camera"))),i("layout",z(e("layout"))),i("maxPeers",nn(e("max-peers")));let s=z(e("ui"));fe(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),fe(e("auto-join"))&&(t.autoJoin=!0);let o=z(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),fe(e("no-audio"))&&(t.audio=!1),fe(e("no-self-view"))&&(t.selfView=!1),fe(e("no-auto-converge"))&&(t.autoConverge=!1),z(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:z(e("accent")),tileAspect:nn(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),z(e("invite-base"))&&(t.invite={base:z(e("invite-base"))}),z(e("browser-url"))&&(t.landing={browserUrl:z(e("browser-url"))}),fe(e("debug"))&&(t.debug=!0),t}var Ns=typeof HTMLElement=="function"?HTMLElement:class{},pe=class r extends Ns{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={...di(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||r.mount||ui;this._pending=new Promise(n=>n(i(this,t))).then(n=>{if(this._pending=null,e!==this._gen)return n.leave(),null;if(this.call=n,this._off=js.map(s=>n.on(s,o=>this._dispatch(s,o))),this._off.push(n.on("error",s=>console.warn(`${ci} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:n}),n.state==="in-call"){this._dispatch("joined",{room:n.room,id:n.id});for(let s of n.peers)this._dispatch("peer",{id:s.id})}return n},n=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(n&&n.message||n),error:n||null}),console.warn(`${ci} mount failed: ${String(n&&n.message||n)}`),n}),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(hi+e,{detail:t,bubbles:!0,composed:!0}))}};function st(r="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(r);return t?(t!==pe&&console.warn(`${ci} <${r}> is already defined by another class; leaving it`),!1):(e.define(r,pe),!0)}var G="[inline3d/call]",zs=2e3,Hs=2500,$s=500,fi=.02,Vs=4,Us=2,Bs=200,sn=240,qs=66,Xs=new Set(["I420","I420A","I422","I444","NV12"]);async function ln(r,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=li(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 n=new pi(r,e,i);return await n._init(),n.handle}async function ui(r,e={}){if(!r||typeof r.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,n=t||await Ne(i.wallOptions);return ln(n,r,i)}var pi=class{constructor(e,t,i){this.o=i,this.t=Zr(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=Gi(),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=Ft(Dt),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=ht(),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 n of[...i])try{n(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 n=(h,d)=>this.log(h,d),s=null,o=null,a=rt(e)?e:null;try{if(s=a||await ti({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:n}),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 ir({log:n})),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)),m=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!==m?.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}),m&&m.owned&&m.cam&&m.cam!==s&&m.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return Pt({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=At(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",Ue(location.href,this.room))}catch{}this._setState("joining");let e=new Ce({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(i,n)=>this.log(i,n)});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,n)=>this._onPeerLeft(i,n),onStream:(i,n)=>this.tiles.get(i)?.setStream(n),onMessage:(i,n)=>this._onMessage(i,n),onPeerState:(i,n)=>{this.tiles.get(i)?.setConn(n),this.emit("state",{id:i,state:n})},onRefused:i=>this.log("refused-peer",{id:i}),onGhost:(i,n)=>this._onGhost(i,n),onSignalingState:(i,n)=>{this.log("signaling",{state:i}),i==="closed"&&n&&this.error(n.code||"signaling-closed",n.message,n)}})}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 ot(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 n=new ot(this,e);n.ghost=!0,this.tiles.set(e,n),n.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()},Hs))}_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 n=Ot(t);if(n)return i.setHello(n);let s=It(t);if(s)return i.setHint(s);let o=Yi(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return Ue(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,n=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",n.videoTrack,n.stream),await this.transport.setSendFormat(n.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==n.format&&this.log("send-format",{format:n.format}),{format:n.format,width:n.width,height:n.height,label:n.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=It({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=(...n)=>(i.pageClosed=!0,t.apply(e,n)),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=Nt(),n=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()-n)});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 Ne()}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)},q(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let n of this.tiles.values())n.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=(n,s)=>this.log(n,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=lt(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(n=>(this.liftApi=n,n.lift?(this.liftPool=dt({lift:n.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!n.caps&&n.capabilities&&Promise.resolve().then(()=>n.capabilities(i)).then(s=>{n.caps=s||null,this._refreshLobby()}).catch(()=>{})):n.reason==="import-failed"||n.reason==="no-lift-export"?this.liftMissing=!0:n.reason!=="off"&&console.info(`${G} mono\u21923D unavailable (${n.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),n))}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),$s)}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 m={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 u=a._prevIn;m.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:u?Math.round((d.bytesReceived-u.bytes)*8/(d.timestamp-u.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 u=a._prevOut;m.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:u?Math.round((d.bytesSent-u.bytes)*8/(d.timestamp-u.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(m.in||m.out)&&(a.quality=m,this.emit("quality",{id:o,...m}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>fi||a.remote.speaking),h>fi&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let n=t?t.id:null;n&&n!==this.speakerId?(this._challengeTicks=this._challenger===n?(this._challengeTicks||0)+1:1,this._challenger=n,this._challengeTicks>=2&&this._setSpeaker(n)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>fi;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 n=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(n-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${n}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;Qr(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[n,s]of Object.entries(this.o.cssVars))e.style.setProperty(n,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||j(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new mi(this,i.selfSlot):j(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(n,s,o,a="")=>E("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":n,title:n,html:s,onclick:o});e.mic=i(t("mute"),X.mic,()=>this.mute()),e.cam=i(t("cameraOff"),X.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"),X.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),X.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?X.micOff:X.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?X.camOff:X.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 n=this.inviteLink();if(!n)return;let s=this.t,o=E("input",{type:"text",readOnly:!0,value:n,"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(n),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{qr(l,n,{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,n=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",n),j(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),j(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(n){j(a,!0),a.replaceChildren();let c=this.local,p=!!this.room,m=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),u=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(p?"join":"start")});f.addEventListener("click",()=>this.join().catch(()=>{}));let y=E("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(y),y.addEventListener("change",()=>this.setCamera(y.value).catch(b=>this.error("camera-failed",b.message,b)));let v=!c||!c.videoTrack?E("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;v?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(E("h3",{text:m}),E("p",{text:u}),E("div",{class:"dxr-call-row"},[this.state==="full"?null:f,v,y]))}else this.state==="in-call"&&s===0?(j(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(j(a,!0),a.replaceChildren(E("p",{text:i("joining")}))):j(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),j(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:Lt,wire:Ve,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()),self:this.self?this.self.diag():null,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(n=>n.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((n,s)=>E("option",{value:n.deviceId,text:n.label||`Camera ${s+1}`}))),i&&(e.value=i),j(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)}},n={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(n))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 Gs(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function on(r,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Gs(r))return;let n=r.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=V(a,o,r.width/r.height,0,0);n.save(),i&&(n.translate(r.width,0),n.scale(-1,1)),n.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,r.width,r.height),n.restore()}var ot=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=Je(),this.autoFocus=Te(),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.luma=null,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=Ft(Dt),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||j(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(Zt(),Kt)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return jt(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,cursor:this.cursor?this.cursor.last:null,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())},zs)}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||"",j(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",X.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,n=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:Wt({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=`${n.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=n.route,n.route==="woven-sbs"?this._registerWoven():n.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:n.route,format:this.format,mono3d:n.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:n.route,mono3d:n.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),j(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(j(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 n=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>n(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++>=Us)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},q(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++>=Vs)return;let e=q(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(j(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.cursor?.idle(),this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||on(this.canvas,this.video):on(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 n=t/2,s=this.call.o.tileAspect,{w:o,h:a}=be(n,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.call.o.autoConverge||c)&&this._sampleDisparity(e,t,i,c);let p=this.conv.step(n),m=l.getContext("2d"),h=[];for(let d of[0,1]){let u=h[d]=V(n,i,s,p,d);m.drawImage(e,d*n+u.sx,u.sy,u.sw,u.sh,d*o,0,o,a)}this.cursor&&this.cursor.draw(m,this.luma,{rL:h[0],rR:h[1],outW:o,outH:a,handle:this.handle},performance.now()/1e3)}_sampleDisparity(e,t,i,n=!1){let s=performance.now();if(this.autoPending||s-this.autoAt<(n?qs:Bs))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&Xs.has(h.format)){this.autoPending=!0;let d=this.autoGen,u=h.visibleRect?h.visibleRect.width:h.displayWidth,f=h.visibleRect?h.visibleRect.height:h.displayHeight,y=new Uint8Array(h.allocationSize());h.copyTo(y).then(v=>{if(d!==this.autoGen)return;let b=performance.now(),k=Math.max(1,Math.ceil(u/2/sn)),x=nr(y,v[0].offset,v[0].stride,u,f,k);this._applyMeasurement(x.img,x.w,x.h,x.w/u,s,performance.now()-b,"videoframe")}).catch(()=>{d===this.autoGen&&this._applyMeasurement(null,0,0,1,s,0,"videoframe")}).finally(()=>{h.close(),this.autoPending=!1});return}h&&h.close()}let o=Math.min(1,sn/(t/2)),a=Math.max(2,Math.round(t*o/2)*2),l=Math.max(2,Math.round(i*o));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let c=this.autoCanvas;(c.width!==a||c.height!==l)&&(c.width=a,c.height=l);let p=c.getContext("2d",{willReadFrequently:!0}),m=null;try{p.drawImage(e,0,0,a,l),m=Ge(p.getImageData(0,0,a,l).data,a*l)}catch{m=null}this._applyMeasurement(m,a,l,a/t,s,performance.now()-s,"canvas")}_applyMeasurement(e,t,i,n,s,o,a){if(this.destroyed||(e&&(this.luma={img:e,w:t,h:i,scale:n}),!this.call.o.autoConverge))return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,p=this.autoTrack.push(c?c.d/n: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/n),y:Math.round(c.y/n)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.luma=null,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,this.cursor?.dispose(),this.cursor=null,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()}},mi=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"):"",j(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,n=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,n):(this.detach(),this.cam=i,this.view=ii(n,this.canvas,i,{mirror:!0,autoConverge:!!this.call.o.autoConverge,cursor:this.call.o.cursor||void 0,aspect:this.call.o.tileAspect,onRouteChange:(s,o)=>{this.cam===i&&(this.call.log("self-route",{route:s,woven:o.woven,reason:o.reason}),this._badge())}})),this._badge()}_badge(){let e=this.call.t,t=!!(this.view&&this.view.woven);this.badge.replaceChildren(E("b",{text:`${e("you")} \xB7 ${e(t?"badge3D":"badge2D")}`})),this.badge.dataset.route=this.route||""}diag(){return this.view?this.view.weaveState():{route:null,woven:!1,reason:"no-camera",firstWoven:null,layerRetries:0}}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)}},Js="1.31",an=new Set;function L(r,e,t){let i=()=>{an.has(r)||(an.add(r),console.warn(`${G} \`${r}\` is internal and leaves '@displayxr/inline3d/call' in ${Js} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(n,s,o){return i(),Reflect.apply(n,s,o)},construct(n,s){return i(),Reflect.construct(n,s)}}):t&&typeof t=="object"?new Proxy(t,{get(n,s,o){return typeof s=="string"&&i(),Reflect.get(n,s,o)}}):t}var da=L("normalizeCallOptions","js/call/options.js",li),ua=L("newRoomId","js/call/wire.js",At),fa=L("isValidRoomId","js/call/wire.js",ce),pa=L("buildInviteLink","js/call/wire.js",Ue),ma=L("normalizeHello","js/call/wire.js",Ot),ga=L("makeHello","js/call/wire.js",Pt),_a=L("routeFor","js/call/wire.js",Wt),ya=L("badgeFor","js/call/wire.js",jt),va=L("createLiveGate","js/call/wire.js",Nt),wa=L("convergenceShiftPx","js/camera/converge.js",ze),ba=L("lowPass","js/camera/converge.js",$e),xa=L("clampShift","js/camera/converge.js",He),Sa=L("eyeCropRect","js/camera/geometry.js",V),Ma=L("mirrorSwapOps","js/camera/geometry.js",ae),Ea=L("mirrorSwapPixels","js/camera/geometry.js",Tt),Ca=L("maxBitrateKbps","js/call/wire.js",Be),Ra=L("measureFocusDisparity","js/camera/disparity.js",$t),ka=L("preferVideoCodecs","js/call/sdp.js",Ee),Ta=L("sortCodecCapabilities","js/call/sdp.js",qe),La=L("VIDEO_CODEC_ORDER","js/call/sdp.js",Me),Da=L("MeshTransport","js/call/transport.js",Ce),Aa=L("clampMaxPeers","js/call/transport.js",Re),Oa=L("qrEncode","js/call/qr.js",si),Pa=L("roomKey","js/call/signaling.js",oi);var Ia=L("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:De.unreachable,cameraBusy:De.cameraBusy})),Fa=L("CALL_ACCENTS","js/call/ui.js",ai),Wa=L("normalizeMono3D","js/call/lift.js",ve),ja=L("resolveLift","js/call/lift.js",lt),Na=L("createLiftPool","js/call/lift.js",dt),za=L("createFrameWatch","js/call/lift.js",ht),Ha=L("liftConvergenceFor","js/call/lift.js",ye),$a=L("liftPriorityFor","js/call/lift.js",Oe),Va=L("setLiftPriority","js/call/lift.js",ct),Ua=L("defaultLiftSpecifier","js/call/lift.js",at),Ba=L("LIFT_PRIORITY","js/call/lift.js",_e);st();_i(()=>new URL("./lift.js",import.meta.url).href);export{hi as CALL_EVENT_PREFIX,zr as CAMERA_SDK,nt as DXR_SIGNAL_DEFAULT,pe as DxrCallElement,ln as addCall,ii as addCameraView,di as attrsToOpts,Vi as createInline3D,st as defineCallElement,ue as dxrSignaling,Hi as inline3DAvailable,rt as isStereoCamera,ui as mountCall,ti as openCamera,Se as parseInviteLink,qt as parseStereoXmp,pr as readJpegStereoMeta,Xt as readJpegXmp,br as readWebmStereoMeta,Ne as sharedInline3D,it as suggestedName};
@@ -25,8 +25,12 @@ import { matchBlock, MIN_NCC } from './disparity.js';
25
25
  export const PAIR_CURSOR_CSS_PX = 19;
26
26
  /** Arrow height as a fraction of the tile height when the tile's on-page size is unknown. */
27
27
  export const PAIR_CURSOR_HEIGHT = 0.06;
28
- /** Below this many output px in front of the glass the drawn arrow hands back to the OS cursor. */
29
- export const PAIR_CURSOR_SHOW_PX = 0.5;
28
+ /**
29
+ * Below this far in front of the glass (metres of on-screen disparity, ~0.3 mm = 0.005 of the eye
30
+ * baseline, the runtime's rule) the drawn arrow hands back to the OS cursor. Never under 0.5 px.
31
+ */
32
+ export const PAIR_CURSOR_SHOW_M = 0.0003;
33
+ export const PAIR_CURSOR_SHOW_MIN_PX = 0.5;
30
34
  /**
31
35
  * The standard pointer arrow, hotspot at the tip (0, 0), unit = its height, x right, y down: the
32
36
  * OS arrow's outline (a 19-px-tall Windows/macOS arrow, normalised).
@@ -34,8 +38,14 @@ export const PAIR_CURSOR_SHOW_PX = 0.5;
34
38
  export const PAIR_CURSOR_ARROW = Object.freeze([
35
39
  [0, 0], [0, 16 / 19], [4.2 / 19, 12.4 / 19], [6.9 / 19, 18.6 / 19], [9.5 / 19, 17.5 / 19], [6.8 / 19, 11.5 / 19], [11.7 / 19, 11.5 / 19],
36
40
  ]);
37
- /** How far in front of out-of-screen content the arrow floats, as a fraction of the eye width (crossed). */
38
- export const PAIR_CURSOR_MARGIN = 0.002;
41
+ /**
42
+ * How far in front of out-of-screen content the arrow floats: 2 mm of on-screen disparity — the
43
+ * runtime's 0.03 of the eye baseline (ADR-046 / runtime #1908), so a lifted tile's cursor and a
44
+ * stereo tile's sit the same way. Converted to buffer px through the tile's `displayMetrics()`.
45
+ */
46
+ export const PAIR_CURSOR_MARGIN_M = 0.002;
47
+ /** One CSS px in metres when the panel cannot say (the CSS reference pixel, 1/96 in). */
48
+ export const PAIR_CURSOR_CSS_PX_M = 0.0254 / 96;
39
49
  /** Comfort cap on how far in front the arrow comes, as a fraction of the eye width. */
40
50
  export const PAIR_CURSOR_CLAMP = 0.08;
41
51
 
@@ -85,10 +95,20 @@ export function pairFootprintDisparity(luma, geo, u, v, height, aspect) {
85
95
  * The arrow's target disparity: in front of content that comes OUT of the screen (its disparity
86
96
  * plus the margin, clamped), else the glass. Never behind the glass — the cursor does not go inside
87
97
  * the display.
98
+ * @param {number} marginPx the margin in output px (pairCursorScale × PAIR_CURSOR_MARGIN_M)
88
99
  */
89
- export function pairCursorTarget(contentPx, outW) {
100
+ export function pairCursorTarget(contentPx, outW, marginPx) {
90
101
  if (contentPx === null || !Number.isFinite(contentPx) || !(contentPx > 0)) return 0;
91
- return Math.min(PAIR_CURSOR_CLAMP * outW, contentPx + PAIR_CURSOR_MARGIN * outW);
102
+ return Math.min(PAIR_CURSOR_CLAMP * outW, contentPx + marginPx);
103
+ }
104
+
105
+ /**
106
+ * Output px of one eye per metre on the glass: the buffer eye is stretched over the tile's CSS
107
+ * width, and one CSS px is `metersPerCssPx` on the panel.
108
+ */
109
+ export function pairCursorScale(outW, tileCssWidth, metersPerCssPx) {
110
+ const m = metersPerCssPx > 0 && Number.isFinite(metersPerCssPx) ? metersPerCssPx : PAIR_CURSOR_CSS_PX_M;
111
+ return tileCssWidth > 0 ? outW / tileCssWidth / m : outW / (1000 * m);
92
112
  }
93
113
 
94
114
  /**
@@ -133,6 +153,9 @@ export class PairCursor {
133
153
  this._luma = null;
134
154
  this._uv = null;
135
155
  this._content = null;
156
+ this._metricsFor = null; // the tile handle whose displayMetrics() was asked for
157
+ /** One CSS px on the panel, metres, once the tile's handle has said (else the CSS reference px). */
158
+ this.metersPerCssPx = null;
136
159
  /** The last frame's placement, for diagnostics: `{ contentPx, targetPx, disparityPx, drawn }` or null. */
137
160
  this.last = null;
138
161
  }
@@ -146,7 +169,8 @@ export class PairCursor {
146
169
  * exactly then); otherwise leaves the buffer alone and the OS arrow shows, on the plane.
147
170
  * @param {CanvasRenderingContext2D} g the woven buffer (2·outW × outH), already painted
148
171
  * @param {object|null} luma the latest grayscale source copy (pairFootprintDisparity)
149
- * @param {{rL: object, rR: object, outW: number, outH: number, mirror?: boolean}} geo
172
+ * @param {{rL: object, rR: object, outW: number, outH: number, mirror?: boolean, handle?: object}} geo
173
+ * `handle` = the tile's woven handle: its `displayMetrics()` gives the panel's pixel pitch
150
174
  * @param {number} nowSec
151
175
  */
152
176
  draw(g, luma, geo, nowSec) {
@@ -160,16 +184,30 @@ export class PairCursor {
160
184
  this._luma = luma;
161
185
  this._uv = uv;
162
186
  }
163
- const target = pairCursorTarget(this._content, geo.outW);
187
+ this._askMetrics(geo.handle);
188
+ const r = this.pointer.canvas.getBoundingClientRect?.();
189
+ const pxPerM = pairCursorScale(geo.outW, r && r.width, this.metersPerCssPx);
190
+ const target = pairCursorTarget(this._content, geo.outW, PAIR_CURSOR_MARGIN_M * pxPerM);
164
191
  // The shared filter rises fast toward SMALLER values (nearer, in its convention): negate.
165
192
  const disparity = -cursorFilterStep(this.filter, CURSOR_DEFAULT_TUNING, -target, nowSec);
166
- const drawn = disparity >= PAIR_CURSOR_SHOW_PX;
193
+ const drawn = disparity >= Math.max(PAIR_CURSOR_SHOW_MIN_PX, PAIR_CURSOR_SHOW_M * pxPerM);
167
194
  if (drawn) drawPairArrow(g, geo.outW, geo.outH, u, v, disparity, hf * geo.outH);
168
195
  this.pointer.hideCss(drawn); // the OS arrow IS the cursor on the plane
169
196
  this.last = { contentPx: this._content, targetPx: target, disparityPx: drawn ? disparity : 0, drawn };
170
197
  return this.last;
171
198
  }
172
199
 
200
+ /** Ask the tile's handle once for the panel's pixel pitch; until it answers, the CSS reference px. */
201
+ _askMetrics(handle) {
202
+ if (!handle || handle === this._metricsFor || typeof handle.displayMetrics !== 'function') return;
203
+ this._metricsFor = handle;
204
+ Promise.resolve(handle.displayMetrics())
205
+ .then((m) => {
206
+ if (this._metricsFor === handle && m && m.metersPerCssPx > 0) this.metersPerCssPx = m.metersPerCssPx;
207
+ })
208
+ .catch(() => {});
209
+ }
210
+
173
211
  /** The OS arrow's height as a fraction of the tile's on-page height. */
174
212
  _osArrowFraction() {
175
213
  const r = this.pointer.canvas.getBoundingClientRect?.();
@@ -1715,7 +1715,7 @@ class Tile {
1715
1715
  const r = (rects[eye] = wire.eyeCropRect(eyeW, H, A, shift, eye));
1716
1716
  g.drawImage(v, eye * eyeW + r.sx, r.sy, r.sw, r.sh, eye * outW, 0, outW, outH);
1717
1717
  }
1718
- if (this.cursor) this.cursor.draw(g, this.luma, { rL: rects[0], rR: rects[1], outW, outH }, performance.now() / 1000);
1718
+ if (this.cursor) this.cursor.draw(g, this.luma, { rL: rects[0], rR: rects[1], outW, outH, handle: this.handle }, performance.now() / 1000);
1719
1719
  }
1720
1720
 
1721
1721
  /**
@@ -762,7 +762,7 @@ class CameraView {
762
762
  }
763
763
  }
764
764
  if (this.cursor) {
765
- const geo = { rL: eyeCropRect(eyeW, H, A, shift, 0), rR: eyeCropRect(eyeW, H, A, shift, 1), outW, outH, mirror: this.mirror };
765
+ const geo = { rL: eyeCropRect(eyeW, H, A, shift, 0), rR: eyeCropRect(eyeW, H, A, shift, 1), outW, outH, mirror: this.mirror, handle: this.handle };
766
766
  this.cursor.draw(g, this._luma, geo, performance.now() / 1000);
767
767
  }
768
768
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displayxr/inline3d",
3
- "version": "1.40.1",
3
+ "version": "1.40.2",
4
4
  "description": "Turn any HTML <canvas> into a 3D window on a spatial display, inside an ordinary web page, for the DisplayXR Browser. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",