@4players/odin-plugin-web 1.15.1 → 1.15.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.
@@ -1,4 +1,4 @@
1
- "use strict";var x0=Object.defineProperty;var pA=Object.getOwnPropertyDescriptor;var hA=Object.getOwnPropertyNames;var mA=Object.prototype.hasOwnProperty;var d=(D,x,A)=>()=>{if(A)throw A[0];try{return D&&(x=D(D=0)),x}catch(F){throw A=[F],F}};var kx=(D,x)=>{for(var A in x)x0(D,A,{get:x[A],enumerable:!0})},qA=(D,x,A,F)=>{if(x&&typeof x=="object"||typeof x=="function")for(let r of hA(x))!mA.call(D,r)&&r!==A&&x0(D,r,{get:()=>x[r],enumerable:!(F=pA(x,r))||F.enumerable});return D};var GA=D=>qA(x0({},"__esModule",{value:!0}),D);var C={};kx(C,{AdditionalCaptureBlocks:()=>yA,AdditionalPlaybackBlocks:()=>$A,ClockJumpCheckInterval:()=>NA,ClockJumpThreshold:()=>wA,ConnectInterval:()=>WA,ConnectTimeout:()=>RA,DefaultRefreshRate:()=>gA,DefaultVideoCodec:()=>zA,HealthCheckTimeout:()=>HA,MainConnectionPingInterval:()=>JA,MaxNumberOfDecoders:()=>LA,MaxReconnectDuration:()=>QA,MinDBFs:()=>A0,MinTokenLifetime:()=>KA,MinTokenRefreshInterval:()=>VA,PlaybackPreload:()=>IA,RenderQuantumSize:()=>PA,VadPreload:()=>_A,WebRtcAnswerTimeout:()=>MA,WebRtcIceTimeout:()=>SA,WebRtcMaxNegotiationAttempts:()=>TA,WebRtcStatsSnapshotInterval:()=>OA,WebRtcTimeout:()=>UA});var $A,yA,IA,gA,_A,LA,PA,A0,HA,NA,wA,JA,OA,SA,UA,MA,TA,RA,KA,VA,WA,QA,zA,F0=d(()=>{"use strict";$A=3,yA=3,IA=3,gA=250,_A=3,LA=512,PA=128,A0=-758.596,HA=1e4,NA=1e3,wA=1e4,JA=3e3,OA=1e3,SA=3e3,UA=1e4,MA=1e4,TA=3,RA=5e3,KA=6e4,VA=5e3,WA=[0,100,200,200,500],QA=12e4,zA="H264"});function cx(D){return typeof D!="symbol"}function s(D){return typeof D=="symbol"}var m,B,U,q,dx=d(()=>{"use strict";m=Symbol("Unencrypted"),B=Symbol("Invalid"),U=Symbol("Retry"),q=Symbol("UnexpectedEof")});function a(D,x,A){return D.postMessage(x,A)}function xx(D,x){return new Promise(A=>{let F=r=>{let[t]=r.data;t===x&&(A(r.data[1]),D.removeEventListener("message",F))};D.addEventListener("message",F)})}var l0=d(()=>{"use strict"});function r0(D,x){D.values[0]=x[0],D.values[1]=x[1]}function u0(D,x){return D.values[2+x*5]}function k0(D,x,A){let F=2+x*5+1;D.values[F+0]=A[0],D.values[F+1]=A[1]}function c0(D){return D.values[0]!==0}function d0(D){return D.values[1]}function p0(D){return D.values[2]}function h0(D,x){return D.values[3]=x}var m0=d(()=>{"use strict"});function q0(D,x){let A=new M(D);A.position=x;let F=A.readObjects(1);return cx(F)?A.position:F}var M,G0=d(()=>{"use strict";dx();M=class{constructor(x,A=0){this.bytes=x;this.position=A}readArrayLength(){let x=this.readTag();return s(x)?x:(x&240)===144?x&15:x===220?this.readUint16():x===221?this.readUint32():B}readNumber(){let x=this.readTag();return s(x)||(x&128)===0?x:(x&224)===224?x-256:x===202?this.readFloat32():x===203?this.readFloat64():x===204?this.readUint8():x===205?this.readUint16():x===206?this.readUint32():x===207?this.readUint64():x===208?this.readInt8():x===209?this.readInt16():x===210?this.readInt32():x===211?this.readInt64():B}readBytes(){let x=this.readTag();if(s(x))return x;let A;if(x===196)A=this.readUint8();else if(x===197)A=this.readUint16();else if(x===198)A=this.readUint32();else return B;if(s(A))return A;let F=this.consume(A);return F!==q?this.bytes.subarray(F,F+A):q}readObjects(x){for(;x>0;x-=1){let A=this.readTag();if(s(A))return A;let F,r=0,t=0;switch(A){case 192:break;case 194:break;case 195:break;case 196:r=this.readUint8();break;case 197:r=this.readUint16();break;case 198:r=this.readUint32();break;case 199:r=this.readUint8(),t=1;break;case 200:r=this.readUint8(),t=1;break;case 201:r=this.readUint32(),t=1;break;case 202:r=4;break;case 203:r=8;break;case 204:r=1;break;case 205:r=2;break;case 206:r=4;break;case 207:r=8;break;case 208:r=1;break;case 209:r=2;break;case 210:r=4;break;case 211:r=8;break;case 212:r=2;break;case 213:r=3;break;case 214:r=5;break;case 215:r=9;break;case 216:r=17;break;case 217:r=this.readUint8();break;case 218:r=this.readUint16();break;case 219:r=this.readUint32();break;case 220:if(F=this.readUint16(),s(F))return F;x+=F;break;case 221:if(F=this.readUint32(),s(F))return F;x+=F;break;case 222:if(F=this.readUint16(),s(F))return F;x+=F*2;break;case 223:if(F=this.readUint32(),s(F))return F;x+=F*2;break;default:if((A&128)!==0){if((A&240)===128)x+=(A&15)*2;else if((A&240)===144)x+=A&15;else if((A&224)===160)r=A&31;else if((A&224)!==224)return B}}if(r===q)return q;if(this.consume(r+t)===q)return q}}consume(x){if(x===q||this.position+x>this.bytes.length)return q;let A=this.position;return this.position=A+x,A}readTag(){let x=this.consume(1);return cx(x)?this.bytes[x]:x}readUint8(){let x=this.consume(1);return cx(x)?this.bytes[x]:x}readUint16(){let x=this.consume(2);return s(x)?x:this.bytes[x]<<8|this.bytes[x+1]}readUint32(){let x=this.consume(4);return s(x)?x:this.bytes[x]<<24|this.bytes[x+1]<<16|this.bytes[x+2]<<8|this.bytes[x+3]}readUint64(){let x=this.readUint32();if(s(x))return x;if(x>=2097152)return B;let A=this.readUint32();return s(A)?A:x<<32|A}readInt8(){let x=this.readUint8();return s(x)||x>=128&&(x=x-256),x}readInt16(){let x=this.readUint16();return s(x)||x>=32768&&(x=x-65536),x}readInt32(){let x=this.readUint32();return s(x)||x>=2147483648&&(x=x-4294967296),x}readInt64(){let x=this.readUint32();if(s(x))return x;if(x>=2097152||x<-2097152)return B;let A=this.readUint32();return s(A)?A:x<<32|A}readFloat32(){let x=this.consume(4);return s(x)?x:new Float32Array(this.bytes.subarray(x,x+4))[0]}readFloat64(){let x=this.consume(8);return s(x)?x:new Float64Array(this.bytes.subarray(x,x+8))[0]}}});var $0,y0=d(()=>{"use strict";$0="1.15.1"});function I0(D,x){G||(G=D??new c.Logger(c.LogLevel.DEBUG,"odin-plugin-web",[]),x&&G.sinks.push(new c.CallbackSink(x,c.Formatter.structured)))}function u(D,...x){let A=px(x);G?G?.error(D,A):(0,c.error)(D,A)}function i(D,...x){let A=px(x);G?G?.warn(D,A):(0,c.warn)(D,A)}function f(D,...x){let A=px(x);G?G?.info(D,A):(0,c.info)(D,A)}function n(D,...x){let A=px(x);G?G?.debug(D,A):(0,c.debug)(D,A)}function px(...D){if(D.length===1&&typeof D[0]=="object"&&D[0]!==null)return{...D[0]};if(D.length>0)return{args:D}}var c,G,g0=d(()=>{"use strict";c=require("@4players/odin-common")});function p(D){return D.connectionId*4294967296+D.mediaId}var I,Q,o=d(()=>{"use strict";F0();dx();F0();l0();m0();G0();y0();g0();dx();I={isSilent:!0,rmsDBFS:-758.596};Q=class{constructor(){this.inFlight=null}run(x){return this.inFlight||(this.inFlight=x().finally(()=>{this.inFlight=null})),this.inFlight}}});function jx(D,x,A,F,r){return Promise.all([xF(D),AF(A,x,F,r)])}async function xF(D){let x=URL.createObjectURL(new Blob([D],{type:"text/javascript"})),A=new Worker(x,{type:"module",name:"odin worker"});return rx.push(A),A}async function AF(D,x,A,F){try{let e=new AudioWorkletNode(D,A,F);return z.push(e),e}catch{}let r=D0.get(D);if(r===void 0){let e=URL.createObjectURL(new Blob([x],{type:"text/javascript"}));r=D.audioWorklet.addModule(e),D0.set(D,r),r.catch(()=>D0.delete(D))}await r;let t=new AudioWorkletNode(D,A,F);return z.push(t),t}async function N0(){return{workers:await Promise.all(rx.map(ex)),worklets:await Promise.all(z.map(D=>ex(D.port)))}}function ex(D){let{port1:x,port2:A}=new MessageChannel,{promise:F,resolve:r}=Promise.withResolvers();return A.onmessage=t=>r(t.data),setTimeout(()=>r("timeout"),100),a(D,["dump",{result:x}],[x]),F}var rx,z,Dx,tx,D0,mx=d(()=>{"use strict";o();rx=[],z=[],Dx=class{constructor(x,A,F){this.audioContext=x;this.worklet=A;this.worker=F;this.availableIndexes=[];this.medias=new Map;F.addEventListener("message",this._OnMessages.bind(this))}connectOutput(x){this.worklet.disconnect(),this.worklet.connect(x)}receivePacket(x,A){a(this.worker,["playbackReceivePacket",{connectionId:x,packet:A}],[A.buffer])}addMedias(x,A,F=[1,1]){let r=[];for(let t of A){let e=this._GetFreeIndex();e!==void 0&&(this.medias.set(p({connectionId:x,mediaId:t}),{index:e}),r.push({connectionId:x,mediaId:t,index:e,volume:F}))}a(this.worker,["playbackUpdateMedias",{added:r,removed:[]}])}removeMedias(x,A){let F=[];for(let r of A){let t=p({connectionId:x,mediaId:r}),e=this.medias.get(t);e!==void 0&&(this.medias.delete(t),this.availableIndexes.push(e.index),F.push({connectionId:x,mediaId:r,index:e.index}))}a(this.worker,["playbackUpdateMedias",{added:[],removed:F}])}close(){a(this.worker,["close",void 0]),a(this.worklet.port,["close",void 0]);let x=rx.indexOf(this.worker);x>=0&&rx.splice(x,1);let A=z.indexOf(this.worklet);A>=0&&z.splice(A,1)}async dump(){return{playbackWorker:await ex(this.worker),playbackWorklet:await ex(this.worklet.port)}}_GetFreeIndex(){return this.availableIndexes.pop()}_OnMessages(x){}},tx=class D{constructor(x,A,F,r,t){this.worklet=x;this.worker=A;this.sink=(e,j)=>{t.deref()!==void 0?F(e,j):(u("capture worker was left abandoned, aborting capture worker"),D.shutdown(x,A))},this.monitorSink=(e,j)=>{t.deref()!==void 0?r(e,j):(u("capture worker was left abandoned, aborting capture worker"),D.shutdown(x,A))},A.addEventListener("message",this._OnMessages.bind(this))}get context(){return this.worklet.context}setMedias(x){a(this.worker,["captureSetMedias",{connections:x}])}setVad(x){a(this.worker,["captureSetVad",x])}close(){D.shutdown(this.worklet,this.worker)}static shutdown(x,A){a(x.port,["close",void 0]),a(A,["close",void 0]);let F=rx.indexOf(A);F>=0&&rx.splice(F,1);let r=z.indexOf(x);r>=0&&z.splice(r,1)}async dump(){return{captureWorker:await ex(this.worker),captureWorklet:await ex(this.worklet.port)}}_OnMessages(x){let[A,F]=x.data;A==="sendPacket"&&(F.connectionId===0?this.monitorSink(F.connectionId,F.packet):this.sink(F.connectionId,F.packet))}};D0=new WeakMap});var t0,w0=d(()=>{t0=`"use strict";(()=>{var dn=Object.create;var or=Object.defineProperty;var qn=Object.getOwnPropertyDescriptor;var fn=Object.getOwnPropertyNames;var Cn=Object.getPrototypeOf,Gn=Object.prototype.hasOwnProperty;var pn=(e,A)=>()=>{try{return A||e((A={exports:{}}).exports,A),A.exports}catch(t){throw A=0,t}},En=(e,A)=>{for(var t in A)or(e,t,{get:A[t],enumerable:!0})},mn=(e,A,t,s)=>{if(A&&typeof A=="object"||typeof A=="function")for(let i of fn(A))!Gn.call(e,i)&&i!==t&&or(e,i,{get:()=>A[i],enumerable:!(s=qn(A,i))||s.enumerable});return e};var hn=(e,A,t)=>(t=e!=null?dn(Cn(e)):{},mn(A||!e||!e.__esModule?or(t,"default",{value:e,enumerable:!0}):t,e));var $t=pn((ht,KA)=>{"use strict";var TA=(()=>{var e=globalThis.document?.currentScript?.src;return async function(A={}){var t=A,s=!!globalThis.window,i=!!globalThis.WorkerGlobalScope,d=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer",q=i&&globalThis.name=="em-pthread",p=[],I="./this.program",g=(r,j)=>{throw j};i&&(e=self.location.href);var MA="",U,Ht;if(s||i){try{MA=new URL(".",e).href}catch{}i&&(Ht=r=>{var j=new XMLHttpRequest;return j.open("GET",r,!1),j.responseType="arraybuffer",j.send(null),new Uint8Array(j.response)}),U=async r=>{var j=await fetch(r,{credentials:"same-origin"});if(j.ok)return j.arrayBuffer();throw new Error(j.status+" : "+j.url)}}var SA=console.log.bind(console),J=console.error.bind(console),Dt,eA,GA=!1,z;class Lt{}class Ls extends Lt{}function yt(r){for(var j=0,n=r.length,l=new Uint8Array(n),o;j<n;++j)o=r.charCodeAt(j),l[j]=~o>>8&o;return l}var _r;if(q){let r=function(j){try{var n=j.data,l=n.cmd;if(l==1){let o=[];self.onmessage=a=>o.push(a),_r=()=>{postMessage({cmd:3});for(let a of o)r(a);self.onmessage=r};for(let a of n.handlers)(!t[a]||t[a].proxy)&&(t[a]=(...k)=>{postMessage({cmd:9,handler:a,args:k})},a=="print"&&(SA=t[a]),a=="printErr"&&(J=t[a]));iA=n.wasmMemory,Dr(),eA=n.wasmModule,xr(),gj(),_r()}else if(l==2){Kt(n.pthread_ptr),sr(n.pthread_ptr,0,0,1,0,0),E.threadInitTLS(),tr(n.pthread_ptr),VA||(pj(),VA=!0);try{Mt(n.start_routine,n.arg)}catch(o){if(o!="unwind")throw o}}else l==4?VA&&LA():l&&(J(\`worker: received unknown command \${l}\`),J(n))}catch(o){throw Hr&&mj(),o}};var gs=r,VA=!1;self.onunhandledrejection=j=>{throw j.reason||j},self.onmessage=r}var Hr=!1;function Dr(){var r=iA.buffer;V=new Int8Array(r),EA=new Int16Array(r),t.HEAPU8=x=new Uint8Array(r),nA=new Uint16Array(r),t.HEAP32=T=new Int32Array(r),t.HEAPU32=$=new Uint32Array(r),t.HEAPF32=Nr=new Float32Array(r),mA=new Float64Array(r),S=new BigInt64Array(r),br=new BigUint64Array(r)}function gt(){if(!q){{var r=16777216;iA=new WebAssembly.Memory({initial:r/65536,maximum:r/65536,shared:!0})}Dr()}}function xt(){var r=t.preRun;r&&(typeof r=="function"&&(r=[r]),wr.push(...r)),Or(wr)}function Lr(){Hr=!0,!q&&rA.F()}function Bt(){var r=t.postRun;r&&(typeof r=="function"&&(r=[r]),Sr.push(...r)),Or(Sr)}function pA(r){t.onAbort?.(r),r=\`Aborted(\${r})\`,J(r),GA=!0,r+=". Build with -sASSERTIONS for more info.";var j=new WebAssembly.RuntimeError(r);throw j}var yr;function Nt(){return yt(\`\\0asm\\0\\0\\0\\xAC=\\\`\\x7F\\0\\\`\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\\`\\0\\0\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`||\\\`\\0\\x7F\\\`\\x7F}\\\`}}\\\`\\x07\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\b\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F~\\x7F~\\\`\\x7F\\x7F}\\\`\\x7F}}\\\`\\x7F\\x7F}}\\0\\\`
1
+ "use strict";var x0=Object.defineProperty;var pA=Object.getOwnPropertyDescriptor;var hA=Object.getOwnPropertyNames;var mA=Object.prototype.hasOwnProperty;var d=(D,x,A)=>()=>{if(A)throw A[0];try{return D&&(x=D(D=0)),x}catch(F){throw A=[F],F}};var kx=(D,x)=>{for(var A in x)x0(D,A,{get:x[A],enumerable:!0})},qA=(D,x,A,F)=>{if(x&&typeof x=="object"||typeof x=="function")for(let r of hA(x))!mA.call(D,r)&&r!==A&&x0(D,r,{get:()=>x[r],enumerable:!(F=pA(x,r))||F.enumerable});return D};var GA=D=>qA(x0({},"__esModule",{value:!0}),D);var C={};kx(C,{AdditionalCaptureBlocks:()=>yA,AdditionalPlaybackBlocks:()=>$A,ClockJumpCheckInterval:()=>NA,ClockJumpThreshold:()=>wA,ConnectInterval:()=>WA,ConnectTimeout:()=>RA,DefaultRefreshRate:()=>gA,DefaultVideoCodec:()=>zA,HealthCheckTimeout:()=>HA,MainConnectionPingInterval:()=>JA,MaxNumberOfDecoders:()=>LA,MaxReconnectDuration:()=>QA,MinDBFs:()=>A0,MinTokenLifetime:()=>KA,MinTokenRefreshInterval:()=>VA,PlaybackPreload:()=>IA,RenderQuantumSize:()=>PA,VadPreload:()=>_A,WebRtcAnswerTimeout:()=>MA,WebRtcIceTimeout:()=>SA,WebRtcMaxNegotiationAttempts:()=>TA,WebRtcStatsSnapshotInterval:()=>OA,WebRtcTimeout:()=>UA});var $A,yA,IA,gA,_A,LA,PA,A0,HA,NA,wA,JA,OA,SA,UA,MA,TA,RA,KA,VA,WA,QA,zA,F0=d(()=>{"use strict";$A=3,yA=3,IA=3,gA=250,_A=3,LA=512,PA=128,A0=-758.596,HA=1e4,NA=1e3,wA=1e4,JA=3e3,OA=1e3,SA=3e3,UA=1e4,MA=1e4,TA=3,RA=5e3,KA=6e4,VA=5e3,WA=[0,100,200,200,500],QA=12e4,zA="H264"});function cx(D){return typeof D!="symbol"}function s(D){return typeof D=="symbol"}var m,B,U,q,dx=d(()=>{"use strict";m=Symbol("Unencrypted"),B=Symbol("Invalid"),U=Symbol("Retry"),q=Symbol("UnexpectedEof")});function a(D,x,A){return D.postMessage(x,A)}function xx(D,x){return new Promise(A=>{let F=r=>{let[t]=r.data;t===x&&(A(r.data[1]),D.removeEventListener("message",F))};D.addEventListener("message",F)})}var l0=d(()=>{"use strict"});function r0(D,x){D.values[0]=x[0],D.values[1]=x[1]}function u0(D,x){return D.values[2+x*5]}function k0(D,x,A){let F=2+x*5+1;D.values[F+0]=A[0],D.values[F+1]=A[1]}function c0(D){return D.values[0]!==0}function d0(D){return D.values[1]}function p0(D){return D.values[2]}function h0(D,x){return D.values[3]=x}var m0=d(()=>{"use strict"});function q0(D,x){let A=new M(D);A.position=x;let F=A.readObjects(1);return cx(F)?A.position:F}var M,G0=d(()=>{"use strict";dx();M=class{constructor(x,A=0){this.bytes=x;this.position=A}readArrayLength(){let x=this.readTag();return s(x)?x:(x&240)===144?x&15:x===220?this.readUint16():x===221?this.readUint32():B}readNumber(){let x=this.readTag();return s(x)||(x&128)===0?x:(x&224)===224?x-256:x===202?this.readFloat32():x===203?this.readFloat64():x===204?this.readUint8():x===205?this.readUint16():x===206?this.readUint32():x===207?this.readUint64():x===208?this.readInt8():x===209?this.readInt16():x===210?this.readInt32():x===211?this.readInt64():B}readBytes(){let x=this.readTag();if(s(x))return x;let A;if(x===196)A=this.readUint8();else if(x===197)A=this.readUint16();else if(x===198)A=this.readUint32();else return B;if(s(A))return A;let F=this.consume(A);return F!==q?this.bytes.subarray(F,F+A):q}readObjects(x){for(;x>0;x-=1){let A=this.readTag();if(s(A))return A;let F,r=0,t=0;switch(A){case 192:break;case 194:break;case 195:break;case 196:r=this.readUint8();break;case 197:r=this.readUint16();break;case 198:r=this.readUint32();break;case 199:r=this.readUint8(),t=1;break;case 200:r=this.readUint8(),t=1;break;case 201:r=this.readUint32(),t=1;break;case 202:r=4;break;case 203:r=8;break;case 204:r=1;break;case 205:r=2;break;case 206:r=4;break;case 207:r=8;break;case 208:r=1;break;case 209:r=2;break;case 210:r=4;break;case 211:r=8;break;case 212:r=2;break;case 213:r=3;break;case 214:r=5;break;case 215:r=9;break;case 216:r=17;break;case 217:r=this.readUint8();break;case 218:r=this.readUint16();break;case 219:r=this.readUint32();break;case 220:if(F=this.readUint16(),s(F))return F;x+=F;break;case 221:if(F=this.readUint32(),s(F))return F;x+=F;break;case 222:if(F=this.readUint16(),s(F))return F;x+=F*2;break;case 223:if(F=this.readUint32(),s(F))return F;x+=F*2;break;default:if((A&128)!==0){if((A&240)===128)x+=(A&15)*2;else if((A&240)===144)x+=A&15;else if((A&224)===160)r=A&31;else if((A&224)!==224)return B}}if(r===q)return q;if(this.consume(r+t)===q)return q}}consume(x){if(x===q||this.position+x>this.bytes.length)return q;let A=this.position;return this.position=A+x,A}readTag(){let x=this.consume(1);return cx(x)?this.bytes[x]:x}readUint8(){let x=this.consume(1);return cx(x)?this.bytes[x]:x}readUint16(){let x=this.consume(2);return s(x)?x:this.bytes[x]<<8|this.bytes[x+1]}readUint32(){let x=this.consume(4);return s(x)?x:this.bytes[x]<<24|this.bytes[x+1]<<16|this.bytes[x+2]<<8|this.bytes[x+3]}readUint64(){let x=this.readUint32();if(s(x))return x;if(x>=2097152)return B;let A=this.readUint32();return s(A)?A:x<<32|A}readInt8(){let x=this.readUint8();return s(x)||x>=128&&(x=x-256),x}readInt16(){let x=this.readUint16();return s(x)||x>=32768&&(x=x-65536),x}readInt32(){let x=this.readUint32();return s(x)||x>=2147483648&&(x=x-4294967296),x}readInt64(){let x=this.readUint32();if(s(x))return x;if(x>=2097152||x<-2097152)return B;let A=this.readUint32();return s(A)?A:x<<32|A}readFloat32(){let x=this.consume(4);return s(x)?x:new Float32Array(this.bytes.subarray(x,x+4))[0]}readFloat64(){let x=this.consume(8);return s(x)?x:new Float64Array(this.bytes.subarray(x,x+8))[0]}}});var $0,y0=d(()=>{"use strict";$0="1.15.2"});function I0(D,x){G||(G=D??new c.Logger(c.LogLevel.DEBUG,"odin-plugin-web",[]),x&&G.sinks.push(new c.CallbackSink(x,c.Formatter.structured)))}function u(D,...x){let A=px(x);G?G?.error(D,A):(0,c.error)(D,A)}function i(D,...x){let A=px(x);G?G?.warn(D,A):(0,c.warn)(D,A)}function f(D,...x){let A=px(x);G?G?.info(D,A):(0,c.info)(D,A)}function n(D,...x){let A=px(x);G?G?.debug(D,A):(0,c.debug)(D,A)}function px(...D){if(D.length===1&&typeof D[0]=="object"&&D[0]!==null)return{...D[0]};if(D.length>0)return{args:D}}var c,G,g0=d(()=>{"use strict";c=require("@4players/odin-common")});function p(D){return D.connectionId*4294967296+D.mediaId}var I,Q,o=d(()=>{"use strict";F0();dx();F0();l0();m0();G0();y0();g0();dx();I={isSilent:!0,rmsDBFS:-758.596};Q=class{constructor(){this.inFlight=null}run(x){return this.inFlight||(this.inFlight=x().finally(()=>{this.inFlight=null})),this.inFlight}}});function jx(D,x,A,F,r){return Promise.all([xF(D),AF(A,x,F,r)])}async function xF(D){let x=URL.createObjectURL(new Blob([D],{type:"text/javascript"})),A=new Worker(x,{type:"module",name:"odin worker"});return rx.push(A),A}async function AF(D,x,A,F){try{let e=new AudioWorkletNode(D,A,F);return z.push(e),e}catch{}let r=D0.get(D);if(r===void 0){let e=URL.createObjectURL(new Blob([x],{type:"text/javascript"}));r=D.audioWorklet.addModule(e),D0.set(D,r),r.catch(()=>D0.delete(D))}await r;let t=new AudioWorkletNode(D,A,F);return z.push(t),t}async function N0(){return{workers:await Promise.all(rx.map(ex)),worklets:await Promise.all(z.map(D=>ex(D.port)))}}function ex(D){let{port1:x,port2:A}=new MessageChannel,{promise:F,resolve:r}=Promise.withResolvers();return A.onmessage=t=>r(t.data),setTimeout(()=>r("timeout"),100),a(D,["dump",{result:x}],[x]),F}var rx,z,Dx,tx,D0,mx=d(()=>{"use strict";o();rx=[],z=[],Dx=class{constructor(x,A,F){this.audioContext=x;this.worklet=A;this.worker=F;this.availableIndexes=[];this.medias=new Map;F.addEventListener("message",this._OnMessages.bind(this))}connectOutput(x){this.worklet.disconnect(),this.worklet.connect(x)}receivePacket(x,A){a(this.worker,["playbackReceivePacket",{connectionId:x,packet:A}],[A.buffer])}addMedias(x,A,F=[1,1]){let r=[];for(let t of A){let e=this._GetFreeIndex();e!==void 0&&(this.medias.set(p({connectionId:x,mediaId:t}),{index:e}),r.push({connectionId:x,mediaId:t,index:e,volume:F}))}a(this.worker,["playbackUpdateMedias",{added:r,removed:[]}])}removeMedias(x,A){let F=[];for(let r of A){let t=p({connectionId:x,mediaId:r}),e=this.medias.get(t);e!==void 0&&(this.medias.delete(t),this.availableIndexes.push(e.index),F.push({connectionId:x,mediaId:r,index:e.index}))}a(this.worker,["playbackUpdateMedias",{added:[],removed:F}])}close(){a(this.worker,["close",void 0]),a(this.worklet.port,["close",void 0]);let x=rx.indexOf(this.worker);x>=0&&rx.splice(x,1);let A=z.indexOf(this.worklet);A>=0&&z.splice(A,1)}async dump(){return{playbackWorker:await ex(this.worker),playbackWorklet:await ex(this.worklet.port)}}_GetFreeIndex(){return this.availableIndexes.pop()}_OnMessages(x){}},tx=class D{constructor(x,A,F,r,t){this.worklet=x;this.worker=A;this.sink=(e,j)=>{t.deref()!==void 0?F(e,j):(u("capture worker was left abandoned, aborting capture worker"),D.shutdown(x,A))},this.monitorSink=(e,j)=>{t.deref()!==void 0?r(e,j):(u("capture worker was left abandoned, aborting capture worker"),D.shutdown(x,A))},A.addEventListener("message",this._OnMessages.bind(this))}get context(){return this.worklet.context}setMedias(x){a(this.worker,["captureSetMedias",{connections:x}])}setVad(x){a(this.worker,["captureSetVad",x])}close(){D.shutdown(this.worklet,this.worker)}static shutdown(x,A){a(x.port,["close",void 0]),a(A,["close",void 0]);let F=rx.indexOf(A);F>=0&&rx.splice(F,1);let r=z.indexOf(x);r>=0&&z.splice(r,1)}async dump(){return{captureWorker:await ex(this.worker),captureWorklet:await ex(this.worklet.port)}}_OnMessages(x){let[A,F]=x.data;A==="sendPacket"&&(F.connectionId===0?this.monitorSink(F.connectionId,F.packet):this.sink(F.connectionId,F.packet))}};D0=new WeakMap});var t0,w0=d(()=>{t0=`"use strict";(()=>{var dn=Object.create;var or=Object.defineProperty;var qn=Object.getOwnPropertyDescriptor;var fn=Object.getOwnPropertyNames;var Cn=Object.getPrototypeOf,Gn=Object.prototype.hasOwnProperty;var pn=(e,A)=>()=>{try{return A||e((A={exports:{}}).exports,A),A.exports}catch(t){throw A=0,t}},En=(e,A)=>{for(var t in A)or(e,t,{get:A[t],enumerable:!0})},mn=(e,A,t,s)=>{if(A&&typeof A=="object"||typeof A=="function")for(let i of fn(A))!Gn.call(e,i)&&i!==t&&or(e,i,{get:()=>A[i],enumerable:!(s=qn(A,i))||s.enumerable});return e};var hn=(e,A,t)=>(t=e!=null?dn(Cn(e)):{},mn(A||!e||!e.__esModule?or(t,"default",{value:e,enumerable:!0}):t,e));var $t=pn((ht,KA)=>{"use strict";var TA=(()=>{var e=globalThis.document?.currentScript?.src;return async function(A={}){var t=A,s=!!globalThis.window,i=!!globalThis.WorkerGlobalScope,d=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer",q=i&&globalThis.name=="em-pthread",p=[],I="./this.program",g=(r,j)=>{throw j};i&&(e=self.location.href);var MA="",U,Ht;if(s||i){try{MA=new URL(".",e).href}catch{}i&&(Ht=r=>{var j=new XMLHttpRequest;return j.open("GET",r,!1),j.responseType="arraybuffer",j.send(null),new Uint8Array(j.response)}),U=async r=>{var j=await fetch(r,{credentials:"same-origin"});if(j.ok)return j.arrayBuffer();throw new Error(j.status+" : "+j.url)}}var SA=console.log.bind(console),J=console.error.bind(console),Dt,eA,GA=!1,z;class Lt{}class Ls extends Lt{}function yt(r){for(var j=0,n=r.length,l=new Uint8Array(n),o;j<n;++j)o=r.charCodeAt(j),l[j]=~o>>8&o;return l}var _r;if(q){let r=function(j){try{var n=j.data,l=n.cmd;if(l==1){let o=[];self.onmessage=a=>o.push(a),_r=()=>{postMessage({cmd:3});for(let a of o)r(a);self.onmessage=r};for(let a of n.handlers)(!t[a]||t[a].proxy)&&(t[a]=(...k)=>{postMessage({cmd:9,handler:a,args:k})},a=="print"&&(SA=t[a]),a=="printErr"&&(J=t[a]));iA=n.wasmMemory,Dr(),eA=n.wasmModule,xr(),gj(),_r()}else if(l==2){Kt(n.pthread_ptr),sr(n.pthread_ptr,0,0,1,0,0),E.threadInitTLS(),tr(n.pthread_ptr),VA||(pj(),VA=!0);try{Mt(n.start_routine,n.arg)}catch(o){if(o!="unwind")throw o}}else l==4?VA&&LA():l&&(J(\`worker: received unknown command \${l}\`),J(n))}catch(o){throw Hr&&mj(),o}};var gs=r,VA=!1;self.onunhandledrejection=j=>{throw j.reason||j},self.onmessage=r}var Hr=!1;function Dr(){var r=iA.buffer;V=new Int8Array(r),EA=new Int16Array(r),t.HEAPU8=x=new Uint8Array(r),nA=new Uint16Array(r),t.HEAP32=T=new Int32Array(r),t.HEAPU32=$=new Uint32Array(r),t.HEAPF32=Nr=new Float32Array(r),mA=new Float64Array(r),S=new BigInt64Array(r),br=new BigUint64Array(r)}function gt(){if(!q){{var r=16777216;iA=new WebAssembly.Memory({initial:r/65536,maximum:r/65536,shared:!0})}Dr()}}function xt(){var r=t.preRun;r&&(typeof r=="function"&&(r=[r]),wr.push(...r)),Or(wr)}function Lr(){Hr=!0,!q&&rA.F()}function Bt(){var r=t.postRun;r&&(typeof r=="function"&&(r=[r]),Sr.push(...r)),Or(Sr)}function pA(r){t.onAbort?.(r),r=\`Aborted(\${r})\`,J(r),GA=!0,r+=". Build with -sASSERTIONS for more info.";var j=new WebAssembly.RuntimeError(r);throw j}var yr;function Nt(){return yt(\`\\0asm\\0\\0\\0\\xAC=\\\`\\x7F\\0\\\`\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\\`\\0\\0\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`||\\\`\\0\\x7F\\\`\\x7F}\\\`}}\\\`\\x07\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\b\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F~\\x7F~\\\`\\x7F\\x7F}\\\`\\x7F}}\\\`\\x7F\\x7F}}\\0\\\`
2
2
  \\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`|}\\\`|\\x7F|\\\`\\x7F\\x7F}\\0\\\`\\x07\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\` \\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\f\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\b\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x07\\x7F|\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F|}\\\`\\x7F\\x7F\\x7F~~\\0\\\`\\x07\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F|\\\`\\0|\\\`\\r\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F~\\x7F\\x7F\\x7F\\\`\\x7F\\x7F|\\\`\\v\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F}\\x7F\\x7F\\x7F\\\`\\v\\x7F\\x7F\\x7F\\x7F\\x7F}}\\x7F\\x7F\\x7F\\x7F\\0\\\`~\\x7F\\x7F\\\` \\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F}\\x7F\\x7F\\\`||\\x7F|\\\`|||\\\`\\x7F\\x7F\\x7F|\\\`\\v\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\v\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x07\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F}\\\`\\f\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`}\\x7F\\x7F\\\`|\\x7F\\x7F\\\`\\x7F\\x7F\\x7F}\\\`\\x7F}\\x7F\\0\\\`\\x7F\\x7F}\\x7F\\x7F\\x7F}\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F}\\x7F\\x7F\\\`\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\x7F\\0\\\`\\x7F\\x7F\\x7F}}\\0\\\`\\x7F\\x7F\\x7F\\x7F\\x7F|\\\`\\x7F\\x7F|\\0\\xBFab\\0ac\\0ad\\0ae\\0af\\0ag\\0ah\\0!ai\\0
3
3
  aj\\0"ak\\0#al\\0am\\0 an\\0$ao\\0ap\\0aq\\0ar\\0\\0as\\0\\0at\\0au\\0av\\0%aw\\0ax\\0\\bay\\0\\0az\\0\\0aA\\0\\baB\\0\\0aC\\0\\baD\\0\\0aE\\0aa\\x80\\x80\\xFA\\xF8\\0\\x07\\f&\\0\\f\\x07\\f\\f\\0\\x07\\0\\x07'(
4
4
  \\b\\v)\\x07*\\0\\f+,-\\v\\0\\0\\x07\\0\\b\\b\\x1B
@@ -6449,4 +6449,4 @@ K\\xE08\\xDF\\0}\\xBC\\x8A\\x1B\\f\\xE5\\xFF\\xCF\\xE8?\\x9F\\xFFFq\\0\\x88\\xB
6449
6449
  return ret;
6450
6450
  \`),q+=\`}
6451
6451
  \`,new Function(m,q)}function MA(t,j,s,i,o,k){var a=j.length;a<2&&G("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var u=j[1]!==null&&s!==null,c=Lr(j),q=!j[0].isVoid,f=j[0],m=j[1],$=[t,G,i,o,yr,f.fromWireType.bind(f),m?.toWireType.bind(m)],E=2;E<a;++E){var F=j[E];$.push(F.toWireType.bind(F))}if(!c)for(var E=u?1:2;E<j.length;++E)j[E].destructorFunction!==null&&$.push(j[E].destructorFunction);var P=Gt(j,u,q,k)(...$);return hr(t,P)}var pt=(t,j,s,i,o,k)=>{var a=SA(j,s);o=b(i,o),U([],[t],u=>{u=u[0];var c=\`constructor \${u.name}\`;if(u.registeredClass.constructor_body===void 0&&(u.registeredClass.constructor_body=[]),u.registeredClass.constructor_body[j-1]!==void 0)throw new AA(\`Cannot register multiple constructors with identical number of parameters (\${j-1}) for class '\${u.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!\`);return u.registeredClass.constructor_body[j-1]=()=>{z(\`Cannot construct \${u.name} due to unbound types\`,a)},U([],a,q=>(q.splice(1,0,null),u.registeredClass.constructor_body[j-1]=MA(c,q,null,o,k),[])),[]})},Hr=t=>{t=t.trim();let j=t.indexOf("(");return j===-1?t:t.slice(0,j)},Et=(t,j,s,i,o,k,a,u,c,q)=>{var f=SA(s,i);j=v(j),j=Hr(j),k=b(o,k,c),U([],[t],m=>{m=m[0];var $=\`\${m.name}.\${j}\`;j.startsWith("@@")&&(j=Symbol[j.substring(2)]),u&&m.registeredClass.pureVirtualFunctions.push(j);function E(){z(\`Cannot call \${$} due to unbound types\`,f)}var F=m.registeredClass.instancePrototype,y=F[j];return y===void 0||y.overloadTable===void 0&&y.className!==m.name&&y.argCount===s-2?(E.argCount=s-2,E.className=m.name,F[j]=E):(Fr(F,j,$),F[j].overloadTable[s-2]=E),U([],f,P=>{var L=MA($,P,m,k,a,c);return F[j].overloadTable===void 0?(L.argCount=s-2,F[j]=L):F[j].overloadTable[s-2]=L,[]}),[]})},gr=(t,j,s)=>(t instanceof Object||G(\`\${s} with invalid "this": \${t}\`),t instanceof j.registeredClass.constructor||G(\`\${s} incompatible with "this" of type \${t.constructor.name}\`),t.$$.ptr||G(\`cannot call emscripten binding method \${s} on deleted object\`),fA(t.$$.ptr,t.$$.ptrType.registeredClass,j.registeredClass)),mt=(t,j,s,i,o,k,a,u,c,q)=>{j=v(j),o=b(i,o),U([],[t],f=>{f=f[0];var m=\`\${f.name}.\${j}\`,$={get(){z(\`Cannot access \${m} due to unbound types\`,[s,a])},enumerable:!0,configurable:!0};return c?$.set=()=>z(\`Cannot access \${m} due to unbound types\`,[s,a]):$.set=E=>G(m+" is a read-only property"),Object.defineProperty(f.registeredClass.instancePrototype,j,$),U([],c?[s,a]:[s],E=>{var F=E[0],y={get(){var L=gr(this,f,m+" getter");return F.fromWireType(o(k,L))},enumerable:!0};if(c){c=b(u,c);var P=E[1];y.set=function(L){var tA=gr(this,f,m+" setter"),_=[];c(q,tA,P.toWireType(_,L)),yr(_)}}return Object.defineProperty(f.registeredClass.instancePrototype,j,y),[]}),[]})},Nr=[],S=[0,1,,1,null,1,!0,1,!1,1],ht=t=>{if(t>9&&--S[t+1]===0){var j=S[t];S[t]=void 0,Nr.push(t)}},VA={toValue:t=>(t||G(\`Cannot use deleted val. handle = \${t}\`),S[t]),toHandle:t=>{switch(t){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{let j=Nr.pop()||S.length;return S[j]=t,S[j+1]=1,j}}}},$t={name:"emscripten::val",fromWireType:t=>{var j=VA.toValue(t);return ht(t),j},toWireType:(t,j)=>VA.toHandle(j),readValueFromPointer:GA,destructorFunction:null},Ft=t=>x(t,$t),It=(t,j)=>{switch(j){case 4:return function(s){return this.fromWireType(ur[s>>2])};case 8:return function(s){return this.fromWireType(cr[s>>3])};default:throw new TypeError(\`invalid float width (\${j}): \${t}\`)}},vt=(t,j,s)=>{j=v(j),x(t,{name:j,fromWireType:i=>i,toWireType:(i,o)=>o,readValueFromPointer:It(j,s),destructorFunction:null})},Dt=(t,j,s,i,o,k,a,u)=>{var c=SA(j,s);t=v(t),t=Hr(t),o=b(i,o,a),Ir(t,function(){z(\`Cannot call \${t} due to unbound types\`,c)},j-1),U([],c,q=>{var f=[q[0],null].concat(q.slice(1));return Dr(t,MA(t,f,null,o,k,a),j-1),[]})},_t=(t,j,s,i,o)=>{j=v(j);let k=i===0,a=c=>c;if(k){var u=32-8*s;a=c=>c<<u>>>u,o=a(o)}x(t,{name:j,fromWireType:a,toWireType:(c,q)=>q,readValueFromPointer:Gr(j,s,i!==0),destructorFunction:null})},yt=(t,j,s)=>{var i=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array],o=i[j];function k(a){var u=h[a>>2],c=h[a+4>>2];return new o(K.buffer,c,u)}s=v(s),x(t,{name:s,fromWireType:k,readValueFromPointer:k},{ignoreDuplicateRegistrations:!0})},Lt=(t,j,s,i)=>{if(!(i>0))return 0;for(var o=s,k=s+i-1,a=0;a<t.length;++a){var u=t.codePointAt(a);if(u<=127){if(s>=k)break;j[s++]=u}else if(u<=2047){if(s+1>=k)break;j[s++]=192|u>>6,j[s++]=128|u&63}else if(u<=65535){if(s+2>=k)break;j[s++]=224|u>>12,j[s++]=128|u>>6&63,j[s++]=128|u&63}else{if(s+3>=k)break;j[s++]=240|u>>18,j[s++]=128|u>>12&63,j[s++]=128|u>>6&63,j[s++]=128|u&63,a++}}return j[s]=0,s-o},Ht=(t,j,s)=>Lt(t,H,j,s),gt=t=>{for(var j=0,s=0;s<t.length;++s){var i=t.charCodeAt(s);i<=127?j++:i<=2047?j+=2:i>=55296&&i<=57343?(j+=4,++s):j+=3}return j},xr=globalThis.TextDecoder&&new TextDecoder,Br=(t,j,s,i)=>{var o=j+s;if(i)return o;for(;t[j]&&!(j>=o);)++j;return j},br=(t,j=0,s,i)=>{var o=Br(t,j,s,i);if(o-j>16&&t.buffer&&xr)return xr.decode(t.subarray(j,o));for(var k="";j<o;){var a=t[j++];if(!(a&128)){k+=String.fromCharCode(a);continue}var u=t[j++]&63;if((a&224)==192){k+=String.fromCharCode((a&31)<<6|u);continue}var c=t[j++]&63;if((a&240)==224?a=(a&15)<<12|u<<6|c:a=(a&7)<<18|u<<12|c<<6|t[j++]&63,a<65536)k+=String.fromCharCode(a);else{var q=a-65536;k+=String.fromCharCode(55296|q>>10,56320|q&1023)}}return k},Nt=(t,j,s)=>t?br(H,t,j,s):"",xt=(t,j)=>{j=v(j);var s=!0;x(t,{name:j,fromWireType(i){var o=h[i>>2],k=i+4,a;if(s)a=Nt(k,o,!0);else{a="";for(var u=0;u<o;++u)a+=String.fromCharCode(H[k+u])}return J(i),a},toWireType(i,o){o instanceof ArrayBuffer&&(o=new Uint8Array(o));var k,a=typeof o=="string";a||ArrayBuffer.isView(o)&&o.BYTES_PER_ELEMENT==1||G("Cannot pass non-string to std::string"),s&&a?k=gt(o):k=o.length;var u=RA(4+k+1),c=u+4;if(h[u>>2]=k,a)if(s)Ht(o,c,k+1);else for(var q=0;q<k;++q){var f=o.charCodeAt(q);f>255&&(J(u),G("String has UTF-16 code units that do not fit in 8 bits")),H[c+q]=f}else H.set(o,c);return i!==null&&i.push(J,u),u},readValueFromPointer:GA,destructorFunction(i){J(i)}})},Jr=globalThis.TextDecoder?new TextDecoder("utf-16le"):void 0,Bt=(t,j,s)=>{var i=t>>1,o=Br(Y,i,j/2,s);if(o-i>16&&Jr)return Jr.decode(Y.subarray(i,o));for(var k="",a=i;a<o;++a){var u=Y[a];k+=String.fromCharCode(u)}return k},bt=(t,j,s=2147483647)=>{if(s<2)return 0;s-=2;for(var i=j,o=s<t.length*2?s/2:t.length,k=0;k<o;++k){var a=t.charCodeAt(k);uA[j>>1]=a,j+=2}return uA[j>>1]=0,j-i},Jt=t=>t.length*2,Pt=(t,j,s)=>{for(var i="",o=t>>2,k=0;!(k>=j/4);k++){var a=h[o+k];if(!a&&!s)break;i+=String.fromCodePoint(a)}return i},Ot=(t,j,s=2147483647)=>{if(s<4)return 0;for(var i=j,o=i+s-4,k=0;k<t.length;++k){var a=t.codePointAt(k);if(a>65535&&k++,cA[j>>2]=a,j+=4,j+4>o)break}return cA[j>>2]=0,j-i},Ut=t=>{for(var j=0,s=0;s<t.length;++s){var i=t.codePointAt(s);i>65535&&s++,j+=4}return j},wt=(t,j,s)=>{s=v(s);var i,o,k;j===2?(i=Bt,o=bt,k=Jt):(i=Pt,o=Ot,k=Ut),x(t,{name:s,fromWireType:a=>{var u=h[a>>2],c=i(a+4,u*j,!0);return J(a),c},toWireType:(a,u)=>{typeof u!="string"&&G(\`Cannot pass non-string to C++ string type \${s}\`);var c=k(u),q=RA(4+c+j);return h[q>>2]=c/j,o(u,q+4,c+j),a!==null&&a.push(J,q),q},readValueFromPointer:GA,destructorFunction(a){J(a)}})},Tt=(t,j)=>{j=v(j),x(t,{isVoid:!0,name:j,fromWireType:()=>{},toWireType:(s,i)=>{}})},Kt=t=>{kA("OOM")},St=t=>{var j=H.length;t>>>=0,Kt(t)},Mt=t=>52,Vt=9007199254740992,Rt=-9007199254740992,Wt=t=>t<Rt||t>Vt?NaN:Number(t);function Qt(t,j,s,i){return j=Wt(j),70}var zt=[null,[],[]],Xt=(t,j)=>{var s=zt[t];j===0||j===10?((t===1?B:aA)(br(s)),s.length=0):s.push(j)},Zt=(t,j,s,i)=>{for(var o=0,k=0;k<s;k++){var a=h[j>>2],u=h[j+4>>2];j+=8;for(var c=0;c<u;c++)Xt(t,H[a+c]);o+=u}return h[i>>2]=o,0};At(),ct();{r.noExitRuntime&&(Kj=r.noExitRuntime),r.print&&(B=r.print),r.printErr&&(aA=r.printErr),r.arguments&&(C=r.arguments),r.thisProgram&&(p=r.thisProgram);var X=r.preInit;if(X)for(typeof X=="function"&&(r.preInit=X=[X]);X.length>0;)X.shift()()}var Pr,RA,J,Yt,Ae,Or,Ur;function re(t){Pr=t.w,RA=r._malloc=t.y,J=r._free=t.z,Yt=Or=t.u,Ae=Ur=t.x}var je={i:Vj,r:Rj,g:Qj,l:zj,k:ft,j:pt,d:Et,a:mt,s:Ft,f:vt,n:Dt,c:_t,b:yt,t:xt,e:wt,m:Tt,o:St,q:Mt,p:Qt,h:Zt};async function te(){xj();var t=r.setStatus;t&&(t("Running..."),await new Promise(j=>setTimeout(j,1)),setTimeout(t,1,"")),!or&&(Bj(),r.onRuntimeInitialized?.(),bj())}var jA;return jA=await Tj(),await te(),r}})();typeof $j=="object"&&typeof OA=="object"?(OA.exports=nr,OA.exports.default=nr):typeof define=="function"&&define.amd&&define([],()=>nr)});var w={};ke(w,{AdditionalCaptureBlocks:()=>Ce,AdditionalPlaybackBlocks:()=>de,ClockJumpCheckInterval:()=>he,ClockJumpThreshold:()=>$e,ConnectInterval:()=>Ne,ConnectTimeout:()=>Le,DefaultRefreshRate:()=>fe,DefaultVideoCodec:()=>Be,HealthCheckTimeout:()=>me,MainConnectionPingInterval:()=>Fe,MaxNumberOfDecoders:()=>pe,MaxReconnectDuration:()=>xe,MinDBFs:()=>Sr,MinTokenLifetime:()=>He,MinTokenRefreshInterval:()=>ge,PlaybackPreload:()=>qe,RenderQuantumSize:()=>Ee,VadPreload:()=>Ge,WebRtcAnswerTimeout:()=>_e,WebRtcIceTimeout:()=>ve,WebRtcMaxNegotiationAttempts:()=>ye,WebRtcStatsSnapshotInterval:()=>Ie,WebRtcTimeout:()=>De});var de=3,Ce=3,qe=3,fe=250,Ge=3,pe=512,Ee=128,Sr=-758.596,me=1e4,he=1e3,$e=1e4,Fe=3e3,Ie=1e3,ve=3e3,De=1e4,_e=1e4,ye=3,Le=5e3,He=6e4,ge=5e3,Ne=[0,100,200,200,500],xe=12e4,Be="H264";function T(e,A,r){return e.postMessage(A,r)}function Mr(e){return[e.values[0],e.values[1]]}function hA(e,A){e.values[0]=A[0],e.values[1]=A[1]}function $A(e,A){return e.values[2+A*5]}function Vr(e,A,r){e.values[2+A*5]=r}function Rr(e,A){let r=2+A*5+1;return[e.values[r+0],e.values[r+1]]}function FA(e,A,r){let n=2+A*5+1;e.values[n+0]=r[0],e.values[n+1]=r[1]}function Wr(e,A){return e.values[2+A*5+3]}function Qr(e,A,r){e.values[2+A*5+3]=r}function zr(e,A){return e.values[2+A*5+4]}function Xr(e,A,r){e.values[2+A*5+4]=r}function IA(e){return e.values[0]!==0}function vA(e){return e.values[1]}function DA(e){return e.values[2]}function Zr(e){return e.values[3]}function _A(e,A){return e.values[3]=A}function Yr(e){return e?Array.from(e).map(A=>A.toString(16).padStart(2,"0")).join(""):null}var be;(e=>{let A;(r=>(r[r.InvalidPassword=-1]="InvalidPassword",r[r.Unknown=0]="Unknown",r[r.Unencrypted=1]="Unencrypted",r[r.Encrypted=2]="Encrypted"))(A=e.PeerCipherStatus||={})})(be||={});function ej(e){return{type:"Success",value:e}}function g(e){return{type:"Failure",reason:e}}var{Deno:Aj}=globalThis,Je=typeof Aj?.noColor=="boolean"?Aj.noColor:!1,Pe=!Je;function XA(e,A){return{open:\`\\x1B[\${e.join(";")}m\`,close:\`\\x1B[\${A}m\`,regexp:new RegExp(\`\\\\x1b\\\\[\${A}m\`,"g")}}function ZA(e,A){return Pe?\`\${A.open}\${e.replace(A.regexp,A.open)}\${A.close}\`:e}function zA(e){return ZA(e,XA([0],0))}function rj(e){return ZA(e,XA([1],22))}function Oe(e){return ZA(e,XA([2],22))}var Bn=new RegExp(["[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)","(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TXZcf-nq-uy=><~]))"].join("|"),"g"),Ue=new Date,yA=(e=>(e[e.CRITICAL=0]="CRITICAL",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG",e))(yA||{}),nj={0:"\\u{1F4A5}",1:"\\u{1F534}",2:"\\u{1F7E1}",3:"\\u{1F535}",4:"\\u{1F7E3}"},we={4:Oe,3:zA,2:zA,1:rj,0:rj};function Te({message:e}){return String(e)}function jj(e){return JSON.stringify({timestamp:e.date.toISOString(),level:yA[e.level],message:e.message,extra:e.extra})}function tj(e){function A(C,p){return[Math.floor(C/p),C%p]}function r(){let C,p=e.date.valueOf()-Ue.valueOf();[p,C]=A(p,1e3);let[I,N]=A(p,60);return\`\${I.toString().padStart(4,"0")}:\${N.toString().padStart(2,"0")}.\${C.toString().padStart(3,"0")}\`}function n(){return e.extra===void 0?"":typeof Deno=="object"?" "+Deno.inspect(e.extra,{compact:!1,colors:!0,trailingComma:!0}).trimStart():" "+JSON.stringify(e.extra)}let l=nj[e.level],d=e.logger.name!==void 0?\`@\${e.logger.name}\`:"";return\`\${zA(r())}\${d} \${l} \${we[e.level](String(e.message))}\${n()}\`}function Ke(e){let A=\`[\${e.date.toISOString()}]\`,r=\`[\${yA[e.level]}]\`,n=e.logger.name!==void 0?\`[\${e.logger.name}] \`:"",l=nj[e.level];return\`\${A} \${l} \${r.padEnd(7," ")} \${n}\${e.message}\`}function Se(){return typeof Deno=="object"&&Deno.stdout.isTerminal()}var sj=class{static sparse=Te;static json=jj;static pretty=tj;static structured=Ke;static default=Se()?tj:jj;constructor(){}};var Me=class{formatter;consoleObject;filter;constructor(e=sj.default,A=4,r=console){this.filter=A,this.formatter=e,this.consoleObject=r}handle(e){let A=this.formatter(e);switch(e.level){case 0:case 1:this.consoleObject.error(A);break;case 2:this.consoleObject.warn(A);break;case 3:this.consoleObject.info(A);break;case 4:this.consoleObject.debug(A);break}}};var M=class{#A;sinks;filter;parent;get name(){return this.#A}constructor(e,A=void 0,r=[],n=void 0){this.#A=A,this.sinks=r,this.filter=e,this.parent=n}log(e,A,r=void 0){let n={date:new Date,level:e,logger:this,message:A,extra:r};this.filter<e||this.insert(n)}insert(e){if(!(this.filter<e.level)){for(let A of this.sinks)A.filter>=e.level&&A.handle(e);this.parent!==void 0&&this.parent.insert(e)}}error=this.log.bind(this,1);warn=this.log.bind(this,2);info=this.log.bind(this,3);debug=this.log.bind(this,4)},eA=globalThis[Symbol.for("odin-global-logger")]??=new M(3,void 0,[new Me]),Ve=M.prototype.log.bind(eA,1),Re=M.prototype.log.bind(eA,2),lj=M.prototype.log.bind(eA,3),We=M.prototype.log.bind(eA,4),bn=M.prototype.log.bind(eA);var ij;function oj(e,...A){let r=Qe(A);ij?ij?.info(e,r):lj(e,r)}function Qe(...e){if(e.length===1&&typeof e[0]=="object"&&e[0]!==null)return{...e[0]};if(e.length>0)return{args:e}}function LA(e){return e.connectionId*4294967296+e.mediaId}function aj(e){return{mediaId:e%4294967296,connectionId:Math.floor(e/4294967296)}}function O(e,A,r){let n;switch(A){case"f32":n=e.HEAPF32;break;case"u32":n=e.HEAPU32;break;case"i32":n=e.HEAP32;break;case"u8":n=e.HEAPU8;break;default:throw new Error(\`allocating \${A} is not supported\`)}let l=e._malloc(r*n.BYTES_PER_ELEMENT);if(l===0||l%n.BYTES_PER_ELEMENT!==0)throw new Error(\`failed allocating a \${r} \${A} array\`);let d=l/n.BYTES_PER_ELEMENT;return n.subarray(d,d+r)}function V(e,A){e._free(A.byteOffset)}function kj(e,A){return{values:O(e,"f32",2+A*5),length:A}}function uj(e,A){V(e,A.values)}function cj(e){return{values:O(e,"f32",4)}}function dj(e,A){V(e,A.values)}function Cj(e){let A=e.length,r=0,n=0;for(;n<A;){let l=e.charCodeAt(n++);if((l&4294967168)===0){r++;continue}else if((l&4294965248)===0)r+=2;else{if(l>=55296&&l<=56319&&n<A){let d=e.charCodeAt(n);(d&64512)===56320&&(++n,l=((l&1023)<<10)+(d&1023)+65536)}(l&4294901760)===0?r+=3:r+=4}}return r}function ze(e,A,r){let n=e.length,l=r,d=0;for(;d<n;){let C=e.charCodeAt(d++);if((C&4294967168)===0){A[l++]=C;continue}else if((C&4294965248)===0)A[l++]=C>>6&31|192;else{if(C>=55296&&C<=56319&&d<n){let p=e.charCodeAt(d);(p&64512)===56320&&(++d,C=((C&1023)<<10)+(p&1023)+65536)}(C&4294901760)===0?(A[l++]=C>>12&15|224,A[l++]=C>>6&63|128):(A[l++]=C>>18&7|240,A[l++]=C>>12&63|128,A[l++]=C>>6&63|128)}A[l++]=C&63|128}}var Xe=new TextEncoder,Ze=50;function Ye(e,A,r){Xe.encodeInto(e,A.subarray(r))}function qj(e,A,r){e.length>Ze?Ye(e,A,r):ze(e,A,r)}var An=4096;function YA(e,A,r){let n=A,l=n+r,d=[],C="";for(;n<l;){let p=e[n++];if((p&128)===0)d.push(p);else if((p&224)===192){let I=e[n++]&63;d.push((p&31)<<6|I)}else if((p&240)===224){let I=e[n++]&63,N=e[n++]&63;d.push((p&31)<<12|I<<6|N)}else if((p&248)===240){let I=e[n++]&63,N=e[n++]&63,UA=e[n++]&63,B=(p&7)<<18|I<<12|N<<6|UA;B>65535&&(B-=65536,d.push(B>>>10&1023|55296),B=56320|B&1023),d.push(B)}else d.push(p);d.length>=An&&(C+=String.fromCharCode(...d),d.length=0)}return d.length>0&&(C+=String.fromCharCode(...d)),C}var rn=new TextDecoder,jn=200;function tn(e,A,r){let n=e.subarray(A,A+r);return rn.decode(n)}function fj(e,A,r){return r>jn?tn(e,A,r):YA(e,A,r)}var R=class{type;data;constructor(A,r){this.type=A,this.data=r}};var D=class e extends Error{constructor(A){super(A);let r=Object.create(e.prototype);Object.setPrototypeOf(this,r),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:e.name})}};function Gj(e,A,r){let n=r/4294967296,l=r;e.setUint32(A,n),e.setUint32(A+4,l)}function HA(e,A,r){let n=Math.floor(r/4294967296),l=r;e.setUint32(A,n),e.setUint32(A+4,l)}function gA(e,A){let r=e.getInt32(A),n=e.getUint32(A+4);return r*4294967296+n}function pj(e,A){let r=e.getUint32(A),n=e.getUint32(A+4);return r*4294967296+n}var en=-1,nn=4294967296-1,sn=17179869184-1;function ln({sec:e,nsec:A}){if(e>=0&&A>=0&&e<=sn)if(A===0&&e<=nn){let r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,e),r}else{let r=e/4294967296,n=e&4294967295,l=new Uint8Array(8),d=new DataView(l.buffer);return d.setUint32(0,A<<2|r&3),d.setUint32(4,n),l}else{let r=new Uint8Array(12),n=new DataView(r.buffer);return n.setUint32(0,A),HA(n,4,e),r}}function on(e){let A=e.getTime(),r=Math.floor(A/1e3),n=(A-r*1e3)*1e6,l=Math.floor(n/1e9);return{sec:r+l,nsec:n-l*1e9}}function an(e){if(e instanceof Date){let A=on(e);return ln(A)}else return null}function kn(e){let A=new DataView(e.buffer,e.byteOffset,e.byteLength);switch(e.byteLength){case 4:return{sec:A.getUint32(0),nsec:0};case 8:{let r=A.getUint32(0),n=A.getUint32(4),l=(r&3)*4294967296+n,d=r>>>2;return{sec:l,nsec:d}}case 12:{let r=gA(A,4),n=A.getUint32(0);return{sec:r,nsec:n}}default:throw new D(\`Unrecognized data size for timestamp (expected 4, 8, or 12): \${e.length}\`)}}function un(e){let A=kn(e);return new Date(A.sec*1e3+A.nsec/1e6)}var Ej={type:en,encode:an,decode:un};var Z=class e{static defaultCodec=new e;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(Ej)}register({type:A,encode:r,decode:n}){if(A>=0)this.encoders[A]=r,this.decoders[A]=n;else{let l=-1-A;this.builtInEncoders[l]=r,this.builtInDecoders[l]=n}}tryToEncode(A,r){for(let n=0;n<this.builtInEncoders.length;n++){let l=this.builtInEncoders[n];if(l!=null){let d=l(A,r);if(d!=null){let C=-1-n;return new R(C,d)}}}for(let n=0;n<this.encoders.length;n++){let l=this.encoders[n];if(l!=null){let d=l(A,r);if(d!=null){let C=n;return new R(C,d)}}}return A instanceof R?A:null}decode(A,r,n){let l=r<0?this.builtInDecoders[-1-r]:this.decoders[r];return l?l(A,r,n):new R(r,A)}};function cn(e){return e instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&e instanceof SharedArrayBuffer}function nA(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):cn(e)?new Uint8Array(e):Uint8Array.from(e)}var dn=100,Cn=2048,NA=class e{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(A){this.extensionCodec=A?.extensionCodec??Z.defaultCodec,this.context=A?.context,this.useBigInt64=A?.useBigInt64??!1,this.maxDepth=A?.maxDepth??dn,this.initialBufferSize=A?.initialBufferSize??Cn,this.sortKeys=A?.sortKeys??!1,this.forceFloat32=A?.forceFloat32??!1,this.ignoreUndefined=A?.ignoreUndefined??!1,this.forceIntegerToFloat=A?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new e({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(A){if(this.entered)return this.clone().encodeSharedRef(A);try{return this.entered=!0,this.reinitializeState(),this.doEncode(A,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(A){if(this.entered)return this.clone().encode(A);try{return this.entered=!0,this.reinitializeState(),this.doEncode(A,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(A,r){if(r>this.maxDepth)throw new Error(\`Too deep objects in depth \${r}\`);A==null?this.encodeNil():typeof A=="boolean"?this.encodeBoolean(A):typeof A=="number"?this.forceIntegerToFloat?this.encodeNumberAsFloat(A):this.encodeNumber(A):typeof A=="string"?this.encodeString(A):this.useBigInt64&&typeof A=="bigint"?this.encodeBigInt64(A):this.encodeObject(A,r)}ensureBufferSizeToWrite(A){let r=this.pos+A;this.view.byteLength<r&&this.resizeBuffer(r*2)}resizeBuffer(A){let r=new ArrayBuffer(A),n=new Uint8Array(r),l=new DataView(r);n.set(this.bytes),this.view=l,this.bytes=n}encodeNil(){this.writeU8(192)}encodeBoolean(A){A===!1?this.writeU8(194):this.writeU8(195)}encodeNumber(A){!this.forceIntegerToFloat&&Number.isSafeInteger(A)?A>=0?A<128?this.writeU8(A):A<256?(this.writeU8(204),this.writeU8(A)):A<65536?(this.writeU8(205),this.writeU16(A)):A<4294967296?(this.writeU8(206),this.writeU32(A)):this.useBigInt64?this.encodeNumberAsFloat(A):(this.writeU8(207),this.writeU64(A)):A>=-32?this.writeU8(224|A+32):A>=-128?(this.writeU8(208),this.writeI8(A)):A>=-32768?(this.writeU8(209),this.writeI16(A)):A>=-2147483648?(this.writeU8(210),this.writeI32(A)):this.useBigInt64?this.encodeNumberAsFloat(A):(this.writeU8(211),this.writeI64(A)):this.encodeNumberAsFloat(A)}encodeNumberAsFloat(A){this.forceFloat32?(this.writeU8(202),this.writeF32(A)):(this.writeU8(203),this.writeF64(A))}encodeBigInt64(A){A>=BigInt(0)?(this.writeU8(207),this.writeBigUint64(A)):(this.writeU8(211),this.writeBigInt64(A))}writeStringHeader(A){if(A<32)this.writeU8(160+A);else if(A<256)this.writeU8(217),this.writeU8(A);else if(A<65536)this.writeU8(218),this.writeU16(A);else if(A<4294967296)this.writeU8(219),this.writeU32(A);else throw new Error(\`Too long string: \${A} bytes in UTF-8\`)}encodeString(A){let n=Cj(A);this.ensureBufferSizeToWrite(5+n),this.writeStringHeader(n),qj(A,this.bytes,this.pos),this.pos+=n}encodeObject(A,r){let n=this.extensionCodec.tryToEncode(A,this.context);if(n!=null)this.encodeExtension(n);else if(Array.isArray(A))this.encodeArray(A,r);else if(ArrayBuffer.isView(A))this.encodeBinary(A);else if(typeof A=="object")this.encodeMap(A,r);else throw new Error(\`Unrecognized object: \${Object.prototype.toString.apply(A)}\`)}encodeBinary(A){let r=A.byteLength;if(r<256)this.writeU8(196),this.writeU8(r);else if(r<65536)this.writeU8(197),this.writeU16(r);else if(r<4294967296)this.writeU8(198),this.writeU32(r);else throw new Error(\`Too large binary: \${r}\`);let n=nA(A);this.writeU8a(n)}encodeArray(A,r){let n=A.length;if(n<16)this.writeU8(144+n);else if(n<65536)this.writeU8(220),this.writeU16(n);else if(n<4294967296)this.writeU8(221),this.writeU32(n);else throw new Error(\`Too large array: \${n}\`);for(let l of A)this.doEncode(l,r+1)}countWithoutUndefined(A,r){let n=0;for(let l of r)A[l]!==void 0&&n++;return n}encodeMap(A,r){let n=Object.keys(A);this.sortKeys&&n.sort();let l=this.ignoreUndefined?this.countWithoutUndefined(A,n):n.length;if(l<16)this.writeU8(128+l);else if(l<65536)this.writeU8(222),this.writeU16(l);else if(l<4294967296)this.writeU8(223),this.writeU32(l);else throw new Error(\`Too large map object: \${l}\`);for(let d of n){let C=A[d];this.ignoreUndefined&&C===void 0||(this.encodeString(d),this.doEncode(C,r+1))}}encodeExtension(A){if(typeof A.data=="function"){let n=A.data(this.pos+6),l=n.length;if(l>=4294967296)throw new Error(\`Too large extension object: \${l}\`);this.writeU8(201),this.writeU32(l),this.writeI8(A.type),this.writeU8a(n);return}let r=A.data.length;if(r===1)this.writeU8(212);else if(r===2)this.writeU8(213);else if(r===4)this.writeU8(214);else if(r===8)this.writeU8(215);else if(r===16)this.writeU8(216);else if(r<256)this.writeU8(199),this.writeU8(r);else if(r<65536)this.writeU8(200),this.writeU16(r);else if(r<4294967296)this.writeU8(201),this.writeU32(r);else throw new Error(\`Too large extension object: \${r}\`);this.writeI8(A.type),this.writeU8a(A.data)}writeU8(A){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,A),this.pos++}writeU8a(A){let r=A.length;this.ensureBufferSizeToWrite(r),this.bytes.set(A,this.pos),this.pos+=r}writeI8(A){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,A),this.pos++}writeU16(A){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,A),this.pos+=2}writeI16(A){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,A),this.pos+=2}writeU32(A){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,A),this.pos+=4}writeI32(A){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,A),this.pos+=4}writeF32(A){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,A),this.pos+=4}writeF64(A){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,A),this.pos+=8}writeU64(A){this.ensureBufferSizeToWrite(8),Gj(this.view,this.pos,A),this.pos+=8}writeI64(A){this.ensureBufferSizeToWrite(8),HA(this.view,this.pos,A),this.pos+=8}writeBigUint64(A){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,A),this.pos+=8}writeBigInt64(A){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,A),this.pos+=8}};function Ar(e,A){return new NA(A).encodeSharedRef(e)}function xA(e){return\`\${e<0?"-":""}0x\${Math.abs(e).toString(16).padStart(2,"0")}\`}var qn=16,fn=16,BA=class{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(A=qn,r=fn){this.maxKeyLength=A,this.maxLengthPerKey=r,this.caches=[];for(let n=0;n<this.maxKeyLength;n++)this.caches.push([])}canBeCached(A){return A>0&&A<=this.maxKeyLength}find(A,r,n){let l=this.caches[n-1];A:for(let d of l){let C=d.bytes;for(let p=0;p<n;p++)if(C[p]!==A[r+p])continue A;return d.str}return null}store(A,r){let n=this.caches[A.length-1],l={bytes:A,str:r};n.length>=this.maxLengthPerKey?n[Math.random()*n.length|0]=l:n.push(l)}decode(A,r,n){let l=this.find(A,r,n);if(l!=null)return this.hit++,l;this.miss++;let d=YA(A,r,n),C=Uint8Array.prototype.slice.call(A,r,r+n);return this.store(C,d),d}};var rr="array",iA="map_key",hj="map_value",Gn=e=>{if(typeof e=="string"||typeof e=="number")return e;throw new D("The type of key must be string or number but "+typeof e)},jr=class{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(A){let r=this.getUninitializedStateFromPool();r.type=rr,r.position=0,r.size=A,r.array=new Array(A)}pushMapState(A){let r=this.getUninitializedStateFromPool();r.type=iA,r.readCount=0,r.size=A,r.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let A={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(A)}return this.stack[this.stackHeadPosition]}release(A){if(this.stack[this.stackHeadPosition]!==A)throw new Error("Invalid stack state. Released state is not on top of the stack.");if(A.type===rr){let n=A;n.size=0,n.array=void 0,n.position=0,n.type=void 0}if(A.type===iA||A.type===hj){let n=A;n.size=0,n.map=void 0,n.readCount=0,n.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}},lA=-1,tr=new DataView(new ArrayBuffer(0)),pn=new Uint8Array(tr.buffer);try{tr.getInt8(0)}catch(e){if(!(e instanceof RangeError))throw new Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var mj=new RangeError("Insufficient data"),En=new BA,bA=class e{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=tr;bytes=pn;headByte=lA;stack=new jr;entered=!1;constructor(A){this.extensionCodec=A?.extensionCodec??Z.defaultCodec,this.context=A?.context,this.useBigInt64=A?.useBigInt64??!1,this.rawStrings=A?.rawStrings??!1,this.maxStrLength=A?.maxStrLength??4294967295,this.maxBinLength=A?.maxBinLength??4294967295,this.maxArrayLength=A?.maxArrayLength??4294967295,this.maxMapLength=A?.maxMapLength??4294967295,this.maxExtLength=A?.maxExtLength??4294967295,this.keyDecoder=A?.keyDecoder!==void 0?A.keyDecoder:En,this.mapKeyConverter=A?.mapKeyConverter??Gn}clone(){return new e({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=lA,this.stack.reset()}setBuffer(A){let r=nA(A);this.bytes=r,this.view=new DataView(r.buffer,r.byteOffset,r.byteLength),this.pos=0}appendBuffer(A){if(this.headByte===lA&&!this.hasRemaining(1))this.setBuffer(A);else{let r=this.bytes.subarray(this.pos),n=nA(A),l=new Uint8Array(r.length+n.length);l.set(r),l.set(n,r.length),this.setBuffer(l)}}hasRemaining(A){return this.view.byteLength-this.pos>=A}createExtraByteError(A){let{view:r,pos:n}=this;return new RangeError(\`Extra \${r.byteLength-n} of \${r.byteLength} byte(s) found at buffer[\${A}]\`)}decode(A){if(this.entered)return this.clone().decode(A);try{this.entered=!0,this.reinitializeState(),this.setBuffer(A);let r=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return r}finally{this.entered=!1}}*decodeMulti(A){if(this.entered){yield*this.clone().decodeMulti(A);return}try{for(this.entered=!0,this.reinitializeState(),this.setBuffer(A);this.hasRemaining(1);)yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(A){if(this.entered)return this.clone().decodeAsync(A);try{this.entered=!0;let r=!1,n;for await(let p of A){if(r)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(p);try{n=this.doDecodeSync(),r=!0}catch(I){if(!(I instanceof RangeError))throw I}this.totalPos+=this.pos}if(r){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return n}let{headByte:l,pos:d,totalPos:C}=this;throw new RangeError(\`Insufficient data in parsing \${xA(l)} at \${C} (\${d} in the current buffer)\`)}finally{this.entered=!1}}decodeArrayStream(A){return this.decodeMultiAsync(A,!0)}decodeStream(A){return this.decodeMultiAsync(A,!1)}async*decodeMultiAsync(A,r){if(this.entered){yield*this.clone().decodeMultiAsync(A,r);return}try{this.entered=!0;let n=r,l=-1;for await(let d of A){if(r&&l===0)throw this.createExtraByteError(this.totalPos);this.appendBuffer(d),n&&(l=this.readArraySize(),n=!1,this.complete());try{for(;yield this.doDecodeSync(),--l!==0;);}catch(C){if(!(C instanceof RangeError))throw C}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){A:for(;;){let A=this.readHeadByte(),r;if(A>=224)r=A-256;else if(A<192)if(A<128)r=A;else if(A<144){let l=A-128;if(l!==0){this.pushMapState(l),this.complete();continue A}else r={}}else if(A<160){let l=A-144;if(l!==0){this.pushArrayState(l),this.complete();continue A}else r=[]}else{let l=A-160;r=this.decodeString(l,0)}else if(A===192)r=null;else if(A===194)r=!1;else if(A===195)r=!0;else if(A===202)r=this.readF32();else if(A===203)r=this.readF64();else if(A===204)r=this.readU8();else if(A===205)r=this.readU16();else if(A===206)r=this.readU32();else if(A===207)this.useBigInt64?r=this.readU64AsBigInt():r=this.readU64();else if(A===208)r=this.readI8();else if(A===209)r=this.readI16();else if(A===210)r=this.readI32();else if(A===211)this.useBigInt64?r=this.readI64AsBigInt():r=this.readI64();else if(A===217){let l=this.lookU8();r=this.decodeString(l,1)}else if(A===218){let l=this.lookU16();r=this.decodeString(l,2)}else if(A===219){let l=this.lookU32();r=this.decodeString(l,4)}else if(A===220){let l=this.readU16();if(l!==0){this.pushArrayState(l),this.complete();continue A}else r=[]}else if(A===221){let l=this.readU32();if(l!==0){this.pushArrayState(l),this.complete();continue A}else r=[]}else if(A===222){let l=this.readU16();if(l!==0){this.pushMapState(l),this.complete();continue A}else r={}}else if(A===223){let l=this.readU32();if(l!==0){this.pushMapState(l),this.complete();continue A}else r={}}else if(A===196){let l=this.lookU8();r=this.decodeBinary(l,1)}else if(A===197){let l=this.lookU16();r=this.decodeBinary(l,2)}else if(A===198){let l=this.lookU32();r=this.decodeBinary(l,4)}else if(A===212)r=this.decodeExtension(1,0);else if(A===213)r=this.decodeExtension(2,0);else if(A===214)r=this.decodeExtension(4,0);else if(A===215)r=this.decodeExtension(8,0);else if(A===216)r=this.decodeExtension(16,0);else if(A===199){let l=this.lookU8();r=this.decodeExtension(l,1)}else if(A===200){let l=this.lookU16();r=this.decodeExtension(l,2)}else if(A===201){let l=this.lookU32();r=this.decodeExtension(l,4)}else throw new D(\`Unrecognized type byte: \${xA(A)}\`);this.complete();let n=this.stack;for(;n.length>0;){let l=n.top();if(l.type===rr)if(l.array[l.position]=r,l.position++,l.position===l.size)r=l.array,n.release(l);else continue A;else if(l.type===iA){if(r==="__proto__")throw new D("The key __proto__ is not allowed");l.key=this.mapKeyConverter(r),l.type=hj;continue A}else if(l.map[l.key]=r,l.readCount++,l.readCount===l.size)r=l.map,n.release(l);else{l.key=null,l.type=iA;continue A}}return r}}readHeadByte(){return this.headByte===lA&&(this.headByte=this.readU8()),this.headByte}complete(){this.headByte=lA}readArraySize(){let A=this.readHeadByte();switch(A){case 220:return this.readU16();case 221:return this.readU32();default:{if(A<160)return A-144;throw new D(\`Unrecognized array type byte: \${xA(A)}\`)}}}pushMapState(A){if(A>this.maxMapLength)throw new D(\`Max length exceeded: map length (\${A}) > maxMapLengthLength (\${this.maxMapLength})\`);this.stack.pushMapState(A)}pushArrayState(A){if(A>this.maxArrayLength)throw new D(\`Max length exceeded: array length (\${A}) > maxArrayLength (\${this.maxArrayLength})\`);this.stack.pushArrayState(A)}decodeString(A,r){return!this.rawStrings||this.stateIsMapKey()?this.decodeUtf8String(A,r):this.decodeBinary(A,r)}decodeUtf8String(A,r){if(A>this.maxStrLength)throw new D(\`Max length exceeded: UTF-8 byte length (\${A}) > maxStrLength (\${this.maxStrLength})\`);if(this.bytes.byteLength<this.pos+r+A)throw mj;let n=this.pos+r,l;return this.stateIsMapKey()&&this.keyDecoder?.canBeCached(A)?l=this.keyDecoder.decode(this.bytes,n,A):l=fj(this.bytes,n,A),this.pos+=r+A,l}stateIsMapKey(){return this.stack.length>0?this.stack.top().type===iA:!1}decodeBinary(A,r){if(A>this.maxBinLength)throw new D(\`Max length exceeded: bin length (\${A}) > maxBinLength (\${this.maxBinLength})\`);if(!this.hasRemaining(A+r))throw mj;let n=this.pos+r,l=this.bytes.subarray(n,n+A);return this.pos+=r+A,l}decodeExtension(A,r){if(A>this.maxExtLength)throw new D(\`Max length exceeded: ext length (\${A}) > maxExtLength (\${this.maxExtLength})\`);let n=this.view.getInt8(this.pos+r),l=this.decodeBinary(A,r+1);return this.extensionCodec.decode(l,n,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let A=this.view.getUint8(this.pos);return this.pos++,A}readI8(){let A=this.view.getInt8(this.pos);return this.pos++,A}readU16(){let A=this.view.getUint16(this.pos);return this.pos+=2,A}readI16(){let A=this.view.getInt16(this.pos);return this.pos+=2,A}readU32(){let A=this.view.getUint32(this.pos);return this.pos+=4,A}readI32(){let A=this.view.getInt32(this.pos);return this.pos+=4,A}readU64(){let A=pj(this.view,this.pos);return this.pos+=8,A}readI64(){let A=gA(this.view,this.pos);return this.pos+=8,A}readU64AsBigInt(){let A=this.view.getBigUint64(this.pos);return this.pos+=8,A}readI64AsBigInt(){let A=this.view.getBigInt64(this.pos);return this.pos+=8,A}readF32(){let A=this.view.getFloat32(this.pos);return this.pos+=4,A}readF64(){let A=this.view.getFloat64(this.pos);return this.pos+=8,A}};function er(e,A){return new bA(A).decode(e)}var oA=class e{constructor(A,r,n,l,d){this.mediaIds=A;this.sequenceNumber=r;this.timeStamp=n;this.isEndOfSpurt=l;this.payload=d}static parse(A){let r;try{r=er(A)}catch{return g("not valid msgpack")}if(!Array.isArray(r))return g("container must be an array");if(r.length<6)return g("missing fields");if(r[0]!==1)return g("unknown type");if(!Array.isArray(r[1]))return g("media ids must be an array");if(!r[1].every(N=>typeof N=="number"))return g("media ids must be numbers");if(typeof r[2]!="number")return g("sequence number must be a number");if(typeof r[3]!="number")return g("timestamp must be a number");if(typeof r[4]!="number")return g("flags must be a number");let n=r[1],l=r[2]>>>0,d=r[3]>>>0,p=(r[4]&1)!==0,I=r[r.length-1];return I instanceof Uint8Array?ej(new e(n,l,d,p,I)):g("payload must be bytes")}toBytes(){let A=Number(this.isEndOfSpurt),r=[1,this.mediaIds,this.sequenceNumber>>>0,this.timeStamp>>>0,A,this.payload];return new Uint8Array(Ar(r,{forceFloat32:!0,ignoreUndefined:!0}))}};var JA=class{constructor(A,r){this.sampleRate=A;this.wasm=r;this.sequenceNumber=Math.random()*Math.pow(2,32)>>0;this.timestamp=Math.random()*Math.pow(2,32)>>0;this.connections=[];this.monitoring=!1;this.active=!1;this.stats={numberPackets:0,numberTicks:0,numberPacketError:0,numberPacketsMediaNotFound:0};this.encoder=new r.Encoder(A,15,!0,w.VadPreload),this.encoder.complexity=navigator.hardwareConcurrency>=4?6:4,this.information=cj(this.wasm),this.outBuffer=O(this.wasm,"u8",1270),_A(this.information,1)}setVad(A){this.encoder.set_volume_gate(A.volumeGate!==void 0,A.volumeGate?.attackThreshold??0,A.volumeGate?.releaseThreshold??0),this.encoder.set_speech_detection(A.voiceActivity!==void 0,A.voiceActivity?.attackThreshold??0,A.voiceActivity?.releaseThreshold??0)}setMedias(A){this.connections=A.filter(({mediaIds:r})=>r.length>0)}close(){dj(this.wasm,this.information),V(this.wasm,this.outBuffer),this.encoder.delete()}encode(A){for(this.encoder.push(A.byteOffset,this.information.values.byteOffset);;){let r=this.encoder.pop(this.connections.length===0?0:this.outBuffer.byteOffset,this.outBuffer.length);if(r===0)break;if(r<0){oj(\`failed encoding packet: \${r}\`);return}if(this.timestamp=this.timestamp+1800>>0,r===1)continue;this.sequenceNumber=this.sequenceNumber+1>>0;let n=this.active&&!this.encoder.active;this.active=this.encoder.active,this.monitoring=this.connections.some(l=>l.id===0);for(let l of this.connections){if(this.monitoring&&l.id!==0)continue;let d=new oA(l.mediaIds,this.sequenceNumber,this.timestamp,n,this.outBuffer.subarray(0,r));T(globalThis,["sendPacket",{connectionId:l.id,packet:d.toBytes()}])}}}onMessage(A){let[r,n]=A;switch(r){case"captureSetVad":this?.setVad(n);break;case"captureSetMedias":this?.setMedias(n.connections);break;case"close":this.close();break;case"dump":n.result.postMessage(this.dump());break}}dump(){return{sequenceNumber:this.sequenceNumber,timestamp:this.timestamp,connections:this.connections.map(A=>\`\${A.id} => \${A.mediaIds.join(",")}\`),active:this.active,monitoring:this.monitoring,information:{active:IA(this.information),speechProbability:vA(this.information),rmsDBFS:DA(this.information),volume:Zr(this.information)},encoder:{sample_rate:this.encoder.sample_rate,fec_packet_loss:this.encoder.fec_packet_loss,voip:this.encoder.voip,vad_preload:this.encoder.vad_preload,complexity:this.encoder.complexity,speech_probability:this.encoder.speech_probability,rms_dbfs:this.encoder.rms_dbfs,active:this.encoder.active,speech_detection_enabled:this.encoder.speech_detection_enabled,speech_detection_going_active:this.encoder.speech_detection_going_active,speech_detection_going_inactive:this.encoder.speech_detection_going_inactive,volume_gate_enabled:this.encoder.volume_gate_enabled,volume_gate_going_active:this.encoder.volume_gate_going_active,volume_gate_going_inactive:this.encoder.volume_gate_going_inactive}}}},PA=class{constructor(A){this.wasm=A;this.medias=new Map;this.stats={numberPackets:0,numberTicks:0,numberPacketError:0,numberPacketsMediaNotFound:0,numberTicksWithAudio:0};this.largestIndex=-1;this.decoders=O(this.wasm,"u32",w.MaxNumberOfDecoders),this.information=kj(this.wasm,w.MaxNumberOfDecoders),hA(this.information,[1,1])}close(){uj(this.wasm,this.information);for(let{decoder:A}of this.medias.values())A.delete()}receivePacket(A,r){this.stats.numberPackets++;let n=oA.parse(r);if(n.type==="Failure"){this.stats.numberPacketError++;let l=Array.from(r).map(d=>d.toString(16).padStart(2,"0")).join("");console.error(\`failed decoding audio packet; reason: \${n.reason}, connection: \${A}, dump: \${l}\`);return}for(let l of n.value.mediaIds){let d=this.medias.get(LA({connectionId:A,mediaId:l}));if(d===void 0){this.stats.numberPacketsMediaNotFound++;continue}d.lastPacket=r;let C=O(this.wasm,"u8",n.value.payload.length);C.set(n.value.payload),d.decoder.push(n.value.sequenceNumber,n.value.timeStamp,n.value.isEndOfSpurt,C.byteOffset,C.length)}}insertMedia(A,r,n,l=[1,1]){let d=LA({connectionId:r,mediaId:n}),C=new this.wasm.Decoder;this.medias.set(d,{index:A,decoder:C,lastPacket:void 0}),this.decoders[A]=C.$$.ptr,this.largestIndex=Math.max(this.largestIndex,A),FA(this.information,A,l),Xr(this.information,A,0),Qr(this.information,A,0)}removeMedia(A,r,n){let l=LA({connectionId:r,mediaId:n}),d=this.medias.get(l);if(!(d===void 0||d.index!==A)&&(this.medias.delete(l),Vr(this.information,A,0),this.decoders[A]=0,d.decoder.delete(),A===this.largestIndex)){for(A=A-1;A>=0&&this.decoders[A]===0;A--);this.largestIndex=A}}decode(A){return{hasAudio:this.wasm.pop_many(this.decoders.byteOffset,this.information.values.byteOffset,this.largestIndex+1,A.byteOffset)}}onMessage(A){let[r,n]=A;switch(r){case"playbackReceivePacket":this.receivePacket(n.connectionId,n.packet);break;case"playbackUpdateMedias":for(let{index:l,connectionId:d,mediaId:C}of n.removed)this.removeMedia(l,d,C);for(let{index:l,connectionId:d,mediaId:C,volume:p}of n.added)this.insertMedia(l,d,C,p);break;case"close":this.close();break;case"dump":n.result.postMessage(this.dump());break}}dump(){let A=[];for(let[r,n]of this.medias){let l=aj(r);A.push({index:n.index,connectionId:l.connectionId,mediaId:l.mediaId,rmsDBFS:$A(this.information,n.index),volume:Rr(this.information,n.index),voicedBlocks:zr(this.information,n.index),silentBlocks:Wr(this.information,n.index),time:n.decoder.time,consecutive_silence:n.decoder.consecutive_silence,last_voiced_time_point:n.decoder.last_voiced_time_point,sequence_number:n.decoder.sequence_number,packetsSeen:n.decoder.packets_seen,packetsInvalid:n.decoder.packets_invalid,packetsTooLate:n.decoder.packets_too_late,packetsTooEarly:n.decoder.packets_too_early,packetsRepeated:n.decoder.packets_repeated,packetsProcessed:n.decoder.packets_processed,packetsLost:n.decoder.packets_lost,rewinds:n.decoder.rewinds,cacheLength:n.decoder.cache_length,lastPacket:Yr(n.lastPacket)})}return{largestIndex:this.largestIndex,globalVolume:Mr(this.information),decoders:A}}};var _j=ce(Fj()),Ij=(0,_j.default)(),vj,Dj;globalThis.addEventListener("message",sr);async function sr(e){let A=e.data,[r,n]=A;switch(r){case"captureInit":n.workletPort.onmessage=sr,vj=new lr(n.sampleRate,await Ij,n.refreshRate);break;case"playbackInit":n.workletPort.onmessage=sr,Dj=new ir(await Ij,n.workletPort,n.refreshRate);break;case"close":globalThis.close();break}vj?.onMessage(A),Dj?.onMessage(A)}var lr=class extends JA{constructor(r,n,l){super(r,n);this.sampleRate=r;this.inBuffer=O(this.wasm,"f32",r*.02),this.updateHandle=setInterval(()=>this.update(),l),T(globalThis,["captureReady",{}])}close(){super.close(),V(this.wasm,this.inBuffer),clearInterval(this.updateHandle)}onMessage(r){super.onMessage(r);let[n,l]=r;switch(n){case"captureSetVolume":this.setVolume(l.value);break;case"captureTick":this.tick(l.buffer);break}}setVolume(r){_A(this.information,r)}tick(r){this.inBuffer.set(r,0),this.encode(this.inBuffer)}update(){T(globalThis,["captureUpdate",{active:IA(this.information),rmsDBFs:DA(this.information),speechProbability:vA(this.information)}])}dump(){return{type:"unshared capture worker",sampleRate:this.sampleRate,...super.dump()}}},ir=class extends PA{constructor(r,n,l){super(r);this.workletPort=n;this.id=w.PlaybackPreload,this.outBuffer=O(this.wasm,"f32",48e3*.02*2),this.updateHandle=setInterval(()=>this.update(),l),T(globalThis,["playbackReady",{}])}close(){super.close(),V(this.wasm,this.outBuffer),clearInterval(this.updateHandle)}onMessage(r){super.onMessage(r);let[n,l]=r;switch(n){case"playbackSetVolume":this.setVolume(l.index,l.value);break;case"playbackTick":this.tick();break}}setVolume(r,n){r==="global"?hA(this.information,n):FA(this.information,r,n)}tick(){this.stats.numberTicks++,this.id+=1;let{hasAudio:r}=this.decode(this.outBuffer);if(r){let n=this.outBuffer.slice();T(this.workletPort,["samples",{id:this.id,buffer:n}],[n.buffer])}}update(){let r=new Float32Array(this.information.length*2);for(let l=0;l<=this.largestIndex;l++)r[l]=$A(this.information,l);let n=[];for(let[l,d]of this.medias)n[d.index]={packetsBuffered:d.decoder.cache_length,packetsSeen:d.decoder.packets_seen,packetsProcessed:d.decoder.packets_processed,packetsTooEarly:d.decoder.packets_too_early,packetsTooLate:d.decoder.packets_too_late,packetsDropped:0,packetsInvalid:d.decoder.packets_invalid,packetsRepeated:d.decoder.packets_repeated,packetsLost:d.decoder.packets_lost};T(globalThis,["playbackUpdate",{activities:r,jitterStats:n}],[r.buffer])}dump(){return{type:"unshared playback worker",id:this.id,...super.dump()}}};})();
6452
- `});var C0,T0=d(()=>{C0='"use strict";(()=>{var P=Object.defineProperty;var M=(e,t)=>{for(var r in t)P(e,r,{get:t[r],enumerable:!0})};var u={};M(u,{AdditionalCaptureBlocks:()=>E,AdditionalPlaybackBlocks:()=>R,ClockJumpCheckInterval:()=>_,ClockJumpThreshold:()=>N,ConnectInterval:()=>Q,ConnectTimeout:()=>G,DefaultRefreshRate:()=>D,DefaultVideoCodec:()=>K,HealthCheckTimeout:()=>O,MainConnectionPingInterval:()=>W,MaxNumberOfDecoders:()=>L,MaxReconnectDuration:()=>Y,MinDBFs:()=>v,MinTokenLifetime:()=>Z,MinTokenRefreshInterval:()=>q,PlaybackPreload:()=>F,RenderQuantumSize:()=>V,VadPreload:()=>C,WebRtcAnswerTimeout:()=>J,WebRtcIceTimeout:()=>$,WebRtcMaxNegotiationAttempts:()=>z,WebRtcStatsSnapshotInterval:()=>j,WebRtcTimeout:()=>H});var R=3,E=3,F=3,D=250,C=3,L=512,V=128,v=-758.596,O=1e4,_=1e3,N=1e4,W=3e3,j=1e3,$=3e3,H=1e4,J=1e4,z=3,G=5e3,Z=6e4,q=5e3,Q=[0,100,200,200,500],Y=12e4,K="H264";function d(e,t,r){return e.postMessage(t,r)}var X;(e=>{let t;(r=>(r[r.InvalidPassword=-1]="InvalidPassword",r[r.Unknown=0]="Unknown",r[r.Unencrypted=1]="Unencrypted",r[r.Encrypted=2]="Encrypted"))(t=e.PeerCipherStatus||={})})(X||={});var{Deno:k}=globalThis,ee=typeof k?.noColor=="boolean"?k.noColor:!1,te=!ee;function m(e,t){return{open:`\\x1B[${e.join(";")}m`,close:`\\x1B[${t}m`,regexp:new RegExp(`\\\\x1b\\\\[${t}m`,"g")}}function h(e,t){return te?`${t.open}${e.replace(t.regexp,t.open)}${t.close}`:e}function p(e){return h(e,m([0],0))}function U(e){return h(e,m([1],22))}function re(e){return h(e,m([2],22))}var Ie=new RegExp(["[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)","(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TXZcf-nq-uy=><~]))"].join("|"),"g"),ne=new Date,f=(e=>(e[e.CRITICAL=0]="CRITICAL",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG",e))(f||{}),T={0:"\\u{1F4A5}",1:"\\u{1F534}",2:"\\u{1F7E1}",3:"\\u{1F535}",4:"\\u{1F7E3}"},se={4:re,3:p,2:p,1:U,0:U};function oe({message:e}){return String(e)}function S(e){return JSON.stringify({timestamp:e.date.toISOString(),level:f[e.level],message:e.message,extra:e.extra})}function I(e){function t(c,i){return[Math.floor(c/i),c%i]}function r(){let c,i=e.date.valueOf()-ne.valueOf();[i,c]=t(i,1e3);let[B,A]=t(i,60);return`${B.toString().padStart(4,"0")}:${A.toString().padStart(2,"0")}.${c.toString().padStart(3,"0")}`}function n(){return e.extra===void 0?"":typeof Deno=="object"?" "+Deno.inspect(e.extra,{compact:!1,colors:!0,trailingComma:!0}).trimStart():" "+JSON.stringify(e.extra)}let s=T[e.level],a=e.logger.name!==void 0?`@${e.logger.name}`:"";return`${p(r())}${a} ${s} ${se[e.level](String(e.message))}${n()}`}function ae(e){let t=`[${e.date.toISOString()}]`,r=`[${f[e.level]}]`,n=e.logger.name!==void 0?`[${e.logger.name}] `:"",s=T[e.level];return`${t} ${s} ${r.padEnd(7," ")} ${n}${e.message}`}function ie(){return typeof Deno=="object"&&Deno.stdout.isTerminal()}var w=class{static sparse=oe;static json=S;static pretty=I;static structured=ae;static default=ie()?I:S;constructor(){}};var ce=class{formatter;consoleObject;filter;constructor(e=w.default,t=4,r=console){this.filter=t,this.formatter=e,this.consoleObject=r}handle(e){let t=this.formatter(e);switch(e.level){case 0:case 1:this.consoleObject.error(t);break;case 2:this.consoleObject.warn(t);break;case 3:this.consoleObject.info(t);break;case 4:this.consoleObject.debug(t);break}}};var o=class{#e;sinks;filter;parent;get name(){return this.#e}constructor(e,t=void 0,r=[],n=void 0){this.#e=t,this.sinks=r,this.filter=e,this.parent=n}log(e,t,r=void 0){let n={date:new Date,level:e,logger:this,message:t,extra:r};this.filter<e||this.insert(n)}insert(e){if(!(this.filter<e.level)){for(let t of this.sinks)t.filter>=e.level&&t.handle(e);this.parent!==void 0&&this.parent.insert(e)}}error=this.log.bind(this,1);warn=this.log.bind(this,2);info=this.log.bind(this,3);debug=this.log.bind(this,4)},l=globalThis[Symbol.for("odin-global-logger")]??=new o(3,void 0,[new ce]),ue=o.prototype.log.bind(l,1),le=o.prototype.log.bind(l,2),fe=o.prototype.log.bind(l,3),de=o.prototype.log.bind(l,4),Te=o.prototype.log.bind(l);var b=class extends AudioWorkletProcessor{constructor(){super();this.alive=!0;this.blocks=0;this.port.onmessage=this.onMessage.bind(this)}async onMessage(r){let[n,s]=r.data;switch(n){case"init":this.state=new y(s.workerPort,sampleRate*.02);break;case"close":this.alive=!1;break;case"dump":s.result.postMessage(this.dump());break}}process(r,n,s){if(this.state===void 0||r.length<1||r[0].length<1)return this.alive;let a=this.state.fill(0,r[0][0]);return this.state.offset===this.state.length&&(this.state.flush(),this.state.fill(a,r[0][0])),this.alive}dump(){return{type:"unshared capture worklet",alive:this.alive,sampleRate,offset:this.state?.offset||null,length:this.state?.length||null,blocks:this.blocks}}},x=class extends AudioWorkletProcessor{constructor(){super();this.alive=!0;this.silenceBlocks=0;this.voiceBlocks=0;this.totalBlocks=0;this.port.onmessage=this.onMessage.bind(this)}async onMessage(r){let[n,s]=r.data;switch(n){case"close":this.alive=!1;break;case"init":this.state=new g(s.workerPort,sampleRate*.02),s.workerPort.onmessage=this.onMessage.bind(this);break;case"samples":this.state?.add(s.id,s.buffer);break;case"dump":s.result.postMessage(this.dump());break}n==="close"&&(this.alive=!1)}process(r,n,s){if(this.state===void 0||n.length<1||n[0].length<2)return this.alive;let a=this.state.fill(0,n[0][0],n[0][1]);return a<u.RenderQuantumSize&&(this.totalBlocks+=1,this.state.next(),this.state.hasVoice?this.voiceBlocks+=1:this.silenceBlocks+=1,this.state.fill(a,n[0][0],n[0][1])),this.alive}dump(){return{type:"unshared playback worklet",alive:this.alive,sampleRate,id:this.state?.id||null,offset:this.state?.offset||null,length:this.state?.length||null,hasVoice:this.state?.hasVoice??!1,silenceBlocks:this.silenceBlocks,voiceBlocks:this.voiceBlocks,totalBlocks:this.totalBlocks}}},y=class{constructor(t,r){this.port=t;this.length=r;this.offset=0,this.buffer=new Float32Array(r)}fill(t,r){let n=Math.min(r.length-t,this.length-this.offset);return this.buffer.set(r.subarray(t,t+n),this.offset),this.offset+=n,t+n}flush(){d(this.port,["captureTick",{buffer:this.buffer}],[this.buffer.buffer]),this.offset=0,this.buffer=new Float32Array(this.length)}},g=class{constructor(t,r){this.port=t;this.length=r;this.cache=[];this.id=-1,this.offset=0,this.buffer=void 0,this.next()}get hasVoice(){return this.buffer!==void 0}fill(t,r,n){let s=Math.min(u.RenderQuantumSize-t,this.length-this.offset);return this.buffer!==void 0&&(r.set(this.buffer.subarray(this.offset,this.offset+s),t),n.set(this.buffer.subarray(this.offset+this.length,this.offset+this.length+s),t)),this.offset+=s,t+s}add(t,r){this.cache.push({id:t,buffer:r})}next(){for(this.id+=1;this.cache[0]?.id<this.id;)this.cache.shift();this.cache[0]?.id===this.id?(this.buffer=this.cache[0].buffer,this.cache.shift()):this.buffer=void 0,this.offset=0,d(this.port,["playbackTick",{}])}};registerProcessor("OdinCaptureProcessor",b);registerProcessor("OdinPlaybackProcessor",x);})();\n'});var K0={};kx(K0,{UnsharedCaptureWorker:()=>qx,UnsharedPlaybackWorker:()=>Gx,createCaptureWorker:()=>CF,createPlaybackWorker:()=>EF});function CF(D,x,A,F,r=C.DefaultRefreshRate){return vF.enqueue(async()=>{let[t,e]=await jx(v0,C0,D,"OdinCaptureProcessor",{channelCount:1,numberOfInputs:1,numberOfOutputs:0});return console.warn("SharedArrayBuffer is not available; creating ODIN CaptureWorker in fallback mode"),qx.create(D,x,A,r,t,e,F)})}async function EF(D,x=C.DefaultRefreshRate){if(D.sampleRate!==48e3)throw new Error("playback sample rate must be 48kHz ");let[A,F]=await jx(v0,C0,D,"OdinPlaybackProcessor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[2]});return Gx.create(D,x,A,F)}var R0,vF,qx,Gx,V0=d(()=>{"use strict";R0=require("@4players/odin-common");o();mx();M0();T0();vF=new R0.Strand;qx=class D extends tx{constructor(A,F,r,t,e){super(A,F,r,t,e);this._Activity=I;this._SpeechProbability=0;F.addEventListener("message",this._OnMessages.bind(this))}static async create(A,F,r,t,e,j,v){let{port1:E,port2:l}=new MessageChannel;return a(e,["captureInit",{sampleRate:A.sampleRate,refreshRate:t,workletPort:E}],[E]),await xx(e,"captureReady"),a(j.port,["init",{workerPort:l}],[l]),new D(j,e,F,r,v)}get activity(){return this._Activity}get speechProbability(){return this._SpeechProbability}setVolume(A){a(this.worker,["captureSetVolume",{value:A}])}_OnMessages(A){super._OnMessages(A);let[F,r]=A.data;F==="captureUpdate"&&(this._Activity={isSilent:!r.active,rmsDBFS:r.rmsDBFs},this._SpeechProbability=r.speechProbability)}},Gx=class D extends Dx{constructor(A,F,r){super(A,F,r);this.activities=new Float32Array;this.jitterStats=[]}static async create(A,F,r,t){let{port1:e,port2:j}=new MessageChannel;return a(r,["playbackInit",{workletPort:e,refreshRate:F}],[e]),await xx(r,"playbackReady"),a(t.port,["init",{workerPort:j}],[j]),new D(A,t,r)}getActivity(A){let F=this.medias.get(p(A));if(F===void 0)return;let r=this.activities.at(F.index);if(r!==void 0)return r===0?I:{isSilent:!1,rmsDBFS:r}}getJitterStats(A){let F=this.medias.get(p(A));if(F===void 0)return;let r=this.jitterStats.at(F.index);if(r!==void 0)return r}setGlobalVolume(A){a(this.worker,["playbackSetVolume",{index:"global",value:A}])}setVolume(A,F){let r=this.medias.get(p(A));r!==void 0&&a(this.worker,["playbackSetVolume",{index:r.index,value:F}])}_GetFreeIndex(){let A=super._GetFreeIndex();if(A!==void 0)return A;if(this.medias.size<C.MaxNumberOfDecoders)return this.medias.size}_OnMessages(A){super._OnMessages(A);let[F,r]=A.data;F==="playbackUpdate"&&(this.activities=r.activities,this.jitterStats=r.jitterStats)}}});var PF={};kx(PF,{SESSION_ID:()=>bx,createPlugin:()=>_F});module.exports=GA(PF);var gF=require("@4players/odin-common");o();var X=require("@4players/odin-common");o();var Bx=require("@4players/odin-common");o();var g=require("@4players/odin-common");o();var L0="getUserMedia; timeout";async function _0(D,x){try{let A=await Promise.race([navigator.mediaDevices.getUserMedia({audio:{echoCancellation:D.echoCanceller,noiseSuppression:D.noiseSuppression!=="None",autoGainControl:D.gainController,echoCancellationType:"system",deviceId:x?{exact:x}:void 0}}),(0,g.sleep)(3e4,"timeout")]);return A==="timeout"?(0,g.failure)(L0):(0,g.success)(A)}catch(A){return(0,g.failure)(`getUserMedia; ${A}`)}}async function P0(D,x,A){let F,r=!1;if(x.device?.device.kind==="track"&&x.device?.device.audioTrack)F=new MediaStream([x.device.device.audioTrack]);else{let j=x.device&&x.device.device.deviceId!=="default"?x.device.device.deviceId:void 0,v=await _0(A,j);if(v.type!=="Success"&&v.reason!==L0&&j&&(i(`unable to open requested capture device, falling back to default; ${v.reason}`),v=await _0(A),r=v.type==="Success"),v.type!=="Success")return v;F=v.value}let t=F.getAudioTracks()[0].getSettings().sampleRate,e=await D.audioContexts.acquire(t);return(0,g.success)({source:e.createMediaStreamSource(F),defaulted:r})}function Fx(D){D.getTracks().forEach(x=>{x.stop(),D.removeTrack(x)})}async function H0(D){return new Ax({deviceId:D.id,kind:"track",name:D.label??"MediaStreamTrack",audioTrack:D},!1)}async function XA(){let D=(await navigator.mediaDevices.enumerateDevices()).filter(x=>!!x.label);if(D.length===0&&(0,g.isFirefoxBrowser)()){let x=await ZA("microphone");(x==="granted"||x===!1)&&(await YA("audio"),D=(await navigator.mediaDevices.enumerateDevices()).filter(A=>!!A.label))}return D}async function hx(){let D=await XA(),x=new Map,A=[];for(let r of D){let t=r.kind;if(!(t!=="audioinput"&&t!=="audiooutput")){if(r.deviceId==="default"){x.set(t,r);continue}A.push(new Ax({deviceId:r.deviceId,name:r.label,kind:t},!1))}}let F=r=>new Ax({deviceId:"default",name:x.get(r)?.label??"Default",kind:r},!0);return[F("audioinput"),F("audiooutput"),...A]}async function ZA(D){try{return(await navigator.permissions.query({name:D})).state}catch{return!1}}async function YA(D){try{let x=await navigator.mediaDevices.getUserMedia({[D]:!0});return x?.getTracks().forEach(A=>{A.stop(),x.removeTrack(A)}),!0}catch{return!1}}var $x=require("@4players/odin-common");o();var W0=(0,$x.isSharedArrayBufferCapable)()&&!(0,$x.isSafariBrowser)()?Promise.resolve().then(()=>(U0(),S0)):Promise.resolve().then(()=>(V0(),K0));async function Q0(D,x,A,F){return W0.then(r=>r.createCaptureWorker(D,x,A,F,C.DefaultRefreshRate))}async function z0(D){return W0.then(x=>x.createPlaybackWorker(D,C.DefaultRefreshRate))}var fF=250,nF=1e3,N=class{constructor(x,A){this.controller=x;this._Medias=new Map;this._Vad={...Bx.VAD_DEFAULTS};this._Apm={...Bx.APM_DEFAULTS};this._Volume=1;this._Queue=Promise.resolve();this.#r=0;this._DeviceCb=()=>{clearTimeout(this.#F),this.#F=setTimeout(()=>{this._enqueue(async()=>{let x=this._DeviceParameters?.device;!x||x.device.kind==="track"||(x.device.deviceId==="default"?await this._followDefaultDevice():await this._detectSelectedDeviceRemoved(x.device.deviceId))}).catch(x=>i("device-change handler failed",x))},fF)};A.apm&&this.setApm(A.apm).catch(console.error),A.vad&&this.setVad(A.vad),typeof A.volume<"u"&&this.setVolume(A.volume).catch(console.error),this.uid=(0,Bx.generateUUID)(),this.#x=A.customType,this.#A=A.ref}#x;#A;#F;#r;async _followDefaultDevice(){let x=this._DeviceParameters;this._Volume==="muted"||!this._Capture||!x||Date.now()-this.#r<nF||(n("default capture device may have moved, re-opening capture"),await this._setDeviceImpl(x))}async _detectSelectedDeviceRemoved(x){(await hx()).some(t=>t.device.deviceId===x)||this._Capture?.source.mediaStream?.getAudioTracks()[0]?.readyState==="live"||(this._DeviceParameters?.onStatusChanged?.("stopped"),navigator.mediaDevices.removeEventListener("devicechange",this._DeviceCb),this._DeviceParameters=void 0,await this._closeImpl())}_enqueue(x){let A=this._Queue.then(x,x);return this._Queue=A.catch(()=>{}),A}get vad(){return this._Vad}get apm(){return this._Apm}get volume(){return this._Volume}get activity(){return this._Capture?.worker.activity??I}get speechProbability(){return this._Capture?.worker.speechProbability??0}get deviceId(){return this._DeviceParameters?.device?.device.deviceId}async start(x,A){let F=this._Medias.get(A.connectionId);F===void 0&&this._Medias.set(A.connectionId,F=new Set),f(`starting audio capture media ${A.mediaId} on connection ${A.connectionId}`),!F.has(A.mediaId)&&(F.add(A.mediaId),x.mainConnection?.id===A.connectionId&&await x.request("StartMedia",{media_id:A.mediaId,properties:{kind:"audio",uid:this.uid,ref:this.#A,customType:this.#x}}).catch(r=>u(`StartMedia got rejected; ${r}`)),this._UpdateMedias())}async stop(x,A){let F=this._Medias.get(A.connectionId);f(`stopping audio capture media ${A.mediaId} on connection ${A.connectionId}`),F?.delete(A.mediaId)&&(x.mainConnection?.id===A.connectionId&&await x.request("StopMedia",{media_id:A.mediaId}).catch(r=>u(`StopMedia got rejected; ${r}`)),this._UpdateMedias())}setVad(x){n("updating vad config",x),this._Vad=x,this._Capture&&this._Capture.worker.setVad(x)}async setApm(x){await this._enqueue(()=>this._setApmImpl(x))}async _setApmImpl(x){n("updating apm config",x),this._Apm=x,this._DeviceParameters&&await this._setDeviceImpl(this._DeviceParameters)}async setDevice(x){await this._enqueue(()=>this._setDeviceImpl(x))}async _setDeviceImpl(x){n("updating capture device parameters",x);let A=this._DeviceParameters;if(this._DeviceParameters=x,this._Volume==="muted")return;let F;try{let r=await P0(this.controller,x,{...this._Apm,echoCanceller:this._Monitor?!1:this._Apm.echoCanceller});if(r.type!=="Success"){u(`unable to open capture device; ${r.reason}`),this._DeviceParameters=A;return}F=r.value.source.context,navigator.mediaDevices.addEventListener("devicechange",this._DeviceCb);let t=this._Capture?.source.context;if(this._Capture!==void 0){Fx(this._Capture.source.mediaStream);try{this._Capture.source.disconnect(this._Capture.worker.worklet)}catch(e){i("failed to disconnect previous capture source",e)}}this._Capture===void 0||this._Capture.worker.worklet.context!==r.value.source.context?(this._Capture?.worker.close(),this._Capture={worker:await Q0(r.value.source.context,this.controller.sink,this.controller.receiveMonitoredPacket.bind(this.controller),new WeakRef(this)),source:r.value.source},await this._UpdateMedias(),this._Capture.worker.setVolume(this._Volume),this.setVad(this.vad)):this._Capture.source=r.value.source,F=void 0,this._Capture.source.connect(this._Capture.worker.worklet),t!==void 0&&await this.controller.audioContexts.release(t),this.#r=Date.now(),x.onStatusChanged?.(r.value.defaulted?"defaulted":"started")}catch(r){throw F!==void 0&&await this.controller.audioContexts.release(F),new Error(`Error in setDevice(); ${r}`,{cause:r})}}async setVolume(x){await this._enqueue(()=>this._setVolumeImpl(x))}async _setVolumeImpl(x){n(`updating capture volume to ${x}`),this._Volume=x,x==="muted"?await this._closeImpl():(!this._Capture&&this._DeviceParameters&&await this._setDeviceImpl(this._DeviceParameters),this._Capture?.worker.setVolume(x))}async close(){await this._enqueue(()=>this._closeImpl())}async _closeImpl(){if(n("closing audio capture"),clearTimeout(this.#F),this.#F=void 0,this._Capture!==void 0){this._Capture.worker.close(),Fx(this._Capture.source.mediaStream);try{this._Capture.source.disconnect(this._Capture.worker.worklet)}catch(x){i("failed to disconnect audio node",x)}await this.controller.audioContexts.release(this._Capture.source.context)}navigator.mediaDevices.removeEventListener("devicechange",this._DeviceCb),this._Capture=void 0}async dump(){let x=[];for(let[A,F]of this._Medias)x.push(`${A} => ${Array.from(F.values()).join(",")}`);return{uid:this.uid,ref:this.#A??null,customType:this.#x??null,worker:await this._Capture?.worker.dump()??null,vad:this._Vad,apm:this._Apm,volume:this._Volume,medias:x}}async _UpdateMedias(){if(this._Capture!==void 0){let x=Array.from(this._Medias).map(([A,F])=>({id:A,mediaIds:Array.from(F)}));this._Capture.worker.setMedias(x)}}async startLoopback(){this._Monitor===void 0&&(n("starting audio capture loopback"),this.setApm(this._Apm),this._Monitor=await this.controller.createAudioPlayback({uid:"loopback"}),this._Monitor.start({connectionId:0,mediaId:0}),this._Medias.set(0,new Set([0])),await this._UpdateMedias())}async stopLoopback(){this._Monitor!==void 0&&(n("stopping audio capture loopback"),this._Monitor.close(),this._Monitor=void 0,this.setApm(this._Apm),this._Medias.delete(0),await this._UpdateMedias())}};var ix=require("@4players/odin-common");o();var $=class{constructor(x,A){this.controller=x;this.parameters=A;this.uid=(0,ix.generateUUID)()}#x;#A=new Map;#F;get customType(){return this.parameters?.customType}get mediaStream(){return this.#x}get audioCapture(){return this.#F}get volume(){return(0,ix.assert)(this.audioCapture,"getting the volume failed, this video has no Audio"),this.audioCapture.volume}async setVolume(x){(0,ix.assert)(this.audioCapture,"setVolume() failed, this video has no Audio"),await this.audioCapture.setVolume(x)}get vad(){return(0,ix.assert)(this.audioCapture,"getting the vad config failed, this video has no Audio"),this.audioCapture.vad}setVad(x){(0,ix.assert)(this.audioCapture,"setVad() failed, this video has no Audio"),this.audioCapture.setVad(x)}async setDevice(x,A={voiceActivity:void 0,volumeGate:void 0}){if(this.#x)throw new Error("This VideoCapture already has a MediaStream.");if(!x.getVideoTracks()[0])throw new Error("Error when calling setDevice(), MediaStream does not contain a VideoStreamTrack!");if(this.#x=x,x.getAudioTracks()[0]){let r={device:await H0(x.getAudioTracks()[0]),vad:A,ref:this.uid};this.#F=await this.controller.createAudioCapture(r)}}async start(x,A){let F=this.#A.get(A.connectionId);if(F===void 0&&this.#A.set(A.connectionId,F=new Set),!F.has(A.mediaId)&&(F.add(A.mediaId),x.mainConnection?.id===A.connectionId)){let r={kind:"video",codec:this.parameters?.codec??C.DefaultVideoCodec,ref:this.#F?.uid,uid:this.uid};this.parameters?.customType&&(r.customType=this.parameters.customType),await x.request("StartMedia",{media_id:A.mediaId,properties:r}).catch(t=>u(`StartMedia got rejected; ${t}`))}}async stop(x,A){this.#x&&Fx(this.#x),this.#A.get(A.connectionId)?.delete(A.mediaId)&&x.mainConnection?.id===A.connectionId&&await x.request("StopMedia",{media_id:A.mediaId}).catch(r=>u(`StopMedia got rejected; ${r}`))}async dump(){let x=[];for(let[A,F]of this.#A)x.push(`${A} => ${Array.from(F.values()).join(",")}`);return{uid:this.uid,ref:this.#F?.uid??null,customType:this.customType??null,tracks:this.#x?.getVideoTracks().map(A=>({id:A.id,kind:A.kind,label:A.label,ready:A.readyState,muted:A.muted,settings:{...A.getSettings()}}))??[],volume:this.#F?.volume??0,medias:x}}close(){this.#x&&Fx(this.#x),this.audioCapture?.close(),this.#F=void 0}};var Wr=require("@4players/odin-common");o();var _=class{constructor(x,A,F){this.controller=x;this.uid=A;this.customType=F}get volume(){return this.controller.playbackGetVolume(this.uid)}get activity(){return this.controller.playbackGetActivity(this.uid)}get jitterStats(){return this.controller.playbackGetJitterStats(this.uid)}start(x){f(`starting audio playback media ${x.mediaId} on connection ${x.connectionId}`),this.controller.playbackStart(this.uid,x)}stop(x){f(`stopping audio playback media ${x.mediaId} on connection ${x.connectionId}`),this.controller.playbackStop(this.uid,x)}setVolume(x){n(`updating audio playback media '${this.uid}' volume to ${x}`),this.controller.playbackSetVolume(this.uid,x)}close(){n(`closing audio playback media '${this.uid}'`),this.controller.closePlayback(this.uid)}};function sF(D,x){let A=D.audioContext;if(typeof A.setSinkId=="function"){D.connectOutput(A.destination);let F,r=()=>{if(A.state==="running"&&F!==void 0){let t=F;F=void 0,A.setSinkId(t).catch(e=>i("failed to apply deferred sinkId",e))}};return A.addEventListener("statechange",r),{async setSinkId(t){if(A.state!=="running"){F=t;return}await A.setSinkId(t)},dispose(){A.removeEventListener("statechange",r)}}}if(x&&typeof document<"u"&&typeof HTMLAudioElement<"u"&&typeof HTMLAudioElement.prototype.setSinkId=="function"){let F=A.createMediaStreamDestination();D.connectOutput(F);let r=new Audio;r.srcObject=F.stream,r.muted=!1,r.volume=1;let t=!1,e=!1,j={once:!0,passive:!0,capture:!0},v=()=>{e=!1,k()},E=()=>{e||t||(e=!0,document.addEventListener("pointerdown",v,j),document.addEventListener("keydown",v,j))},l=()=>{e&&(e=!1,document.removeEventListener("pointerdown",v,!0),document.removeEventListener("keydown",v,!0))},k=()=>{t||r.play().catch(sx=>{t||(sx instanceof DOMException&&sx.name==="NotAllowedError"?E():i("failed to start playback audio element",sx))})},ux=()=>{A.state==="running"&&r.paused&&k()};return A.addEventListener("statechange",ux),k(),{async setSinkId(sx){await r.setSinkId(sx)},dispose(){t=!0,l(),A.removeEventListener("statechange",ux),r.pause(),r.srcObject=null,r.removeAttribute("src");try{r.load()}catch{}F.disconnect()}}}return D.connectOutput(A.destination),{async setSinkId(){},dispose(){}}}var yx=class{constructor(x){this.audioContextFactory=x;this.entries=[];this._acquireStrand=new X.Strand}acquire(x){return this._acquireStrand.enqueue(async()=>{for(let r of this.entries)if(r.sampleRate===x||r.sampleRate===void 0&&r.audioContext.sampleRate===x)return r.references+=1,r.audioContext;let A=await this.audioContextFactory(x),F=this.entries.find(r=>r.audioContext.sampleRate===A.sampleRate);return F?(F.references+=1,A.close().catch(()=>{}),F.audioContext):(this.entries.push({sampleRate:x,audioContext:A,references:1}),A)})}async release(x){let A=this.entries.findIndex(F=>F.audioContext===x);if(!(A<0)&&(this.entries[A].references-=1,this.entries[A].references<=0)){let F=this.entries[A].audioContext;this.entries.splice(A,1),await F.close()}}close(){for(let x of this.entries.splice(0))x.audioContext.close().catch(()=>{})}},Ix=class D{constructor(x,A,F=!1){this.audioContexts=x;this.sink=A;this.enableHTMLAudioElementFallback=F;this.audioCaptures=[];this.videoCaptures=[];this.globalVolume=[1,1];this.playbacks=new Map;this.setPlaybackStrand=new X.Strand}async create(x,A){return new D(x,A)}receivePacket(x,A){this.playbackWorker?.receivePacket(x,A)}receiveMonitoredPacket(x,A){let F=A.slice();this.receivePacket(x,F)}async createAudioPlayback(x){let A=this.playbacks.get(x.uid),F=x.volume;if(A===void 0){F=F??[1,1];let r=new _(this,x.uid,x.customType);A={id:void 0,volume:F,playback:r},this.playbacks.set(x.uid,A)}return F!==void 0&&A.playback.setVolume(F),A.playback}async createAudioCapture(x){let A=new N(this,x);return await A.setDevice(x),this.audioCaptures.push(new WeakRef(A)),A}async createVideoCapture(x,A){let F=new $(this,A);return await F.setDevice(x),this.videoCaptures.push(new WeakRef(F)),F}playbackSetDevice(x){return this.setPlaybackStrand.enqueue(async()=>{let A=x?.device.deviceId??"";if(A==="default"&&(A=""),this.playbackWorker===void 0){let F=await this.audioContexts.acquire(48e3);this.playbackWorker=await z0(F),this.playbackSink=sF(this.playbackWorker,this.enableHTMLAudioElementFallback),this.playbackWorker.setGlobalVolume(this.globalVolume);for(let[,r]of this.playbacks)r.id!==void 0&&this.playbackWorker.addMedias(r.id.connectionId,[r.id.mediaId],r.volume)}if(x&&this.playbackSink!==void 0)try{await this.playbackSink.setSinkId(A)}catch(F){i("failed to set playback sink",F)}})}playbackSetGlobalVolume(x){this.globalVolume=x,this.playbackWorker?.setGlobalVolume(this.globalVolume)}playbackStart(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.id!==void 0&&this.playbackStop(x,F.id),F.id=A,this.playbackWorker?.addMedias(A.connectionId,[A.mediaId],F.volume))}playbackStop(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.id!==A&&i(`playback media ${A.mediaId} on connection ${A.connectionId} is out of sync`,F.id,A),F.id=void 0,this.playbackWorker?.removeMedias(A.connectionId,[A.mediaId]))}playbackGetActivity(x){let A=this.playbacks.get(x);return A?.id===void 0?I:this.playbackWorker?.getActivity(A.id)??I}playbackGetJitterStats(x){let A=this.playbacks.get(x);return A?.id===void 0?X.JITTER_STATS_INITIAL:this.playbackWorker?.getJitterStats(A.id)??X.JITTER_STATS_INITIAL}playbackSetVolume(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.volume=A,F.id!==void 0&&this.playbackWorker?.setVolume(F.id,F.volume))}playbackGetVolume(x){return this.playbacks.get(x)?.volume??[1,1]}closePlayback(x){let A=this.playbacks.get(x);A!==void 0&&(A.id!==void 0&&this.playbackStop(x,A.id),this.playbacks.delete(x))}close(){this.playbackSink?.dispose(),this.playbackSink=void 0,this.playbackWorker?.close(),this.audioContexts.close()}async dump(){let x=[];for(let r of this.audioCaptures){let t=r.deref();t!==void 0&&x.push(await t.dump())}let A=[];for(let r of this.videoCaptures){let t=r.deref();t!==void 0&&A.push(await t.dump())}let F=[];for(let[r,t]of this.playbacks)F.push({uid:r,id:t.id||null,volume:t.volume});return{globalVolume:this.globalVolume,playbackWorker:await this.playbackWorker?.dump()||null,audioCaptures:x,videoCaptures:A,playbacks:F}}},Ax=class{constructor(x,A=!1){this.device=x;this.isDefault=A}get type(){switch(this.device.kind){case"audioinput":return"AudioCapture";case"track":return"AudioCapture";case"audiooutput":return"AudioPlayback";default:(0,X.assert)(!1,"not supported device")}}get id(){return this.device.deviceId}get name(){return this.device.name}};var ax=require("@4players/odin-common"),rA=require("@msgpack/msgpack");o();var tt=require("@4players/odin-common");o();var J=require("@4players/odin-common"),K=require("@4players/odin-common/api");o();var R=require("@4players/odin-common"),Z=require("@4players/odin-common/api"),gx=require("@msgpack/msgpack");o();var T=class{constructor(x){this.stream=x;this._SendQueue=[];this._RecvQueue=[];this._EventQueue=[];this._Requests=new Map;this._Close=new AbortController;this._NextId=1;x instanceof WebSocket?(x.addEventListener("open",this._OnWebSocketOpen.bind(this)),x.addEventListener("close",this.close.bind(this)),x.addEventListener("message",A=>this._OnRpcMessage(A.data)),x.binaryType="arraybuffer"):(bF(x.readable.getReader(),this._OnRpcMessage.bind(this)).finally(this.close.bind(this)),this._Writer=x.writable.getWriter()),this._Close.signal.addEventListener("abort",this._Cleanup.bind(this),{once:!0})}get closed(){return this._Close.signal.aborted}get closeSignal(){return this._Close.signal}async request(x,A,F){if(this.closed)return Promise.resolve("closed");let r=this._NextId,t=F===void 0?void 0:setTimeout(()=>this._TimeoutRequest(r),F);return this._Send([0,r,x,A]),new Promise(e=>{this._Requests.set(r,{accept:e,timeoutId:t}),this._NextId+=1})}notify(x,A){this.closed||this._Send([2,x,A])}recv(){if(this.closed)return Promise.resolve("closed");let x=this._EventQueue.shift();return x!==void 0?Promise.resolve(x):new Promise(A=>this._RecvQueue.push(A))}close(){this._Close.abort()}_TimeoutRequest(x){let A=this._Requests.get(x);A!==void 0&&(this._Requests.delete(x),clearTimeout(A.timeoutId),A.accept("timeout"))}_Send(x){let A;x instanceof Uint8Array?A=x:A=new Uint8Array((0,gx.encode)(x,{ignoreUndefined:!0,forceFloat32:!0})),this.stream instanceof WebSocket?this.stream.send(A):this._Writer.write(A).catch(()=>{})}_OnWebSocketOpen(x){for(let A of this._SendQueue)this._Send(A);this._SendQueue.length=0}_OnRpcMessage(x){let A=iF(x);if(A.type!=="Success"){this.close();return}switch(A.value[0]){case 0:this._Send([1,A.value[1],"not supported",null]);break;case 1:this._OnResponse(A.value[1],A.value[2],A.value[3]);break;case 2:this._OnEvent(A.value[1],A.value[2]);break}}_OnResponse(x,A,F){let r=this._Requests.get(x);r!==void 0&&(clearTimeout(r.timeoutId),r.accept(A===null?(0,R.success)(F):(0,R.failure)(A)))}_OnEvent(x,A){let F=this._RecvQueue.shift();F!==void 0?F({name:x,properties:A}):this._EventQueue.push({name:x,properties:A})}_Cleanup(){for(let x of this._Requests.values())clearTimeout(x.timeoutId),x.accept("closed");this._Requests.clear();for(let x of this._RecvQueue)x("closed");this._RecvQueue.length=0,this._SendQueue.length=0,this.stream instanceof WebSocket?this.stream.close():this._Writer?.close().catch(()=>{})}},Y=class{constructor(x,A,F){this.rpc=x;this._Commands=A;this._Events=F}get closed(){return this.rpc.closed}get closeSignal(){return this.rpc.closeSignal}async request(x,A,F){A=(0,Z.parseRequest)(x,A,this._Commands);let r=await this.rpc.request(x,A,F);if(r==="closed"||r==="timeout"||r.type==="Failure")return r;let t=(0,Z.parseResponse)(x,r.value,this._Commands);return t!==void 0?(0,R.success)(t):(0,R.failure)("response schema failed validation")}notify(x,A){A=(0,Z.parseRequest)(x,A,this._Commands),this.rpc.notify(x,A)}async recv(){let x=await this.rpc.recv();if(x==="closed")return x;let A=E0(this._Events,x);return A!==void 0?A:(X0(this._Events,x.name)?(u(`schema validation for ${x.name} failed; closing connection`),this.rpc.close()):i(`dropping unknown event ${x.name}`),"closed")}close(){this.rpc.close()}};function iF(D){try{return(0,R.success)(Z.MessagePackRpcSchema.parse((0,gx.decode)(new Uint8Array(D))))}catch(x){return(0,R.failure)(String(x))}}function E0(D,x){if(!X0(D,x.name))return;let A=D[x.name].safeParse(x.properties);if(A.success)return{name:x.name,properties:A.data}}function X0(D,x){return x in D}async function bF(D,x){let A=new Uint8Array;for(;;){let F=q0(A,0);if(F===B){D.cancel("protocol violation");break}if(F!==q&&F<=A.length){x(A.subarray(0,F)),A=A.subarray(F);continue}let r;try{r=await D.read()}catch{break}if(r.done)break;A=oF(A,r.value)}A.length>0&&i("unprocessed bytes left in rpc stream",A)}function oF(D,x){if(D.length===0)return x;if(x.length===0)return D;let A=new Uint8Array(D.length+x.length);return A.set(D,0),A.set(x,D.length),A}var w=require("@4players/odin-common"),Z0=require("@4players/odin-common/api");o();var y=class D{constructor(x,A){this.text=x;this.claims=A;if(A.ups!==void 0){let F=D.parse(A.ups);F.type==="Success"?this._Upstream=F.value:u(`upstream in token can not be parsed; ${F.reason}`)}}static parse(x){let A=x.split(".");if(A.length!==3)return(0,w.failure)("expected three segments");let F=(0,w.fromBase64Url)(A[1]);if(F.type==="Failure")return(0,w.failure)(`invalid token; ${F.reason}`);let r;try{r=JSON.parse(F.value)}catch(e){return(0,w.failure)(`invalid token; ${e}`)}let t=Z0.TokenClaimsSchema.safeParse(r);return t.success===!1?(0,w.failure)(`invalid token; ${t.error}`):(0,w.success)(new D(x,t.data))}get timeLeft(){return this.claims.exp===void 0?1/0:this.claims.exp*1e3-Date.now()}get upstream(){return this._Upstream}get defaultRoomId(){return Array.isArray(this.claims.rid)?this.claims.rid.length===1?this.claims.rid[0]:void 0:this.claims.rid}hasAudience(x){return this.claims.aud===void 0&&x==="gateway"?!0:Array.isArray(this.claims.aud)?this.claims.aud.includes(x):this.claims.aud===x}toString(){return this.text}};var vx=require("@4players/odin-common");o();function Y0(D){typeof globalThis.rtcDataChannels>"u"&&(globalThis.rtcDataChannels=[]),Array.isArray(globalThis.rtcDataChannels)&&globalThis.rtcDataChannels.length<=100&&globalThis.rtcDataChannels.push(D)}function xA(D){let x=globalThis.rtcDataChannels?.indexOf(D);x!==void 0&&x>=0&&globalThis.rtcDataChannels.splice(x,1),D.readyState!=="closed"&&D.close()}function _x(D){typeof globalThis.rtcPeerConnections>"u"&&(globalThis.rtcPeerConnections=[]),Array.isArray(globalThis.rtcPeerConnections)&&globalThis.rtcPeerConnections.length<=100&&globalThis.rtcPeerConnections.push(D)}function Lx(D){let x=globalThis.rtcPeerConnections?.indexOf(D);x!==void 0&&x>=0&&globalThis.rtcPeerConnections.splice(x,1),D.connectionState!=="closed"&&D.close()}var Cx=class{constructor(x,A,F){this._localVideos=new Map;this._remoteVideos=new Map;this._freeLocalVideoTransceivers=[];this._closed=!1;this._negotiationRequested=!1;this._negotiationRunning=!1;this._negotiationCounter=0;this._pendingRemoteCandidates=[];this._WebRtcStatsSnapshot=null;this._peerConnection=x,this._signaling=A,this._answerTimeout=F?.answerTimeout??C.WebRtcAnswerTimeout,this._maxNegotiationAttempts=F?.maxNegotiationAttempts??C.WebRtcMaxNegotiationAttempts,this._peerConnection.ontrack=this._onTrack.bind(this),this._peerConnection.onconnectionstatechange=()=>this._onStatusChanged(),this._peerConnection.onicecandidate=r=>{(r.candidate?this._signaling.sendIceCandidate(r.candidate):this._signaling.sendIceComplete()).catch(e=>{i("failed to send local ice candidate",e)})},this._WebRtcStatsInterval=setInterval(()=>{this._snapshotStats()},C.WebRtcStatsSnapshotInterval)}requestNegotiation(){this._closed||(this._negotiationRequested=!0,!this._negotiationRunning&&(this._negotiationRunning=!0,setTimeout(async()=>{let x=0;for(;this._negotiationRequested&&!this._closed;){this._negotiationRequested=!1;try{await this._negotiate(),x=0}catch(A){if(this._closed)break;if(x+=1,u(`negotiation failed during sdp offer/answer exchange (attempt ${x})`,A),x<this._maxNegotiationAttempts)this._negotiationRequested=!0;else{this._negotiationRunning=!1,this._signaling.closeConnection().catch(()=>{});return}}}this._negotiationRunning=!1})))}async startLocalVideo(x,A,F){if(this._localVideos.has(x))return;f(`starting local video for media ${x}`);let r=this._freeLocalVideoTransceivers.pop();if(r?(await r.sender.replaceTrack(A),r.direction="sendrecv"):r=this._peerConnection.addTransceiver(A),F){let j=r.sender.getParameters(),{maxBitrate:v,maxFramerate:E,scaleResolutionDownBy:l}=F,k={...v!==void 0&&{maxBitrate:v},...E!==void 0&&{maxFramerate:E},...l!==void 0&&{scaleResolutionDownBy:l}};if(j.encodings.length===0)j.encodings.push(k);else for(let ux of j.encodings)Object.assign(ux,k);F.degradationPreference&&(j.degradationPreference=F.degradationPreference),await r.sender.setParameters(j)}let e=new vx.VideoCodec(F?.codec??C.DefaultVideoCodec).isSupported();e&&r.setCodecPreferences([e]),this._localVideos.set(x,{transceiver:r}),this.requestNegotiation()}stopLocalVideo(x){let A=this._localVideos.get(x);A&&(f(`stopping local video for media ${x}`),this._localVideos.delete(x),A.transceiver.sender.track&&(A.transceiver.sender.track.enabled=!1),A.transceiver.direction="inactive",A.transceiver.sender.replaceTrack(null).catch(()=>{}),this._freeLocalVideoTransceivers.push(A.transceiver),this.requestNegotiation())}startRemoteVideo(x){let A=this._remoteVideos.get(x);if(A)return A.track;f(`starting remote video for media ${x}`);let F=this._peerConnection.addTransceiver("video",{direction:"recvonly"}),r,t=new Promise((e,j)=>{r={resolve:e,reject:j}});return t.catch(()=>{}),(0,vx.assert)(r!==void 0,"promise executor must run synchronously"),this._remoteVideos.set(x,{state:"Requested",transceiver:F,promise:r,track:t}),this.requestNegotiation(),t}stopRemoteVideo(x){let A=this._remoteVideos.get(x);if(A){f(`stopping remote video for media ${x}`),this._remoteVideos.delete(x),A.state!=="Active"&&A.promise.reject(new Error("video stopped"));try{A.transceiver.direction="inactive"}catch{}this.requestNegotiation()}}async handleWebRtcUpdate(x){try{switch(x.kind){case"Sdp":await this._updateRemoteSdp(x.type==="Answer"?"answer":"offer",x.sdp,x.media_map,x.negotiation_id);break;case"Trickle":this._addIceCandidate({candidate:x.candidate,sdpMid:x.spd_mid??void 0,sdpMLineIndex:x.spd_mline_index??void 0,usernameFragment:x.username_fragment??void 0});break;case"TrickleFinished":this._addIceCandidate(void 0);break}}catch(A){u("failed to handle webrtc update",A,x)}}startup(){this._peerConnection.connectionState==="new"&&this.requestNegotiation()}cleanup(){this._closed=!0;for(let[,x]of this._remoteVideos)x.state!=="Active"&&x.promise.reject(new Error("connection closed"));this._pendingAnswer?.reject(new Error("connection closed")),this._pendingRemoteCandidates.length=0,clearTimeout(this._WebRtcIceTimeout),clearTimeout(this._WebRtcTimeout),clearInterval(this._WebRtcStatsInterval),this._localVideos.clear(),this._remoteVideos.clear(),this._freeLocalVideoTransceivers.length=0}get stats(){return this._WebRtcStatsSnapshot}get peerConnection(){return this._peerConnection}get localVideos(){return this._localVideos}get remoteVideos(){return this._remoteVideos}get isConnected(){return this._peerConnection.connectionState==="connected"}get isNegotiating(){return this._negotiationRunning}async _snapshotStats(){try{let x=await this._peerConnection.getStats(),A={},F={bytesSent:0,bytesReceived:0,packetsSent:0,packetsReceived:0,rtt:0};x.forEach(r=>{let{type:t,...e}=r;t!=="certificate"&&(t==="candidate-pair"&&r.nominated&&(F.bytesSent+=r.bytesSent??0,F.bytesReceived+=r.bytesReceived??0,F.packetsSent+=r.packetsSent??0,F.packetsReceived+=r.packetsReceived??0,F.rtt=r.currentRoundTripTime??0),A[t]||(A[t]=[]),A[t].push(e))}),this._WebRtcStatsSnapshot={timestamp:Date.now(),status:this._peerConnection.connectionState,stats:F,report:A}}catch{}}_addIceCandidate(x){if(x&&(x.sdpMid===void 0&&x.sdpMLineIndex===void 0&&(x={...x,sdpMid:"0"}),n(`adding new ice ${x.candidate}`,x)),this._peerConnection.remoteDescription===null){this._pendingRemoteCandidates.push(x);return}this._applyIceCandidate(x)}_applyIceCandidate(x){this._peerConnection.addIceCandidate(x).catch(A=>{i("failed to add remote ice candidate",A,x)})}_flushPendingIceCandidates(){let x=this._pendingRemoteCandidates.splice(0);for(let A of x)this._applyIceCandidate(A)}async _negotiate(){let x=++this._negotiationCounter,A=await this._peerConnection.createOffer();(0,vx.assert)(A.type==="offer"&&A.sdp,"generated broken payload"),await this._peerConnection.setLocalDescription(A);let F=[];for(let[t,{transceiver:e}]of this._localVideos)e.mid&&F.push([t,e.mid]);for(let[t,e]of this._remoteVideos)e.state!=="Active"&&e.transceiver.mid&&F.push([t,e.transceiver.mid]);let r=new Promise((t,e)=>{this._pendingAnswer={negotiationId:x,resolve:t,reject:e}});try{await this._signaling.sendOffer(A.sdp,F,x),await aF(r,this._answerTimeout,`timed out waiting for answer to offer ${x}`)}finally{this._pendingAnswer=void 0}}async _updateRemoteSdp(x,A,F,r){if(x==="offer"){i("ignoring unexpected sdp offer from server");return}let t=this._pendingAnswer;if(t===void 0){i("ignoring sdp answer without pending negotiation");return}if(r!==void 0&&r!==t.negotiationId){i(`ignoring stale sdp answer for negotiation ${r}; current is ${t.negotiationId}`);return}if(this._peerConnection.signalingState!=="have-local-offer"){i(`ignoring sdp answer in signaling state ${this._peerConnection.signalingState}`);return}for(let[e,j]of F){let v=this._remoteVideos.get(e);v?.state==="Requested"&&(this._remoteVideos.set(e,{state:"Mapped",transceiver:v.transceiver,mid:j,promise:v.promise,track:v.track}),n(`updated remote video list with media ${e}`,v,this._remoteVideos))}try{await this._peerConnection.setRemoteDescription({type:x,sdp:A})}catch(e){t.reject(e);return}this._flushPendingIceCandidates(),t.resolve()}async _onStatusChanged(){switch(n(`peer connection state changed to ${this._peerConnection.connectionState}`),this._peerConnection.connectionState){case"closed":break;case"connected":clearTimeout(this._WebRtcIceTimeout),this._WebRtcIceTimeout=void 0,clearTimeout(this._WebRtcTimeout),this._WebRtcTimeout=void 0;break;case"failed":this._peerConnection.restartIce(),this.requestNegotiation();case"disconnected":C.MainConnectionPingInterval!==void 0&&await this._signaling.checkConnection();default:this._WebRtcIceTimeout===void 0&&(this._WebRtcIceTimeout=setTimeout(()=>{n("ice connection timeout was reached"),this._peerConnection.restartIce(),this._WebRtcIceTimeout=void 0},C.WebRtcIceTimeout)),this._WebRtcTimeout===void 0&&(this._WebRtcTimeout=setTimeout(async()=>{n("peer connection timeout was reached"),await this._signaling.closeConnection()},C.WebRtcTimeout));break}}_onTrack(x){let A=Array.from(this._remoteVideos).find(([,t])=>t.state==="Mapped"&&t.mid===x.transceiver.mid);if(!A){i(`unexpected track with mid: ${x.transceiver.mid}`);return}let[F,r]=A;(0,vx.assert)(r.state==="Mapped","expected video state to be Mapped"),this._remoteVideos.set(F,{state:"Active",transceiver:x.transceiver,track:r.track}),n(`updated local video list with media ${F}`,A,x.transceiver,this._localVideos),x.track.onended=()=>{n(`video track with mid ${x.transceiver.mid} ended`,A)},r.promise.resolve(x.track)}};function aF(D,x,A){return new Promise((F,r)=>{let t=setTimeout(()=>r(new Error(A)),x);D.then(e=>{clearTimeout(t),F(e)},e=>{clearTimeout(t),r(e)})})}var Px=class D{constructor(x,A,F,r,t,e,j){this.id=x;this.address=A;this.connection=r;this.datagramWritable=t;this.rpc=e;this.closeController=j;this._ConnectionStats={...J.CONNECTION_STATS_INITIAL};this._WebRtcUpdatesRunning=!1;this._WebRtcSessionFlight=new Q;this._PingFlight=new Q;this.status=0;this._ClosePromise=(async()=>{try{await this.connection.closed}catch{}return"closed"})(),C.MainConnectionPingInterval!==void 0&&(this._PingIntervalId=setInterval(async()=>{this.connectionStats.rtt=await this.ping(C.HealthCheckTimeout)},C.MainConnectionPingInterval)),j.signal.addEventListener("abort",()=>this._CleanUp(),{once:!0}),this.datagramWriter=t.getWriter(),this.connection.closed.then(()=>{this.status=2}).catch(()=>{}).finally(()=>{this.closeController.abort("transport closed")}),this.connection.ready.then(()=>{this.status=1}).catch(()=>{}),this.readDatagrams(this.connection,this.id,(v,E)=>{this._ConnectionStats.packetsReceived+=1,F(v,E)})}static async create(x,A,F,r){try{let t=new URL(`https://${A}?version=${$0}&uid=${bx}`),e=new AbortController;r.addEventListener("abort",()=>e.abort(),{once:!0});let j=new WebTransport(t);e.signal.addEventListener("abort",()=>{try{j.close()}catch{}},{once:!0}),await j.ready;let v=j.datagrams,E=v?.createWritable?.()??v?.writable;if(!E)return e.abort(),(0,J.failure)(`connecting to ${A} failed because WebTransport datagrams are not supported by this browser`);let l=await j.createBidirectionalStream(),k=new Y(new T(l),K.MainCommandsRpc,K.MainNotificationsRpc);return e.signal.addEventListener("abort",()=>k.close(),{once:!0}),k.notify("Hello",{stream:"main"}),(0,J.success)(new D(x,A,F,j,E,k,e))}catch(t){return(0,J.failure)(`connecting to ${A} failed with ${t}`)}}get connectionStats(){return this._ConnectionStats}get transport(){return"H3"}get closePromise(){return this._ClosePromise}get closeSignal(){return this.closeController.signal}get closed(){return this.closeSignal.aborted}waitForConnected(){return Promise.race([this.connection.ready,this.connection.closed.then(()=>{throw new Error("connection closed")})])}close(){f(`closing connection to '${this.address}' with id ${this.id}`),this.closeController.abort("request")}async joinRoom(x,A,F,r){try{if(this.closed)return"closed";let t=await this.connection.createBidirectionalStream().catch(()=>"closed");if(t==="closed")return"closed";let e=new Y(new T(t),K.RoomCommandsRpc,K.RoomNotificationsRpc),j=await e.request("Hello",{stream:"room",token:String(x),room_id:A,user_data:F,position:r});return j==="closed"||j.type==="Failure"?j:(0,J.success)(e.rpc)}catch(t){return(0,J.failure)(`JoinRoom failed; ${t}`)}}async getReconnectToken(x){let A=await this._Request("RequestReconnectToken",{peer_id:x});return A.type==="Failure"?A:y.parse(A.value)}async getRtcStats(){return this._PeerConnection?.getStats()}async healthCheck(){let x=await this._RequestPing(C.HealthCheckTimeout);return x||this.close(),x}async ping(x=3e4){let A=Date.now();return await this._RequestPing(x)?Date.now()-A:0}sendDatagram(x){if(!this.closed)try{this.datagramWriter.write(x).catch(()=>{}),this._ConnectionStats.packetsSent+=1;let A=x.byteLength;this.connectionStats.bytesSent+=A}catch{}}async readDatagrams(x,A,F){try{let r=x.datagrams.readable.getReader();for(;;){let t=await r.read();if(t.done)break;let e=t.value.byteLength;this.connectionStats.bytesReceived+=e,F(A,t.value)}}catch{}}_CleanUp(){n(`performing cleanup for connection ${this.id}`),clearInterval(this._PingIntervalId),this._RecycleWebRtcSession("connection closed")}_RecycleWebRtcSession(x){let A=this._WebRtcSession,F=this._PeerConnection;A===void 0&&F===void 0||(i(`recycling webrtc session of connection ${this.id}; ${x}`),this._WebRtcSession=void 0,this._PeerConnection=void 0,A?.cleanup(),F&&Lx(F))}async _EnsureWebRtcSession(){return this._WebRtcSession?this._WebRtcSession:this._WebRtcSessionFlight.run(async()=>(this._PeerConnection=new RTCPeerConnection,_x(this._PeerConnection),this._WebRtcSession=new Cx(this._PeerConnection,{sendOffer:async(x,A,F)=>{let r=await this._Request("WebRtcUpdate",{kind:"Sdp",type:"Offer",sdp:x,media_map:A,negotiation_id:F});if(r.type==="Failure")throw new Error(`failed to send sdp offer; ${r.reason}`)},sendIceCandidate:async x=>{await this._Request("WebRtcUpdate",{kind:"Trickle",candidate:x.candidate,spd_mid:x.sdpMid??void 0,spd_mline_index:x.sdpMLineIndex??void 0,username_fragment:x.usernameFragment??void 0})},sendIceComplete:async()=>{await this._Request("WebRtcUpdate",{kind:"TrickleFinished"})},closeConnection:async()=>{this._RecycleWebRtcSession("negotiation gave up")},checkConnection:async()=>{}}),this._HandleWebRtcUpdates(),this._WebRtcSession))}async _HandleWebRtcUpdates(){if(!this._WebRtcUpdatesRunning){for(this._WebRtcUpdatesRunning=!0;;){let x=await this.rpc.recv();if(x==="closed")break;x.name==="WebRtcUpdate"&&this._WebRtcSession?.handleWebRtcUpdate(x.properties)}this.close()}}async _Request(x,A,F){let r=Date.now(),t=await(F===void 0?this.rpc.request(x,A):this.rpc.request(x,A,F)),e=(Date.now()-r)/1e3;return x!=="Ping"&&n(`sent main rpc '${x}'; took: ${e}s`,{properties:A,timeout:F,result:t}),t==="closed"?(0,J.failure)("connection lost"):t}_RequestPing(x=3e4){return this._PingFlight.run(async()=>{let A=await this._Request("Ping",{},x);return A!=="timeout"&&A.type==="Success"})}async startLocalVideo(x,A,F){await(await this._EnsureWebRtcSession()).startLocalVideo(x,A,F)}stopLocalVideo(x){this._WebRtcSession?.stopLocalVideo(x)}async startRemoteVideo(x){return(await this._EnsureWebRtcSession()).startRemoteVideo(x)}stopRemoteVideo(x){this._WebRtcSession?.stopRemoteVideo(x)}async dump(){return{type:"H3",id:this.id,address:this.address,closed:this.closed,status:this.status,datagrams:{sent:this._ConnectionStats.packetsSent,received:this._ConnectionStats.packetsReceived},webRtc:{signalingState:this._PeerConnection?.signalingState??null,connectionState:this._PeerConnection?.connectionState??null,iceGatheringState:this._PeerConnection?.iceGatheringState??null,iceConnectionState:this._PeerConnection?.iceConnectionState??null,connectionStats:this._WebRtcSession?.stats??null}}}};var h=require("@4players/odin-common"),Nx=require("@4players/odin-common/api");o();var L=require("@4players/odin-common");o();async function f0(D,x){let A=performance.now(),F=(0,L.failure)("no connection was attempted");for(let r=0;r<C.ConnectInterval.length&&!x.aborted;r++){let t=A+uF(r);if(await(0,L.abortableSleep)(t-performance.now(),x)==="aborted")return(0,L.failure)("aborted");if(F=await lF(D,x),F.type==="Success")return F}return F}async function lF(D,x){let A;try{A=new WebSocket(D)}catch(v){return(0,L.failure)(`unable to create websocket; ${v}`)}let F=new AbortController,r=new Promise(v=>A.addEventListener("open",()=>v((0,L.success)(A)),{signal:F.signal})),t=new Promise(v=>A.addEventListener("close",E=>v((0,L.failure)(E.reason!==""?E.reason:"unable to establish websocket connection")),{signal:F.signal})),e=new Promise(v=>x.addEventListener("abort",()=>v((0,L.failure)("aborted")),{signal:F.signal})),j=await Promise.race([r,t,e]);return F.abort(),j}function uF(D){let x=C.ConnectInterval.slice(0,D).reduce((F,r)=>F+r,0),A=C.ConnectInterval[D]*Math.random();return x+A}var Hx=class D{constructor(x,A,F,r,t,e){this.id=x;this.address=A;this.url=F;this.onDatagram=r;this.connection=t;this.webRtc=e;this._PeerIdMap=new WeakMap;this._ConnectionStats={...h.CONNECTION_STATS_INITIAL};this._PingFlight=new Q;f(`creating new webrtc connection to '${this.address}' with id ${this.id}`),this.closeSignal.addEventListener("abort",()=>this._CleanUp(),{once:!0}),this._ClosePromise=new Promise(j=>{this.closeSignal.addEventListener("abort",()=>{j("closed")},{once:!0})}),_x(e),this._AudioChannel=this.webRtc.createDataChannel("audio",{id:2,negotiated:!0,ordered:!1,maxRetransmits:0}),this._AudioChannel.binaryType="arraybuffer",this._AudioChannel.onmessage=j=>{this._ConnectionStats.packetsReceived++;let v=new Uint8Array(j.data);this._ConnectionStats.bytesReceived+=v.byteLength,this.onDatagram(this.id,v)},this._AudioChannel.onerror=j=>i(`webrtc audio data channel for connection with id ${x} raised an error`,j),this._AudioChannel.onclosing=j=>f(`webrtc audio data channel for connection with id ${x} begins shutting down`,j),this._AudioChannel.onclose=j=>f(`webrtc audio data channel for connection with id ${x} has closed`,j),Y0(this._AudioChannel),this._WebRtcSession=new Cx(this.webRtc,{sendOffer:async(j,v,E)=>{let l=await this._Request("WebRtcUpdate",{kind:"Sdp",type:"Offer",sdp:j,media_map:v,negotiation_id:E});if(l.type==="Failure")throw new Error(`failed to send sdp offer; ${l.reason}`)},sendIceCandidate:async j=>{await this._Request("WebRtcUpdate",{kind:"Trickle",candidate:j.candidate,spd_mid:j.sdpMid??void 0,spd_mline_index:j.sdpMLineIndex??void 0,username_fragment:j.usernameFragment??void 0})},sendIceComplete:async()=>{await this._Request("WebRtcUpdate",{kind:"TrickleFinished"})},closeConnection:async()=>{this.close()},checkConnection:async()=>{this.healthCheck().then()}}),this._WebRtcSession.startup(),C.MainConnectionPingInterval!==void 0&&(this._PingIntervalId=setInterval(async()=>{this.connectionStats.rtt=await this.ping(C.HealthCheckTimeout)},C.MainConnectionPingInterval)),this._HandleWebRtcUpdates()}static async create(x,A,F,r){if(r.aborted)return(0,h.failure)("aborted");let t;try{t=new URL(`wss://${A}`)}catch(E){return(0,h.fail)(`address in token(${A}) can not be parsed; ${E}`)}let e=(0,h.extendUrl)(t,`main?uid=${bx}`);if(e.type!=="Success")return e;let j=await f0(e.value,r);if(j.type!=="Success")return j;let v=new Y(new T(j.value),Nx.MainCommandsRpc,Nx.MainNotificationsRpc);try{return(0,h.success)(new D(x,A,t,F,v,new RTCPeerConnection))}catch(E){return v.close(),(0,h.failure)(`unable to create webrtc connection; ${E}`)}}get status(){switch(this.webRtc.connectionState){case"connected":return 1;case"failed":case"closed":return 2;default:return 0}}get connectionStats(){return this._ConnectionStats}get transport(){return"WebRTC"}get closePromise(){return this._ClosePromise}get closeSignal(){return this.connection.closeSignal}get closed(){return this.connection.closed}async waitForConnected(){return new Promise((x,A)=>{let F=()=>{let r=this.status;r!==0&&(this.webRtc.removeEventListener("connectionstatechange",F),r===1?x():A(new Error("connection closed")))};this.webRtc.addEventListener("connectionstatechange",F),F(),this.closePromise.then(()=>{A(new Error("connection closed"))})})}close(){f(`closing ${this.transport} connection to '${this.address}' with id ${this.id}`),this.connection.close()}async joinRoom(x,A,F,r){let t=await this.connection.request("JoinRoom",{token:String(x),room_id:A,user_data:F,position:r});if(t==="closed"||t.type==="Failure")return t;let e=t.value;if(!("token"in e))return(0,h.failure)("JoinRoom responded without token");let j=(0,h.extendUrl)(this.url,`room?token=${e.token}`);if(j.type==="Failure")return j;let v=await f0(j.value,this.closeSignal);return v.type==="Success"?(this._PeerIdMap.set(v.value,e.peer_id),(0,h.success)(new T(v.value))):v}async getReconnectToken(x){let A=await this._Request("RequestReconnectToken",{peer_id:x});return A.type==="Failure"?A:y.parse(A.value)}async getRtcStats(){return this.webRtc.getStats()}async healthCheck(){let x=await this._RequestPing(C.HealthCheckTimeout);return x||this.close(),x}async ping(x=3e4){let A=Date.now();return await this._RequestPing(x)?Date.now()-A:0}sendDatagram(x){if(this._AudioChannel.readyState==="open"){let A=x.byteLength;this._AudioChannel.send(x),this._ConnectionStats.packetsSent+=1,this._ConnectionStats.bytesSent+=A}}_CleanUp(){n(`performing cleanup for connection ${this.id}`),clearInterval(this._PingIntervalId),xA(this._AudioChannel),Lx(this.webRtc),this._WebRtcSession.cleanup(),this.connection.close()}async _HandleWebRtcUpdates(){for(;;){let x=await this.connection.recv();if(x==="closed")break;x.name==="WebRtcUpdate"&&this._WebRtcSession.handleWebRtcUpdate(x.properties)}this.close()}async _Request(x,A,F){let r=Date.now(),t=await(F===void 0?this.connection.request(x,A):this.connection.request(x,A,F)),e=(Date.now()-r)/1e3;return x!=="Ping"&&n(`sent main rpc '${x}'; took: ${e}s`,{properties:A,timeout:F,result:t}),t==="closed"?(0,h.failure)("connection lost"):t}_RequestPing(x=3e4){return this._PingFlight.run(async()=>{let A=await this._Request("Ping",{},x);return A!=="timeout"&&A.type==="Success"})}async startLocalVideo(x,A,F){await this._WebRtcSession.startLocalVideo(x,A,F)}stopLocalVideo(x){this._WebRtcSession.stopLocalVideo(x)}async startRemoteVideo(x){return this._WebRtcSession.startRemoteVideo(x)}stopRemoteVideo(x){this._WebRtcSession.stopRemoteVideo(x)}async dump(){return{type:"WebRtc",id:this.id,address:this.address,url:this.url.toString(),closed:this.closed,audioChannel:{readyState:this._AudioChannel.readyState,bufferedAmount:this._AudioChannel.bufferedAmount},datagrams:{sent:this.connectionStats.packetsSent,received:this.connectionStats.packetsReceived},webRtc:{signalingState:this.webRtc.signalingState,connectionState:this.webRtc.connectionState,iceGatheringState:this.webRtc.iceGatheringState,iceConnectionState:this.webRtc.iceConnectionState,connectionStats:this._WebRtcSession.stats}}}};function FA(D,x,A,F,r){switch(f(`creating ${x} main connection to '${A}'`),x){case"H3":return Px.create(D,A,F,r);case"WebRTC":return Hx.create(D,A,F,r);default:throw new Error(`transport ${x} is not supported`)}}var ox=require("@4players/odin-common"),P=require("@4players/odin-common/api");o();var wx=class{constructor(x,A,F,r){this.id=x;this.connection=A;this.cipher=F;this.mediaMap=r;this._DatagramReceived=0;this._DatagramSent=0;this._DatagramReceivedInvalid=0;this._DatagramSentInvalid=0;A.closeSignal.addEventListener("abort",()=>this.close())}get connectionStats(){return this.connection.connectionStats}get transport(){return this.connection.transport}get address(){return this.connection.address}get status(){return this.closed?2:this.connection.status}get closePromise(){return this.connection.closePromise}get closeSignal(){return this.connection.closeSignal}get closed(){return this.connection.closed}waitForConnected(){return this.connection.waitForConnected()}close(){this.connection.close()}async joinRoom(x,A,F,r){this.cipher.reset();let t=await this.cipher.encryptUserData(F);if(t===B)return(0,ox.failure)("unable to encrypt initial user-data");let e=await this.connection.joinRoom(x,A,t,r);return e==="closed"||e.type==="Failure"?e:(0,ox.success)(new n0(e.value,this.cipher,this))}getReconnectToken(x){return this.connection.getReconnectToken(x)}getRtcStats(){return this.connection.getRtcStats()}healthCheck(){return this.connection.healthCheck()}async sendDatagram(x){let A=await this.cipher.encryptDatagram(x);A!==B?(this._DatagramSent+=1,this.connection.sendDatagram(A)):this._DatagramSentInvalid+=1}async decryptDatagram(x,A){let F=await this.cipher.decryptDatagram(x,A);return F!==B?this._DatagramReceived+=1:this._DatagramReceivedInvalid+=1,F}startLocalVideo(x,A,F){return this.connection.startLocalVideo(x,A,F)}stopLocalVideo(x){return this.connection.stopLocalVideo(x)}startRemoteVideo(x){return this.connection.startRemoteVideo(x)}stopRemoteVideo(x){return this.connection.stopRemoteVideo(x)}async dump(){return{type:"Encrypted",id:this.id,address:this.address,connectionId:this.connection.id,closed:this.closed,transport:this.transport,datagrams:{sent:this._DatagramSent,received:this._DatagramReceived,sentInvalid:this._DatagramSentInvalid,receivedInvalid:this._DatagramReceivedInvalid},cipher:await this.cipher.dump()}}},Jx=class{constructor(x){this.room=x}resendUserData(){this.room.roomConnection?.notify("UpdatePeer",{user_data:this.room.roomConnection.userData})}setUserData(x,A){let F={kind:"UserDataChanged",peer_id:x,user_data:A};this.room.onEvent("PeerUpdated",F)}},n0=class{constructor(x,A,F){this.rpc=x;this.cipher=A;this.connection=F;this.peers=new Map;this.closeSignal.addEventListener("abort",this.cleanup.bind(this),{once:!0})}get closed(){return this.rpc.closed}get closeSignal(){return this.rpc.closeSignal}async request(x,A,F){let r=await this.outgoing(x,A);return r===B?(0,ox.failure)("can not be encrypted"):await this.rpc.request(x,r,F)}async notify(x,A){let F=await this.outgoing(x,A);if(F!==B)return this.rpc.notify(x,F)}async recv(){for(;;){let x=await this.rpc.recv();if(x==="closed")return x;let A=await this.incoming(x.name,x.properties);if(A!==B)return{name:x.name,properties:A}}}close(){return this.rpc.close()}async outgoing(x,A){if(!(x in P.RoomCommandsRpc))return A;let F=(0,P.parseCommand)(x,A,P.RoomCommandsRpc);if(F===void 0)return B;switch(F.name){case"UpdatePeer":{let r=await this.cipher.encryptUserData(F.request.user_data);if(r===B)return B;F.request.user_data=r}break;case"SendMessage":{let r=await this.cipher.encryptMessage(F.request.message);if(r===B)return B;F.request.message=r}break}return F.request}async incoming(x,A){if(!(x in P.RoomNotificationsRpc))return A;let F=(0,P.parseNotification)(x,A,P.RoomNotificationsRpc);if(F===void 0)return B;switch(F.name){case"RoomUpdated":for(let r=0;r<F.properties.updates.length;r++){let t=await this.roomUpdate(F.properties.updates[r]);if(t===B)return B;F.properties.updates[r]=t}break;case"PeerUpdated":{let r=await this.peerUpdate(F.properties);if(r===B)return B;F.properties=r}break;case"MessageReceived":{let r=await this.cipher.decryptMessage(F.properties.sender_peer_id,F.properties.message);if(r===B)return B;F.properties.message=r}break}return F.properties}async peerUpdate(x){switch(x.kind){case"UserDataChanged":{let A=await this.cipher.decryptUserData(x.peer_id,x.user_data);if(A===B)return B;x.user_data=A}break;case"MediaStarted":this.mediaStarted(x.peer_id,x.media.id);break;case"MediaStopped":this.mediaStopped(x.peer_id,x.media_id);break}return x}async roomUpdate(x){switch(x.kind){case"Joined":for(let A of x.room.peers){for(let r of A.medias)this.mediaStarted(A.id,r.id);let F=await this.cipher.decryptUserData(A.id,A.user_data);F!==B?A.user_data=F:A.user_data=new Uint8Array}break;case"PeerJoined":{for(let F of x.peer.medias)this.mediaStarted(x.peer.id,F.id);let A=await this.cipher.decryptUserData(x.peer.id,x.peer.user_data);A!==B?x.peer.user_data=A:x.peer.user_data=new Uint8Array}break;case"PeerLeft":{let A=this.peers.get(x.peer_id);this.peers.delete(x.peer_id),this.cipher.deletePeerKey(x.peer_id);for(let F of A??[])this.mediaStopped(x.peer_id,F)}break}return x}mediaStarted(x,A){let F=this.peers.get(x);F===void 0&&(F=new Set,this.peers.set(x,F)),F.add(A);let r=p({connectionId:this.connection.connection.id,mediaId:A});this.connection.mediaMap.set(r,{peerId:x,connection:this.connection})}mediaStopped(x,A){this.peers.get(x)?.delete(A);let r=p({connectionId:this.connection.connection.id,mediaId:A});this.connection.mediaMap.delete(r)}cleanup(){for(let[x,A]of this.peers)for(let F of A)this.mediaStopped(x,F)}};var Ox=class{constructor(x){this.onDatagram=x;this._LastConnectionId=0;this._Connections=new Map;this._Close=new AbortController;this._MediaMap=new Map;let A=Date.now(),F=setInterval(()=>{Math.abs(Date.now()-A)>C.ClockJumpThreshold&&this.checkHealth(),A=Date.now()},C.ClockJumpCheckInterval);addEventListener("offline",()=>this.checkHealth(),{signal:this._Close.signal}),this._Close.signal.addEventListener("abort",()=>{clearInterval(F);for(let r of this._Connections.values())r.type==="establishing"?r.abort.abort():r.connection.close();this._Connections.clear()},{once:!0})}get closed(){return this._Close.signal.aborted}sendDatagram(x,A){let F=this._Connections.get(x);(F?.type==="established"||F?.type==="virtual")&&F.connection.sendDatagram(A)}async recvDatagram(x,A){let F=kF(A);if(F===void 0||F.length===0)return;let r=this._MediaMap.get(p({connectionId:x,mediaId:F[0]}));if(r===void 0)this.onDatagram(x,A);else{let t=await r.connection.decryptDatagram(r.peerId,A);if(t===B)return;this.onDatagram(r.connection.id,t)}}async acquireConnection(x,A,F,r){if(await(0,ax.nextTick)(),this.closed)return"closed";let t=this.findConnection(x,A),e;switch(t?.type){case"established":n(`reusing existing connection ${t.id}`),e=t;break;case"establishing":{n(`waiting for connecting to '${A}' finish`);let E=await t.finished;if(E.type!=="Success")return E;e=E.value}break;case void 0:{n(`connecting to '${A}'`);let E=await this.createConnection(x,A,r);if(E.type!=="Success")return E;e=E.value}break}let j=e.id,v=new s0(e.connection,()=>this.releaseConnection(j));return e.references+=1,F&&(v=new wx(++this._LastConnectionId,v,F,this._MediaMap),this.addConnection({type:"virtual",id:v.id,connection:v,createdAt:Date.now()})),(0,ax.success)(v)}async createConnection(x,A,F){let r=++this._LastConnectionId,t=Date.now(),e=new AbortController;F.addEventListener("abort",()=>e.abort(),{once:!0}),n(`creating new connection ${r}`);let j=FA(r,x,A,this.recvDatagram.bind(this),F),{promise:v,resolve:E}=Promise.withResolvers();this.addConnection({type:"establishing",id:r,address:A,transport:x,finished:v,createdAt:Date.now(),abort:e});let l=await j;if(this._Connections.delete(r),l.type!=="Success")return E(l),l;let k={type:"established",id:r,address:A,transport:x,createdAt:t,references:0,connection:l.value};return this.addConnection(k),(0,ax.success)(k)}addConnection(x){(x.type==="established"||x.type==="virtual")&&x.connection.closeSignal.addEventListener("abort",()=>{f(`connection ${x.id} has been closed`),this._Connections.delete(x.id)},{once:!0}),this._Connections.set(x.id,x)}releaseConnection(x){let A=this._Connections.get(x);A?.type==="established"&&(A.references-=1,A.references<=0&&A.connection.close())}checkHealth(){for(let x of this._Connections.values())x.type==="established"&&x.connection.healthCheck()}close(){this._Close.abort()}async dump(){let x=[];for(let F of this._Connections.values()){let r;switch(F.type){case"established":r={transport:F.transport,address:F.address,connection:await F.connection.dump(),references:F.references};break;case"establishing":r={transport:F.transport,address:F.address,aborted:F.abort.signal.aborted};break;case"virtual":r={connection:await F.connection.dump()};break}x.push({type:F.type,id:F.id,createdAt:F.createdAt,...r})}let A=[];for(let[F,r]of this._MediaMap)A.push(`${F} -> ${r.peerId} @${r.connection.id} `);return{lastConnectionId:this._LastConnectionId,connections:x,mediaMap:A,closed:this.closed}}findConnection(x,A){for(let F of this._Connections.values())if(F.type!=="virtual"&&F.transport===x&&F.address===A&&(F.type!=="established"||!F.connection.closed))return F}},s0=class{constructor(x,A){this.connection=x;this.release=A;this.closeController=new AbortController;this.closePromise=new Promise(x=>this.closeController.signal.addEventListener("abort",()=>x("closed"),{once:!0}));x.closeSignal.addEventListener("abort",()=>this.close(),{once:!0})}get closeSignal(){return this.closeController.signal}get closed(){return this.closeSignal.aborted}close(){this.release(),this.closeController.abort("closed")}get connectionStats(){return this.connection.connectionStats}get id(){return this.connection.id}get transport(){return this.connection.transport}get address(){return this.connection.address}get status(){return this.connection.status}waitForConnected(){return this.connection.waitForConnected()}joinRoom(x,A,F,r){return this.connection.joinRoom(x,A,F,r)}getReconnectToken(x){return this.connection.getReconnectToken(x)}getRtcStats(){return this.connection.getRtcStats()}healthCheck(){return this.connection.healthCheck()}sendDatagram(x){return this.connection.sendDatagram(x)}startLocalVideo(x,A,F){return this.connection.startLocalVideo(x,A,F)}stopLocalVideo(x){return this.connection.stopLocalVideo(x)}startRemoteVideo(x){return this.connection.startRemoteVideo(x)}stopRemoteVideo(x){return this.connection.stopRemoteVideo(x)}async dump(){let x=await this.connection.dump();return typeof x=="object"&&(x={...x,isShared:!0,referenceClosed:this.closed}),x}};function kF(D){let x;try{x=(0,rA.decode)(D)}catch{return}if(!Array.isArray(x)||x.length<2)return;let A=x[1];if(Array.isArray(A))return A.map(Number)}var Sx=require("@4players/odin-common"),H=class{constructor(x,A){this.uid=x;this.customType=A}#x;#A;get mediaStream(){return this.#x}get audioPlayback(){return(0,Sx.assert)(this.#A,"getting the audioPlayback failed, this video has no Audio"),this.#A}get volume(){return(0,Sx.assert)(this.audioPlayback,"getting the volume failed, this video has no Audio"),this.audioPlayback.volume}setVolume(x){(0,Sx.assert)(this.#A,"Can not set the volume, this video has no Audio"),this.#A.setVolume(x)}setMediaStream(x){this.#x=x}close(){this.#x?.getVideoTracks().forEach(x=>{x.stop(),this.#x?.removeTrack(x)}),this.#x=void 0}};var S=require("@4players/odin-common"),kA=require("@4players/odin-common/api");var b=require("@4players/odin-common"),V=require("@4players/odin-common/api");o();var Ux=class{constructor(x,A,F,r,t,e,j,v,E,l){this.connectionPool=x;this.transport=A;this.onEvent=F;this.gateway=r;this.roomId=e;this.cipher=E;this.disableAutoReconnect=l;this._Close=new AbortController;this._TokenUsed=!1;this._WasConnected=!1;this._FailedConnections=0;this._LastTokenRenew=performance.now();this._LastReconnectStartedAt=0;this._ReconnectingSince=0;this._Closed=new Promise(x=>this._Close.signal.addEventListener("abort",()=>x(this._Close.signal.reason?"disconnected":"closed"),{once:!0}));this._Token=t,this._UserData=j,this._Position=v,this._Main().then(({reason:k})=>n(`_Main() resolved; ${k}`))}get token(){return this._Token}get userData(){return this._UserData}get position(){return this._Position}get closed(){return this._Close.signal.aborted}get mainConnection(){return this._MainConnection}async requestUnsafe(x,A){if(this._RoomConnection===void 0)return(0,b.failure)("currently not connected");let F=await this._RoomConnection.request(x,A,void 0);return(0,b.assert)(F!=="timeout","request should not timeout"),F!=="closed"&&F.type==="Success"&&this._HandleRequests(x,A,F.value),F}async request(x,A){let F=Date.now(),r=await this.requestUnsafe(x,A),t=(Date.now()-F)/1e3;if(n(`sent room rpc '${x}'; took: ${t}s`,{properties:A,result:r}),r==="closed"||r.type==="Failure")return r;let e=(0,V.parseResponse)(x,r.value,V.RoomCommandsRpc);return e!==void 0?(0,b.success)(e):(0,b.failure)(`received invalid response from ${x}`)}notify(x,A){this._RoomConnection!==void 0&&this._RoomConnection.notify(x,A)}close(){this._Close.abort(!0)}get renewTokenIn(){let x=this._LastTokenRenew-performance.now()+C.MinTokenRefreshInterval,A=this._Token.timeLeft-C.MinTokenLifetime;return Math.max(x,A)}async _Main(){let x;for(let A=0;;this._FailedConnections++){if(await(0,b.sleep)(Math.max(A-performance.now(),0)),this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}if(this._WasConnected&&this._ReconnectingSince!==0&&DA(this._ReconnectingSince,C.MaxReconnectDuration)){x="reconnect time limit reached";break}if(A=performance.now()+1e3,this._TokenUsed=!0,this._Token.hasAudience("sfu")){let F=await this._ConnectToServer();if(F.type==="Success"&&F.value==="shutdown"){n("connection closed by user request; shutting down"),x="user requested";break}if(this.disableAutoReconnect&&this._WasConnected){x=F.type==="Failure"?F.reason:"connection lost";break}if(this._LastReconnectStartedAt===0&&(this._LastReconnectStartedAt=performance.now()),this._WasConnected&&this._ReconnectingSince===0&&(this._ReconnectingSince=performance.now()),F.type==="Failure"&&!this._WasConnected&&this._FailedConnections>=3){x=F.reason;break}if(F.type==="Failure"&&!DA(this._LastReconnectStartedAt))continue}if(this.reset(),this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}if(this.gateway!==void 0&&this._Token.hasAudience("gateway")){this._ChangeStatus("Joining",`requesting new token from ${this.gateway}`);let F=await cF(this.gateway,this._Token,this._Close.signal);if(F.type==="Success")if(F.value instanceof y)A=0,this._Token=F.value,this._TokenUsed=!1;else{x=`gateway error; ${F.value}`;break}else if(!this._WasConnected&&this._FailedConnections>=3){x="unable to contact the gateway";break}}if(this._TokenUsed&&this._Token.timeLeft<=0){x="token has expired";break}if(this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}}return this._ChangeStatus("Closed",x),this.close(),(0,b.failure)(x)}async _ConnectToServer(){let x=this._Token;for(;x.upstream!==void 0;)x=x.upstream;let A=x.claims.adr??this.gateway?.toString();if(!A)return(0,b.success)("continue");if(this._ChangeStatus("Joining",`connecting to ${x.claims.adr}`),this._MainConnection===void 0||this._MainConnection.closed||this._MainConnection.address!==x.claims.adr){this._MainConnection?.close();let t=await this.connectionPool.acquireConnection(this.transport,A,this.cipher,this._Close.signal);if(t==="closed")return(0,b.failure)("connection pool closed");if(t.type==="Failure")return this._ChangeStatus("Joining",`connection failed; ${t.reason}`),(0,b.failure)(`connection failed; ${t.reason}`);this._MainConnection=t.value,this._OwnPeerId=void 0}let F=await Promise.race([Promise.all([this._MainConnection.joinRoom(x,this.roomId,this.userData,this.position)]),(0,b.sleep)(C.ConnectTimeout,"timeout"),this._Closed]);if(F==="closed"||F==="disconnected")return(0,b.success)("continue");if(F==="timeout")return this._ChangeStatus("Joining","timed out"),(0,b.success)("continue");let[r]=F;if(r==="closed")return(0,b.success)("continue");if(r.type==="Failure")return(0,b.failure)(`unable to join room; ${r.reason}`);this._RoomConnection=r.value,this._WasConnected=!0,this._FailedConnections=0,this._ReconnectingSince=0,this._ChangeStatus("Joined",`joined ${this.roomId}`);try{await this._MainConnection.waitForConnected();let t=await this._HandleConnection(this._MainConnection);return(0,b.success)(t?"shutdown":"continue")}catch(t){return(0,b.failure)(`unable to handle connection; ${t}`)}}_ChangeStatus(x,A){let F={status:x,message:A};this.onEvent("RoomStatusChanged",F)}async _HandleConnection(x){if(this._RoomConnection===void 0)return!1;let A=new b.Selector([()=>(0,b.sleep)(this.renewTokenIn,"renewToken"),()=>(0,b.sleep)(500,"tick"),async()=>await this._RoomConnection?.recv(),()=>this._Closed,()=>x.closePromise]);for(;;){let F=await A.next();switch(F){case void 0:case"closed":return this._RoomConnection?.close(),this._MainConnection?.close(),!1;case"disconnected":return this._RoomConnection?.close(),this._MainConnection?.close(),!0;case"renewToken":this._RenewToken();break;case"tick":break;default:this._HandleEvent(F);break}}}_HandleEvent(x){if(x.name==="RoomUpdated"){let A=V.RoomNotificationsRpc.RoomUpdated.safeParse(x.properties);if(!A.success)return;for(let F of A.data.updates)F.kind==="Joined"&&(this._OwnPeerId=F.own_peer_id)}this.onEvent(x.name,x.properties)}_HandleRequests(x,A,F){switch(x){case"SetPeerPosition":{let r=V.RoomCommandsRpc.SetPeerPosition.request.safeParse(A);if(r.success){let t=r.data.position;this._Position=t.length===2?[t[0],t[1],0]:t}else i("unable to process SetPeerPosition command");break}case"UpdatePeer":{let r=V.RoomCommandsRpc.UpdatePeer.request.safeParse(A);r.success?this._UserData=r.data.user_data:i("unable to process UpdatePeer command");break}}}async _RenewToken(x){if(this._LastTokenRenew=performance.now(),!x&&this.token.timeLeft>C.MinTokenLifetime)return;if(this._MainConnection===void 0||this._OwnPeerId===void 0)return(0,b.failure)("connection is not established");let A=await this._MainConnection.getReconnectToken(this._OwnPeerId);return A.type==="Success"?(this._Token=A.value,(0,b.success)()):(0,b.failure)(`${this._MainConnection.address} rejected reconnect token request; ${A.reason}`)}reset(){this._LastReconnectStartedAt=0,this._RoomConnection?.close(),this._RoomConnection=void 0,this._MainConnection?.close(),this._MainConnection=void 0,this._OwnPeerId=void 0}};async function cF(D,x,A){try{let F={jsonrpc:"2.0",id:1,method:"Connect",params:{}};f(`sending authentication request to '${D}'`,F);let t=await(await fetch(D,{body:JSON.stringify(F),method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${x}`},signal:A})).json();if(f(`received authentication response fom '${D}'`,t),"result"in t)return y.parse(t.result.token);{let e=t.error?.message??"malformed response";return u(`gateway rejected token; ${e}`),(0,b.success)(e)}}catch(F){return(0,b.failure)(String(F))}}function DA(D,x=8e3){return performance.now()-D>x}o();var lA=require("@4players/odin-common");var W=require("@4players/odin-common");o();var sA=require("@4players/odin-common");o();var fA=require("@msgpack/msgpack");o();var tA={name:"PBKDF2",hash:"SHA-256",iterations:6e5,salt:new Uint8Array([111,100,105,110,95,99,114,121,112,116,111,95,109,97,115,116,101,114,95,107,101,121])},eA=D=>({name:"PBKDF2",hash:"SHA-256",iterations:600,salt:D}),jA=32,BA=1e6,vA=2147483648,CA=32,O=[79,68,73,78,1,75,105,109],Ex=16,fx=64,EA=16;function nA(D,x){if(D.length!==x.length)return!1;for(let A=0;A<D.length;A++)if(D[A]!==x[A])return!1;return!0}function dF(D){return isFinite(D)}function pF(D){return Array.isArray(D)}function Mx(D){return dF(D)?D:B}function lx(D){return D instanceof Uint8Array?D:B}function hF(D,...x){let A;try{A=(0,fA.decode)(D)}catch{return B}if(!pF(A))return B;let F=new Array(A.length);for(let r in x)if(F[r]=x[r](A[r]),F[r]===B)return B;return F}function Tx(D,...x){if(D.length<O.length)return m;for(let A=0;A<O.length;A++)if(D[A]!==O[A])return m;return hF(D.subarray(O.length),...x)}var nx=class{constructor(x){this.first=1;this.offset=0;this.window=Array(x)}isReplay(x){let A=x-this.first;if(A<0)return!0;if(A>=this.window.length)if(A<this.window.length*2){let t=A-this.window.length+1;A-=t;for(let e=0;e<t;e++)this.advance()}else return this.first=x+1-self.window.length,this.offset=0,this.window.fill(!1),!1;let F=(this.offset+A)%this.window.length,r=this.window[F]===!0;for(this.window[F]=!0;this.window[this.offset]===!0;)this.advance();return r}advance(){this.window[this.offset]=!1,this.first+=1,this.offset=(this.offset+1)%this.window.length}};var Rx=class D{constructor(x){this.key=x}static async create(x){typeof x=="string"&&(x=new TextEncoder().encode(x));let A=await globalThis.crypto.subtle.importKey("raw",x,"PBKDF2",!1,["deriveBits"]),F=await globalThis.crypto.subtle.deriveBits(tA,A,256),r=await globalThis.crypto.subtle.importKey("raw",F,"PBKDF2",!1,["deriveKey"]);return new D(r)}async generatePeerKey(x,A){return await globalThis.crypto.subtle.deriveKey(eA(x),this.key,{name:"AES-GCM",length:256},!1,[A])}},Kx=class D{constructor(x,A){this.seed=x;this.key=A;this.sequenceNumbers={datagram:1,message:1,userData:1};this.number_of_packets=0;this.number_of_bytes=0}static async create(x){let A=globalThis.crypto.getRandomValues(new Uint8Array(jA)),F=await x.generatePeerKey(A,"encrypt");return new D(A,F)}get limitReached(){return this.key===void 0?!1:this.number_of_bytes>=vA||this.number_of_packets>=BA}nextSequenceNumber(x){return this.sequenceNumbers[x]++}};function i0(D,x){return{kind:"encrypted",key:D,material:x,antiReplays:{datagram:new nx(CA),userData:new nx(0),message:new nx(0)}}}var Vx=class D{constructor(x,A,F,r){this.additionalData=x;this.sequenceNumber=A;this.seed=F;this.encrypted=r}static parse(x){let A=Tx(x,lx,Mx,lx);if(A===B||A===m)return A;let[F,r,t]=A,e=x.subarray(0,x.length-t.length);return new D(e,r,F,t)}isSameSeed(x){return nA(this.seed,x.seed)}async generateKey(x){return await x.generatePeerKey(this.seed,"decrypt")}};function Wx(D,x){let A=new Uint8Array(12);switch(A[0]=x&255,A[1]=x>>8&255,A[2]=x>>16&255,A[3]=x>>24&255,D){case"datagram":A[5]=1;break;case"userData":A[5]=2;break;case"message":A[5]=3;break;default:(0,sA.assert)(!1,"missing content implementation")}return A}var b0=require("@msgpack/msgpack"),bA=require("@4players/odin-common");o();var Qx=class{constructor(x){this.actions=x}changeKey(x){this.masterKey!==x&&(this.masterKey=x,this.ownKey=B,this.actions.resendUserData())}async encryptDatagram(x){let A=await this.getKey("datagram");return A===void 0?x:A===U?B:await GF(A,x)}async encryptMessage(x){let A=await this.getKey("message");return A===void 0?x:A===U?U:await iA(A,x,"message")}async encryptUserData(x){let A=await this.getKey("userData");return A===void 0?x:((0,bA.assert)(A!==U,"key unavailable for user data encryption"),await iA(A,x,"userData",A.seed))}async getKey(x){if(this.ownKey===B||this.ownKey?.limitReached)if(x==="userData")this.ownKey=this.masterKey?await Kx.create(this.masterKey):void 0;else return this.ownKey!==B&&(this.ownKey=B,this.actions.resendUserData()),U;return this.ownKey}reset(){this.ownKey=this.masterKey?B:void 0}};async function iA(D,x,A,...F){let r=D.nextSequenceNumber(A),t=x.length+Ex,e=qF(r,F,t),j=e.length-t,v=await oA(D,A,r,e.subarray(0,j),x);return e.set(new Uint8Array(v),j),e}function qF(D,x,A){let F=[];x.forEach(e=>F.push(e)),F.push(D),F.push(new Uint8Array(A));let r=(0,b0.encode)(F),t=new Uint8Array(O.length+r.length);return t.set(O,0),t.set(r,O.length),t}async function GF(D,x){let A=$F(x);if(A===B)return B;if((A.kind&fx)!==0)return B;let F=A.body.length+Ex,r=D.nextSequenceNumber("datagram"),t=(0,b0.encode)([A.kind|fx,A.mediaIds,r,new Uint8Array(F)]),e=t.length-F,j=await oA(D,"datagram",r,t.subarray(0,e),A.body);return t.set(j,e),t}async function oA(D,x,A,F,r){return new Uint8Array(await globalThis.crypto.subtle.encrypt({name:"AES-GCM",iv:Wx(x,A),additionalData:F,tagLength:Ex*8},D.key,r))}function $F(D){let x=new M(D),A=x.readArrayLength();if(s(A)||A<2)return B;let F=x.readNumber(),r=x.readArrayLength();if(s(F)||s(r))return B;if(r>EA)return B;let t=Array(r);for(let j=0;j<t.length;j++){let v=x.readNumber();if(s(v))return B;t[j]=v}let e=D.subarray(x.position);return{kind:F,mediaIds:t,body:e}}var aA=require("@msgpack/msgpack");o();var Xx=class{constructor(x){this.actions=x;this.peerKeys=new Map}async changeKey(x){this.masterKey=x;for(let[A,{kind:F,material:r}]of this.peerKeys)if(x!==void 0){let t=await r.generateKey(x),e=i0(t,r),j=await zx(e,"userData",r.additionalData,r.sequenceNumber,r.encrypted);j!==B?(this.peerKeys.set(A,e),this.actions.setUserData(A,j)):(this.peerKeys.set(A,{kind:"broken",material:r}),this.actions.setUserData(A,new Uint8Array))}else F==="encrypted"&&this.peerKeys.set(A,{kind:"broken",material:r})}async decryptDatagram(x,A){let F=yF(A);if(this.masterKey===void 0)return F===m?A:B;if(F===B||F===m)return B;let r=this.peerKeys.get(x);if(r?.kind!=="encrypted")return B;let t=await zx(r,"datagram",F.additionalData,F.sequenceNumber,F.encrypted);return t===B?B:IF(F.kind&~fx,F.mediaIds,t)}async decryptMessage(x,A){let F=Tx(A,Mx,lx);if(this.masterKey===void 0)return F===m?A:B;if(F===B||F===m)return B;let r=this.peerKeys.get(x);if(r?.kind!=="encrypted")return B;let[t,e]=F,j=A.subarray(0,A.length-e.length);return zx(r,"message",j,t,e)}async decryptUserData(x,A){let F=Vx.parse(A);if(F===B)return B;if(F===m)return this.peerKeys.delete(x),this.masterKey===void 0?A:B;if(this.masterKey===void 0)return this.peerKeys.set(x,{kind:"broken",material:F}),B;let r=this.peerKeys.get(x);if(r?.kind==="encrypted"&&r.material.isSameSeed(F))r.material=F;else{let e=await F.generateKey(this.masterKey);r=i0(e,F)}let t=await zx(r,"userData",F.additionalData,F.sequenceNumber,F.encrypted);return t===B?this.peerKeys.set(x,{kind:"broken",material:F}):r!==void 0&&this.peerKeys.set(x,r),t}reset(){this.peerKeys.clear()}};function yF(D){let x=new M(D),A=x.readArrayLength();if(s(A)||A<1)return B;let F=x.readNumber();if(s(F))return B;if((F&fx)===0)return m;if(A!==4)return B;let r=x.position;x.readObjects(1);let t=D.subarray(r,x.position),e=x.readNumber(),j=x.readBytes();if(s(e)||s(j))return B;let v=D.subarray(0,D.length-j.length);return{kind:F,mediaIds:t,additionalData:v,sequenceNumber:e,encrypted:j}}async function zx(D,x,A,F,r){let t=await globalThis.crypto.subtle.decrypt({name:"AES-GCM",iv:Wx(x,F),additionalData:A,tagLength:Ex*8},D.key,r).catch(()=>B);return t===B?B:D.antiReplays[x].isReplay(F)?B:new Uint8Array(t)}function IF(D,x,A){let F=2;try{let e=new M(A);for(e.position=0;e.position<A.length;)e.readObjects(1),F+=1}catch{return B}let r=(0,aA.encode)(D),t=new Uint8Array(3+r.length+x.length+A.length);return t[0]=220,t[1]=F>>8&255,t[2]=F&255,t.set(r,3),t.set(x,3+r.length),t.set(A,3+r.length+x.length),t}var Zx=class{constructor(x,A){this.active=!1;let F=new Xx(A),r=new Qx(A);this.crypto=new W.Strand({encryption:r,decryption:F}),this.peerKeys=F.peerKeys,this.configure(x)}encryptUserData(x){return this.crypto.enqueue(({encryption:A})=>A.encryptUserData(x))}async encryptMessage(x){let A;do A=await this.crypto.enqueue(({encryption:F})=>F.encryptMessage(x));while(A===U);return A}async encryptDatagram(x){return await this.crypto.enqueue(({encryption:A})=>A.encryptDatagram(x))}decryptUserData(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptUserData(x,A))}decryptMessage(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptMessage(x,A))}decryptDatagram(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptDatagram(x,A))}configure(x){return this.crypto.enqueue(async A=>{let F=x.password?await Rx.create(x.password):void 0;this.active=F!==void 0,await A.encryption.changeKey(F),await A.decryption.changeKey(F)})}getPeerStatus(x){switch(this.peerKeys.get(x)?.kind??"unencrypted"){case"broken":return W.Backend.PeerCipherStatus.InvalidPassword;case"encrypted":return W.Backend.PeerCipherStatus.Encrypted;case"unencrypted":return this.active?W.Backend.PeerCipherStatus.InvalidPassword:W.Backend.PeerCipherStatus.Unencrypted;default:return W.Backend.PeerCipherStatus.Unknown}}deletePeerKey(x){this.peerKeys.delete(x)}reset(){return this.crypto.enqueue(async({encryption:x,decryption:A})=>{x.reset(),A.reset()})}async dump(){return this.crypto.enqueue(async()=>({active:this.active,peers:Array.from(this.peerKeys).map(([x,A])=>`${x} => ${A.kind}`)}))}};function uA(D,x){return(0,lA.assert)(D.type==="OdinCrypto","only OdinCrypto supported"),new Zx(D,x)}var Yx=class{constructor(x,A,F){this._Captures=new Map;this._Playbacks=new Map;this._Peers=new Map;this._AvailableMediaIds=[];let{url:r,onEvent:t}=A,e=(0,S.unwrap)(y.parse(A.token)),j=A.roomId??e.defaultRoomId,v=A.userData??new Uint8Array(0),E=A.position??[0,0,0];(0,S.assert)(j!==void 0,"room id required for multi-room-tokens"),this.cipher=A.cipher?uA(A.cipher,new Jx(this)):void 0,this.onEvent=t,f(`creating new room '${j}' ${this.cipher?"with":"without"} cipher`,e,v,E),this._Connection=new Ux(x,A.transport??"H3",this._HandleEvent.bind(this),r?new URL(r):void 0,e,j,v,E,this.cipher,F?.disableAutoReconnect??!1)}get connectionStats(){let x={...S.CONNECTION_STATS_INITIAL};return this.mainConnection?this.mainConnection.connectionStats:x}async getRtcStats(){return this.mainConnection?.getRtcStats()}get roomConnection(){return this._Connection}get mainConnection(){return this.roomConnection?.mainConnection}get token(){return this._Connection.token.text}request(x,A){return this._Connection.requestUnsafe(x,A)}async link(x){if(x instanceof _){let A=this._Playbacks.get(x.uid)??{media:void 0,playback:void 0};A.playback!==void 0&&this.unlink(A.playback),A.media!==void 0&&x.start(A.media),A.playback=x,f(`linking audio playback media '${x.uid}' with volume ${x.volume} to room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof N){let A=this._Captures.get(x);A&&this.unlink(x);let F=this.mainConnection!==void 0&&this._AvailableMediaIds.shift();A={media:F?{connectionId:this.mainConnection.id,mediaId:F}:void 0},f(`linking audio capture media '${x.uid}' with volume ${x.volume} to room '${this._Connection.roomId}'`),this._Captures.set(x,A),A.media!==void 0&&await x.start(this._Connection,A.media)}else if(x instanceof H){let A=this._Playbacks.get(x.uid)??{media:void 0,playback:void 0};if(A.playback!==void 0&&A.playback!==x&&(A.playback instanceof H?(A.playback.setMediaStream(void 0),A.playback=void 0):this.unlink(A.playback)),A.media!==void 0){let F=await this.mainConnection?.startRemoteVideo(A.media.mediaId);F&&x.setMediaStream(new MediaStream([F]))}A.playback=x,f(`linking video playback media '${x.uid}' with type '${x.customType}' to room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof $){let A=this._Captures.get(x);A&&this.unlink(x);let F=x.mediaStream?.getVideoTracks()[0];if(F){let r=this.mainConnection!==void 0&&this._AvailableMediaIds.shift();A={media:r?{connectionId:this.mainConnection.id,mediaId:r}:void 0},f(`linking video capture media '${x.uid}' with type '${x.parameters?.customType}' to room '${this._Connection.roomId}'`),this._Captures.set(x,A),A.media!==void 0&&(await x.start(this._Connection,A.media),this.mainConnection?.startLocalVideo(A.media.mediaId,F,x.parameters)),x.audioCapture&&await this.link(x.audioCapture)}}else throw new Error("Linking failed, media was not supported")}unlink(x){if(x instanceof _||x instanceof H){let A=this._Playbacks.get(x.uid);if(A?.playback!==x)return;A.playback=void 0,A.media!==void 0&&(x instanceof _?x.stop(A.media):(this.mainConnection?.stopRemoteVideo(A.media.mediaId),x.setMediaStream(void 0))),f(`unlinking playback media '${x.uid}' from room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof N||x instanceof $){x instanceof $&&x.audioCapture&&this.unlink(x.audioCapture);let A=this._Captures.get(x);if(A===void 0)return;A.media!==void 0&&(x.stop(this._Connection,A.media),this._AvailableMediaIds.push(A.media.mediaId),x instanceof $&&this.mainConnection?.stopLocalVideo(A.media.mediaId)),f(`unlinking capture media '${x.uid}' from room '${this._Connection.roomId}'`),this._Captures.delete(x)}else throw new Error("invalid media")}close(){f(`closing room '${this._Connection.roomId}'`),this._Connection.close()}_HandleEvent(x,A){let F=E0(kA.RoomNotificationsRpc,{name:x,properties:A});F!==void 0&&(this._HandleKnownEvent(F),A=F.properties),this.onEvent(x,A)}_HandleKnownEvent(x){switch(n(`processing event '${x.name}'`,x.properties),x.name){case"RoomStatusChanged":x.properties.status!=="Joined"&&this._HandleConnectionLost();break;case"RoomUpdated":for(let A of x.properties.updates)this._HandleRoomUpdate(A);break;case"PeerUpdated":this._HandlePeerUpdate(x.properties);break}}_HandleConnectionLost(){for(let x of this._Peers.keys())this._HandlePeerLeft(x);for(let[x,A]of this._Captures)A.media!==void 0&&(x instanceof $,x instanceof N&&(x.stop(this._Connection,A.media),A.media=void 0));this._AvailableMediaIds.length=0}_HandleRoomUpdate(x){if(x.kind==="Joined"){(0,S.assert)(this._AvailableMediaIds.length===0,"left over media ids"),this._AvailableMediaIds.push(...x.media_ids),this._HandleRoomJoined();for(let A of x.room.peers)this._HandlePeerJoined(A)}else x.kind==="PeerJoined"?this._HandlePeerJoined(x.peer):x.kind==="PeerLeft"&&this._HandlePeerLeft(x.peer_id)}_HandleRoomJoined(){for(let[x,A]of this._Captures)this._AvailableMediaIds.length===0||this.mainConnection===void 0||(A.media={connectionId:this.mainConnection.id,mediaId:this._AvailableMediaIds.shift()},x instanceof N&&x.start(this._Connection,A.media),x instanceof $)}_HandlePeerUpdate(x){x.kind==="MediaStarted"?this._HandleMediaStart(x.peer_id,x.media):x.kind==="MediaStopped"&&this._HandleMediaStopped(x.peer_id,x.media_id)}_HandlePeerJoined(x){this._Peers.has(x.id)||this._Peers.set(x.id,{mediaIds:new Map});for(let A of x.medias)this._HandleMediaStart(x.id,A)}_HandlePeerLeft(x){let A=this._Peers.get(x);if(A!==void 0){for(let F of A.mediaIds.keys())this._HandleMediaStopped(x,F);this._Peers.delete(x)}}_HandleMediaStart(x,A){if(this.mainConnection===void 0)return;let F=this._Peers.get(x);if(F===void 0||A.properties.kind!=="audio"&&A.properties.kind!=="video")return;let r=String(A.properties.uid??(0,S.generateUUID)());A.properties.uid=r;let t=this._Playbacks.get(r)??{media:void 0,playback:void 0};if(this._Playbacks.set(r,t),F.mediaIds.set(A.id,r),t.media={connectionId:this.mainConnection.id,mediaId:A.id},t.playback!==void 0&&(t.playback instanceof _&&t.playback.start(t.media),t.playback instanceof H)){let e=t.playback;this.mainConnection.startRemoteVideo(t.media.mediaId).then(j=>{e.setMediaStream(new MediaStream([j]))}).catch(j=>{i(`failed to start remote video for media ${A.id}`,j)})}}_HandleMediaStopped(x,A){let F=this._Peers.get(x);if(F===void 0)return;let r=F?.mediaIds.get(A);if(r===void 0)return;let t=this._Playbacks.get(r);t!==void 0&&(t.media!==void 0&&t.media.mediaId===A&&t.playback!==void 0&&(t.playback instanceof _&&t.playback.stop(t.media),t.playback instanceof H&&this.mainConnection?.stopRemoteVideo(t.media.mediaId),t.media=void 0),F.mediaIds.delete(A))}};mx();function _F(D,x){I0(x?.logger,x?.onLogMessage);let A,F=new Ox((t,e)=>A.receivePacket(t,e)),r=new yx(D);return A=new Ix(r,F.sendDatagram.bind(F),x?.enableHTMLAudioElementFallback??!1),new o0(F,A,x)}var bx=(0,gF.generateUUID)(),a0=[],cA=!1;function LF(){cA||typeof window>"u"||(window.addEventListener("beforeunload",()=>{for(let D of a0)D.deref()?.close()}),cA=!0)}var o0=class{constructor(x,A,F){this.version="9";this.supportedTransports=["H3","WebRTC"];this._PlaybackVolume=[1,1];this._CreatedAt=Date.now();this._Options=F??{},this._Options.disableBeforeUnload||LF(),this._ConnectionPool=x,this._MediaController=A,a0.push(new WeakRef(this)),f("plugin initialized")}get playbackVolume(){return this._PlaybackVolume}joinRoom(x){return new Yx(this._ConnectionPool,x,this._Options)}async createAudioPlayback(x){return this._MediaController.createAudioPlayback(x)}async createAudioCapture(x){return this._MediaController.createAudioCapture(x)}async createVideoCapture(x,A){return this._MediaController.createVideoCapture(x,A)}async createVideoPlayback(x){return new H(x.uid,x.customType)}enumerateDevices(){return hx()}setOutputVolume(x){this._MediaController.playbackSetGlobalVolume(x)}async setOutputDevice(x){await this._MediaController.playbackSetDevice(x.device)}close(){this._MediaController.close(),this._ConnectionPool.close(),f("plugin closed")}async dump(){return{createdAt:this._CreatedAt,connections:await this._ConnectionPool.dump(),medias:await this._MediaController.dump()}}};async function dA(){let D=[];for(let x of a0){let A=x.deref();A!==void 0&&D.push(await A.dump())}return JSON.stringify({timestamp:Date.now(),instances:D,background:await N0()})}globalThis.odin_debug_dump_state=dA;window!==void 0&&(window.odin_debug_dump_state=dA);0&&(module.exports={SESSION_ID,createPlugin});
6452
+ `});var C0,T0=d(()=>{C0='"use strict";(()=>{var P=Object.defineProperty;var M=(e,t)=>{for(var r in t)P(e,r,{get:t[r],enumerable:!0})};var u={};M(u,{AdditionalCaptureBlocks:()=>E,AdditionalPlaybackBlocks:()=>R,ClockJumpCheckInterval:()=>_,ClockJumpThreshold:()=>N,ConnectInterval:()=>Q,ConnectTimeout:()=>G,DefaultRefreshRate:()=>D,DefaultVideoCodec:()=>K,HealthCheckTimeout:()=>O,MainConnectionPingInterval:()=>W,MaxNumberOfDecoders:()=>L,MaxReconnectDuration:()=>Y,MinDBFs:()=>v,MinTokenLifetime:()=>Z,MinTokenRefreshInterval:()=>q,PlaybackPreload:()=>F,RenderQuantumSize:()=>V,VadPreload:()=>C,WebRtcAnswerTimeout:()=>J,WebRtcIceTimeout:()=>$,WebRtcMaxNegotiationAttempts:()=>z,WebRtcStatsSnapshotInterval:()=>j,WebRtcTimeout:()=>H});var R=3,E=3,F=3,D=250,C=3,L=512,V=128,v=-758.596,O=1e4,_=1e3,N=1e4,W=3e3,j=1e3,$=3e3,H=1e4,J=1e4,z=3,G=5e3,Z=6e4,q=5e3,Q=[0,100,200,200,500],Y=12e4,K="H264";function d(e,t,r){return e.postMessage(t,r)}var X;(e=>{let t;(r=>(r[r.InvalidPassword=-1]="InvalidPassword",r[r.Unknown=0]="Unknown",r[r.Unencrypted=1]="Unencrypted",r[r.Encrypted=2]="Encrypted"))(t=e.PeerCipherStatus||={})})(X||={});var{Deno:k}=globalThis,ee=typeof k?.noColor=="boolean"?k.noColor:!1,te=!ee;function m(e,t){return{open:`\\x1B[${e.join(";")}m`,close:`\\x1B[${t}m`,regexp:new RegExp(`\\\\x1b\\\\[${t}m`,"g")}}function h(e,t){return te?`${t.open}${e.replace(t.regexp,t.open)}${t.close}`:e}function p(e){return h(e,m([0],0))}function U(e){return h(e,m([1],22))}function re(e){return h(e,m([2],22))}var Ie=new RegExp(["[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)","(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TXZcf-nq-uy=><~]))"].join("|"),"g"),ne=new Date,f=(e=>(e[e.CRITICAL=0]="CRITICAL",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG",e))(f||{}),T={0:"\\u{1F4A5}",1:"\\u{1F534}",2:"\\u{1F7E1}",3:"\\u{1F535}",4:"\\u{1F7E3}"},se={4:re,3:p,2:p,1:U,0:U};function oe({message:e}){return String(e)}function S(e){return JSON.stringify({timestamp:e.date.toISOString(),level:f[e.level],message:e.message,extra:e.extra})}function I(e){function t(c,i){return[Math.floor(c/i),c%i]}function r(){let c,i=e.date.valueOf()-ne.valueOf();[i,c]=t(i,1e3);let[B,A]=t(i,60);return`${B.toString().padStart(4,"0")}:${A.toString().padStart(2,"0")}.${c.toString().padStart(3,"0")}`}function n(){return e.extra===void 0?"":typeof Deno=="object"?" "+Deno.inspect(e.extra,{compact:!1,colors:!0,trailingComma:!0}).trimStart():" "+JSON.stringify(e.extra)}let s=T[e.level],a=e.logger.name!==void 0?`@${e.logger.name}`:"";return`${p(r())}${a} ${s} ${se[e.level](String(e.message))}${n()}`}function ae(e){let t=`[${e.date.toISOString()}]`,r=`[${f[e.level]}]`,n=e.logger.name!==void 0?`[${e.logger.name}] `:"",s=T[e.level];return`${t} ${s} ${r.padEnd(7," ")} ${n}${e.message}`}function ie(){return typeof Deno=="object"&&Deno.stdout.isTerminal()}var w=class{static sparse=oe;static json=S;static pretty=I;static structured=ae;static default=ie()?I:S;constructor(){}};var ce=class{formatter;consoleObject;filter;constructor(e=w.default,t=4,r=console){this.filter=t,this.formatter=e,this.consoleObject=r}handle(e){let t=this.formatter(e);switch(e.level){case 0:case 1:this.consoleObject.error(t);break;case 2:this.consoleObject.warn(t);break;case 3:this.consoleObject.info(t);break;case 4:this.consoleObject.debug(t);break}}};var o=class{#e;sinks;filter;parent;get name(){return this.#e}constructor(e,t=void 0,r=[],n=void 0){this.#e=t,this.sinks=r,this.filter=e,this.parent=n}log(e,t,r=void 0){let n={date:new Date,level:e,logger:this,message:t,extra:r};this.filter<e||this.insert(n)}insert(e){if(!(this.filter<e.level)){for(let t of this.sinks)t.filter>=e.level&&t.handle(e);this.parent!==void 0&&this.parent.insert(e)}}error=this.log.bind(this,1);warn=this.log.bind(this,2);info=this.log.bind(this,3);debug=this.log.bind(this,4)},l=globalThis[Symbol.for("odin-global-logger")]??=new o(3,void 0,[new ce]),ue=o.prototype.log.bind(l,1),le=o.prototype.log.bind(l,2),fe=o.prototype.log.bind(l,3),de=o.prototype.log.bind(l,4),Te=o.prototype.log.bind(l);var b=class extends AudioWorkletProcessor{constructor(){super();this.alive=!0;this.blocks=0;this.port.onmessage=this.onMessage.bind(this)}async onMessage(r){let[n,s]=r.data;switch(n){case"init":this.state=new y(s.workerPort,sampleRate*.02);break;case"close":this.alive=!1;break;case"dump":s.result.postMessage(this.dump());break}}process(r,n,s){if(this.state===void 0||r.length<1||r[0].length<1)return this.alive;let a=this.state.fill(0,r[0][0]);return this.state.offset===this.state.length&&(this.state.flush(),this.state.fill(a,r[0][0])),this.alive}dump(){return{type:"unshared capture worklet",alive:this.alive,sampleRate,offset:this.state?.offset||null,length:this.state?.length||null,blocks:this.blocks}}},x=class extends AudioWorkletProcessor{constructor(){super();this.alive=!0;this.silenceBlocks=0;this.voiceBlocks=0;this.totalBlocks=0;this.port.onmessage=this.onMessage.bind(this)}async onMessage(r){let[n,s]=r.data;switch(n){case"close":this.alive=!1;break;case"init":this.state=new g(s.workerPort,sampleRate*.02),s.workerPort.onmessage=this.onMessage.bind(this);break;case"samples":this.state?.add(s.id,s.buffer);break;case"dump":s.result.postMessage(this.dump());break}n==="close"&&(this.alive=!1)}process(r,n,s){if(this.state===void 0||n.length<1||n[0].length<2)return this.alive;let a=this.state.fill(0,n[0][0],n[0][1]);return a<u.RenderQuantumSize&&(this.totalBlocks+=1,this.state.next(),this.state.hasVoice?this.voiceBlocks+=1:this.silenceBlocks+=1,this.state.fill(a,n[0][0],n[0][1])),this.alive}dump(){return{type:"unshared playback worklet",alive:this.alive,sampleRate,id:this.state?.id||null,offset:this.state?.offset||null,length:this.state?.length||null,hasVoice:this.state?.hasVoice??!1,silenceBlocks:this.silenceBlocks,voiceBlocks:this.voiceBlocks,totalBlocks:this.totalBlocks}}},y=class{constructor(t,r){this.port=t;this.length=r;this.offset=0,this.buffer=new Float32Array(r)}fill(t,r){let n=Math.min(r.length-t,this.length-this.offset);return this.buffer.set(r.subarray(t,t+n),this.offset),this.offset+=n,t+n}flush(){d(this.port,["captureTick",{buffer:this.buffer}],[this.buffer.buffer]),this.offset=0,this.buffer=new Float32Array(this.length)}},g=class{constructor(t,r){this.port=t;this.length=r;this.cache=[];this.id=-1,this.offset=0,this.buffer=void 0,this.next()}get hasVoice(){return this.buffer!==void 0}fill(t,r,n){let s=Math.min(u.RenderQuantumSize-t,this.length-this.offset);return this.buffer!==void 0&&(r.set(this.buffer.subarray(this.offset,this.offset+s),t),n.set(this.buffer.subarray(this.offset+this.length,this.offset+this.length+s),t)),this.offset+=s,t+s}add(t,r){this.cache.push({id:t,buffer:r})}next(){for(this.id+=1;this.cache[0]?.id<this.id;)this.cache.shift();this.cache[0]?.id===this.id?(this.buffer=this.cache[0].buffer,this.cache.shift()):this.buffer=void 0,this.offset=0,d(this.port,["playbackTick",{}])}};registerProcessor("OdinCaptureProcessor",b);registerProcessor("OdinPlaybackProcessor",x);})();\n'});var K0={};kx(K0,{UnsharedCaptureWorker:()=>qx,UnsharedPlaybackWorker:()=>Gx,createCaptureWorker:()=>CF,createPlaybackWorker:()=>EF});function CF(D,x,A,F,r=C.DefaultRefreshRate){return vF.enqueue(async()=>{let[t,e]=await jx(v0,C0,D,"OdinCaptureProcessor",{channelCount:1,numberOfInputs:1,numberOfOutputs:0});return console.warn("SharedArrayBuffer is not available; creating ODIN CaptureWorker in fallback mode"),qx.create(D,x,A,r,t,e,F)})}async function EF(D,x=C.DefaultRefreshRate){if(D.sampleRate!==48e3)throw new Error("playback sample rate must be 48kHz ");let[A,F]=await jx(v0,C0,D,"OdinPlaybackProcessor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[2]});return Gx.create(D,x,A,F)}var R0,vF,qx,Gx,V0=d(()=>{"use strict";R0=require("@4players/odin-common");o();mx();M0();T0();vF=new R0.Strand;qx=class D extends tx{constructor(A,F,r,t,e){super(A,F,r,t,e);this._Activity=I;this._SpeechProbability=0;F.addEventListener("message",this._OnMessages.bind(this))}static async create(A,F,r,t,e,j,v){let{port1:E,port2:l}=new MessageChannel;return a(e,["captureInit",{sampleRate:A.sampleRate,refreshRate:t,workletPort:E}],[E]),await xx(e,"captureReady"),a(j.port,["init",{workerPort:l}],[l]),new D(j,e,F,r,v)}get activity(){return this._Activity}get speechProbability(){return this._SpeechProbability}setVolume(A){a(this.worker,["captureSetVolume",{value:A}])}_OnMessages(A){super._OnMessages(A);let[F,r]=A.data;F==="captureUpdate"&&(this._Activity={isSilent:!r.active,rmsDBFS:r.rmsDBFs},this._SpeechProbability=r.speechProbability)}},Gx=class D extends Dx{constructor(A,F,r){super(A,F,r);this.activities=new Float32Array;this.jitterStats=[]}static async create(A,F,r,t){let{port1:e,port2:j}=new MessageChannel;return a(r,["playbackInit",{workletPort:e,refreshRate:F}],[e]),await xx(r,"playbackReady"),a(t.port,["init",{workerPort:j}],[j]),new D(A,t,r)}getActivity(A){let F=this.medias.get(p(A));if(F===void 0)return;let r=this.activities.at(F.index);if(r!==void 0)return r===0?I:{isSilent:!1,rmsDBFS:r}}getJitterStats(A){let F=this.medias.get(p(A));if(F===void 0)return;let r=this.jitterStats.at(F.index);if(r!==void 0)return r}setGlobalVolume(A){a(this.worker,["playbackSetVolume",{index:"global",value:A}])}setVolume(A,F){let r=this.medias.get(p(A));r!==void 0&&a(this.worker,["playbackSetVolume",{index:r.index,value:F}])}_GetFreeIndex(){let A=super._GetFreeIndex();if(A!==void 0)return A;if(this.medias.size<C.MaxNumberOfDecoders)return this.medias.size}_OnMessages(A){super._OnMessages(A);let[F,r]=A.data;F==="playbackUpdate"&&(this.activities=r.activities,this.jitterStats=r.jitterStats)}}});var PF={};kx(PF,{SESSION_ID:()=>bx,createPlugin:()=>_F});module.exports=GA(PF);var gF=require("@4players/odin-common");o();var X=require("@4players/odin-common");o();var Bx=require("@4players/odin-common");o();var g=require("@4players/odin-common");o();var L0="getUserMedia; timeout";async function _0(D,x){try{let A=await Promise.race([navigator.mediaDevices.getUserMedia({audio:{echoCancellation:D.echoCanceller,noiseSuppression:D.noiseSuppression!=="None",autoGainControl:D.gainController,echoCancellationType:"system",deviceId:x?{exact:x}:void 0}}),(0,g.sleep)(3e4,"timeout")]);return A==="timeout"?(0,g.failure)(L0):(0,g.success)(A)}catch(A){return(0,g.failure)(`getUserMedia; ${A}`)}}async function P0(D,x,A){let F,r=!1;if(x.device?.device.kind==="track"&&x.device?.device.audioTrack)F=new MediaStream([x.device.device.audioTrack]);else{let j=x.device&&x.device.device.deviceId!=="default"?x.device.device.deviceId:void 0,v=await _0(A,j);if(v.type!=="Success"&&v.reason!==L0&&j&&(i(`unable to open requested capture device, falling back to default; ${v.reason}`),v=await _0(A),r=v.type==="Success"),v.type!=="Success")return v;F=v.value}let t=F.getAudioTracks()[0].getSettings().sampleRate,e=await D.audioContexts.acquire(t);return(0,g.success)({source:e.createMediaStreamSource(F),defaulted:r})}function Fx(D){D.getTracks().forEach(x=>{x.stop(),D.removeTrack(x)})}async function H0(D){return new Ax({deviceId:D.id,kind:"track",name:D.label??"MediaStreamTrack",audioTrack:D},!1)}async function XA(){let D=(await navigator.mediaDevices.enumerateDevices()).filter(x=>!!x.label);if(D.length===0&&(0,g.isFirefoxBrowser)()){let x=await ZA("microphone");(x==="granted"||x===!1)&&(await YA("audio"),D=(await navigator.mediaDevices.enumerateDevices()).filter(A=>!!A.label))}return D}async function hx(){let D=await XA(),x=new Map,A=[];for(let r of D){let t=r.kind;if(!(t!=="audioinput"&&t!=="audiooutput")){if(r.deviceId==="default"){x.set(t,r);continue}r.deviceId!=="communications"&&A.push(new Ax({deviceId:r.deviceId,name:r.label,kind:t},!1))}}let F=r=>new Ax({deviceId:"default",name:x.get(r)?.label??"Default",kind:r},!0);return[F("audioinput"),F("audiooutput"),...A]}async function ZA(D){try{return(await navigator.permissions.query({name:D})).state}catch{return!1}}async function YA(D){try{let x=await navigator.mediaDevices.getUserMedia({[D]:!0});return x?.getTracks().forEach(A=>{A.stop(),x.removeTrack(A)}),!0}catch{return!1}}var $x=require("@4players/odin-common");o();var W0=(0,$x.isSharedArrayBufferCapable)()&&!(0,$x.isSafariBrowser)()?Promise.resolve().then(()=>(U0(),S0)):Promise.resolve().then(()=>(V0(),K0));async function Q0(D,x,A,F){return W0.then(r=>r.createCaptureWorker(D,x,A,F,C.DefaultRefreshRate))}async function z0(D){return W0.then(x=>x.createPlaybackWorker(D,C.DefaultRefreshRate))}var fF=250,nF=1e3,N=class{constructor(x,A){this.controller=x;this._Medias=new Map;this._Vad={...Bx.VAD_DEFAULTS};this._Apm={...Bx.APM_DEFAULTS};this._Volume=1;this._Queue=Promise.resolve();this.#r=0;this._DeviceCb=()=>{clearTimeout(this.#F),this.#F=setTimeout(()=>{this._enqueue(async()=>{let x=this._DeviceParameters?.device;!x||x.device.kind==="track"||(x.device.deviceId==="default"?await this._followDefaultDevice():await this._detectSelectedDeviceRemoved(x.device.deviceId))}).catch(x=>i("device-change handler failed",x))},fF)};A.apm&&this.setApm(A.apm).catch(console.error),A.vad&&this.setVad(A.vad),typeof A.volume<"u"&&this.setVolume(A.volume).catch(console.error),this.uid=(0,Bx.generateUUID)(),this.#x=A.customType,this.#A=A.ref}#x;#A;#F;#r;async _followDefaultDevice(){let x=this._DeviceParameters;this._Volume==="muted"||!this._Capture||!x||Date.now()-this.#r<nF||(n("default capture device may have moved, re-opening capture"),await this._setDeviceImpl(x))}async _detectSelectedDeviceRemoved(x){(await hx()).some(t=>t.device.deviceId===x)||this._Capture?.source.mediaStream?.getAudioTracks()[0]?.readyState==="live"||(this._DeviceParameters?.onStatusChanged?.("stopped"),navigator.mediaDevices.removeEventListener("devicechange",this._DeviceCb),this._DeviceParameters=void 0,await this._closeImpl())}_enqueue(x){let A=this._Queue.then(x,x);return this._Queue=A.catch(()=>{}),A}get vad(){return this._Vad}get apm(){return this._Apm}get volume(){return this._Volume}get activity(){return this._Capture?.worker.activity??I}get speechProbability(){return this._Capture?.worker.speechProbability??0}get deviceId(){return this._DeviceParameters?.device?.device.deviceId}async start(x,A){let F=this._Medias.get(A.connectionId);F===void 0&&this._Medias.set(A.connectionId,F=new Set),f(`starting audio capture media ${A.mediaId} on connection ${A.connectionId}`),!F.has(A.mediaId)&&(F.add(A.mediaId),x.mainConnection?.id===A.connectionId&&await x.request("StartMedia",{media_id:A.mediaId,properties:{kind:"audio",uid:this.uid,ref:this.#A,customType:this.#x}}).catch(r=>u(`StartMedia got rejected; ${r}`)),this._UpdateMedias())}async stop(x,A){let F=this._Medias.get(A.connectionId);f(`stopping audio capture media ${A.mediaId} on connection ${A.connectionId}`),F?.delete(A.mediaId)&&(x.mainConnection?.id===A.connectionId&&await x.request("StopMedia",{media_id:A.mediaId}).catch(r=>u(`StopMedia got rejected; ${r}`)),this._UpdateMedias())}setVad(x){n("updating vad config",x),this._Vad=x,this._Capture&&this._Capture.worker.setVad(x)}async setApm(x){await this._enqueue(()=>this._setApmImpl(x))}async _setApmImpl(x){n("updating apm config",x),this._Apm=x,this._DeviceParameters&&await this._setDeviceImpl(this._DeviceParameters)}async setDevice(x){await this._enqueue(()=>this._setDeviceImpl(x))}async _setDeviceImpl(x){n("updating capture device parameters",x);let A=this._DeviceParameters;if(this._DeviceParameters=x,this._Volume==="muted")return;let F;try{let r=await P0(this.controller,x,{...this._Apm,echoCanceller:this._Monitor?!1:this._Apm.echoCanceller});if(r.type!=="Success"){u(`unable to open capture device; ${r.reason}`),this._DeviceParameters=A;return}F=r.value.source.context,navigator.mediaDevices.addEventListener("devicechange",this._DeviceCb);let t=this._Capture?.source.context;if(this._Capture!==void 0){Fx(this._Capture.source.mediaStream);try{this._Capture.source.disconnect(this._Capture.worker.worklet)}catch(e){i("failed to disconnect previous capture source",e)}}this._Capture===void 0||this._Capture.worker.worklet.context!==r.value.source.context?(this._Capture?.worker.close(),this._Capture={worker:await Q0(r.value.source.context,this.controller.sink,this.controller.receiveMonitoredPacket.bind(this.controller),new WeakRef(this)),source:r.value.source},await this._UpdateMedias(),this._Capture.worker.setVolume(this._Volume),this.setVad(this.vad)):this._Capture.source=r.value.source,F=void 0,this._Capture.source.connect(this._Capture.worker.worklet),t!==void 0&&await this.controller.audioContexts.release(t),this.#r=Date.now(),x.onStatusChanged?.(r.value.defaulted?"defaulted":"started")}catch(r){throw F!==void 0&&await this.controller.audioContexts.release(F),new Error(`Error in setDevice(); ${r}`,{cause:r})}}async setVolume(x){await this._enqueue(()=>this._setVolumeImpl(x))}async _setVolumeImpl(x){n(`updating capture volume to ${x}`),this._Volume=x,x==="muted"?await this._closeImpl():(!this._Capture&&this._DeviceParameters&&await this._setDeviceImpl(this._DeviceParameters),this._Capture?.worker.setVolume(x))}async close(){await this._enqueue(()=>this._closeImpl())}async _closeImpl(){if(n("closing audio capture"),clearTimeout(this.#F),this.#F=void 0,this._Capture!==void 0){this._Capture.worker.close(),Fx(this._Capture.source.mediaStream);try{this._Capture.source.disconnect(this._Capture.worker.worklet)}catch(x){i("failed to disconnect audio node",x)}await this.controller.audioContexts.release(this._Capture.source.context)}navigator.mediaDevices.removeEventListener("devicechange",this._DeviceCb),this._Capture=void 0}async dump(){let x=[];for(let[A,F]of this._Medias)x.push(`${A} => ${Array.from(F.values()).join(",")}`);return{uid:this.uid,ref:this.#A??null,customType:this.#x??null,worker:await this._Capture?.worker.dump()??null,vad:this._Vad,apm:this._Apm,volume:this._Volume,medias:x}}async _UpdateMedias(){if(this._Capture!==void 0){let x=Array.from(this._Medias).map(([A,F])=>({id:A,mediaIds:Array.from(F)}));this._Capture.worker.setMedias(x)}}async startLoopback(){this._Monitor===void 0&&(n("starting audio capture loopback"),this.setApm(this._Apm),this._Monitor=await this.controller.createAudioPlayback({uid:"loopback"}),this._Monitor.start({connectionId:0,mediaId:0}),this._Medias.set(0,new Set([0])),await this._UpdateMedias())}async stopLoopback(){this._Monitor!==void 0&&(n("stopping audio capture loopback"),this._Monitor.close(),this._Monitor=void 0,this.setApm(this._Apm),this._Medias.delete(0),await this._UpdateMedias())}};var ix=require("@4players/odin-common");o();var $=class{constructor(x,A){this.controller=x;this.parameters=A;this.uid=(0,ix.generateUUID)()}#x;#A=new Map;#F;get customType(){return this.parameters?.customType}get mediaStream(){return this.#x}get audioCapture(){return this.#F}get volume(){return(0,ix.assert)(this.audioCapture,"getting the volume failed, this video has no Audio"),this.audioCapture.volume}async setVolume(x){(0,ix.assert)(this.audioCapture,"setVolume() failed, this video has no Audio"),await this.audioCapture.setVolume(x)}get vad(){return(0,ix.assert)(this.audioCapture,"getting the vad config failed, this video has no Audio"),this.audioCapture.vad}setVad(x){(0,ix.assert)(this.audioCapture,"setVad() failed, this video has no Audio"),this.audioCapture.setVad(x)}async setDevice(x,A={voiceActivity:void 0,volumeGate:void 0}){if(this.#x)throw new Error("This VideoCapture already has a MediaStream.");if(!x.getVideoTracks()[0])throw new Error("Error when calling setDevice(), MediaStream does not contain a VideoStreamTrack!");if(this.#x=x,x.getAudioTracks()[0]){let r={device:await H0(x.getAudioTracks()[0]),vad:A,ref:this.uid};this.#F=await this.controller.createAudioCapture(r)}}async start(x,A){let F=this.#A.get(A.connectionId);if(F===void 0&&this.#A.set(A.connectionId,F=new Set),!F.has(A.mediaId)&&(F.add(A.mediaId),x.mainConnection?.id===A.connectionId)){let r={kind:"video",codec:this.parameters?.codec??C.DefaultVideoCodec,ref:this.#F?.uid,uid:this.uid};this.parameters?.customType&&(r.customType=this.parameters.customType),await x.request("StartMedia",{media_id:A.mediaId,properties:r}).catch(t=>u(`StartMedia got rejected; ${t}`))}}async stop(x,A){this.#x&&Fx(this.#x),this.#A.get(A.connectionId)?.delete(A.mediaId)&&x.mainConnection?.id===A.connectionId&&await x.request("StopMedia",{media_id:A.mediaId}).catch(r=>u(`StopMedia got rejected; ${r}`))}async dump(){let x=[];for(let[A,F]of this.#A)x.push(`${A} => ${Array.from(F.values()).join(",")}`);return{uid:this.uid,ref:this.#F?.uid??null,customType:this.customType??null,tracks:this.#x?.getVideoTracks().map(A=>({id:A.id,kind:A.kind,label:A.label,ready:A.readyState,muted:A.muted,settings:{...A.getSettings()}}))??[],volume:this.#F?.volume??0,medias:x}}close(){this.#x&&Fx(this.#x),this.audioCapture?.close(),this.#F=void 0}};var Wr=require("@4players/odin-common");o();var _=class{constructor(x,A,F){this.controller=x;this.uid=A;this.customType=F}get volume(){return this.controller.playbackGetVolume(this.uid)}get activity(){return this.controller.playbackGetActivity(this.uid)}get jitterStats(){return this.controller.playbackGetJitterStats(this.uid)}start(x){f(`starting audio playback media ${x.mediaId} on connection ${x.connectionId}`),this.controller.playbackStart(this.uid,x)}stop(x){f(`stopping audio playback media ${x.mediaId} on connection ${x.connectionId}`),this.controller.playbackStop(this.uid,x)}setVolume(x){n(`updating audio playback media '${this.uid}' volume to ${x}`),this.controller.playbackSetVolume(this.uid,x)}close(){n(`closing audio playback media '${this.uid}'`),this.controller.closePlayback(this.uid)}};function sF(D,x){let A=D.audioContext;if(typeof A.setSinkId=="function"){D.connectOutput(A.destination);let F,r=()=>{if(A.state==="running"&&F!==void 0){let t=F;F=void 0,A.setSinkId(t).catch(e=>i("failed to apply deferred sinkId",e))}};return A.addEventListener("statechange",r),{async setSinkId(t){if(A.state!=="running"){F=t;return}await A.setSinkId(t)},dispose(){A.removeEventListener("statechange",r)}}}if(x&&typeof document<"u"&&typeof HTMLAudioElement<"u"&&typeof HTMLAudioElement.prototype.setSinkId=="function"){let F=A.createMediaStreamDestination();D.connectOutput(F);let r=new Audio;r.srcObject=F.stream,r.muted=!1,r.volume=1;let t=!1,e=!1,j={once:!0,passive:!0,capture:!0},v=()=>{e=!1,k()},E=()=>{e||t||(e=!0,document.addEventListener("pointerdown",v,j),document.addEventListener("keydown",v,j))},l=()=>{e&&(e=!1,document.removeEventListener("pointerdown",v,!0),document.removeEventListener("keydown",v,!0))},k=()=>{t||r.play().catch(sx=>{t||(sx instanceof DOMException&&sx.name==="NotAllowedError"?E():i("failed to start playback audio element",sx))})},ux=()=>{A.state==="running"&&r.paused&&k()};return A.addEventListener("statechange",ux),k(),{async setSinkId(sx){await r.setSinkId(sx)},dispose(){t=!0,l(),A.removeEventListener("statechange",ux),r.pause(),r.srcObject=null,r.removeAttribute("src");try{r.load()}catch{}F.disconnect()}}}return D.connectOutput(A.destination),{async setSinkId(){},dispose(){}}}var yx=class{constructor(x){this.audioContextFactory=x;this.entries=[];this._acquireStrand=new X.Strand}acquire(x){return this._acquireStrand.enqueue(async()=>{for(let r of this.entries)if(r.sampleRate===x||r.sampleRate===void 0&&r.audioContext.sampleRate===x)return r.references+=1,r.audioContext;let A=await this.audioContextFactory(x),F=this.entries.find(r=>r.audioContext.sampleRate===A.sampleRate);return F?(F.references+=1,A.close().catch(()=>{}),F.audioContext):(this.entries.push({sampleRate:x,audioContext:A,references:1}),A)})}async release(x){let A=this.entries.findIndex(F=>F.audioContext===x);if(!(A<0)&&(this.entries[A].references-=1,this.entries[A].references<=0)){let F=this.entries[A].audioContext;this.entries.splice(A,1),await F.close()}}close(){for(let x of this.entries.splice(0))x.audioContext.close().catch(()=>{})}},Ix=class D{constructor(x,A,F=!1){this.audioContexts=x;this.sink=A;this.enableHTMLAudioElementFallback=F;this.audioCaptures=[];this.videoCaptures=[];this.globalVolume=[1,1];this.playbacks=new Map;this.setPlaybackStrand=new X.Strand}async create(x,A){return new D(x,A)}receivePacket(x,A){this.playbackWorker?.receivePacket(x,A)}receiveMonitoredPacket(x,A){let F=A.slice();this.receivePacket(x,F)}async createAudioPlayback(x){let A=this.playbacks.get(x.uid),F=x.volume;if(A===void 0){F=F??[1,1];let r=new _(this,x.uid,x.customType);A={id:void 0,volume:F,playback:r},this.playbacks.set(x.uid,A)}return F!==void 0&&A.playback.setVolume(F),A.playback}async createAudioCapture(x){let A=new N(this,x);return await A.setDevice(x),this.audioCaptures.push(new WeakRef(A)),A}async createVideoCapture(x,A){let F=new $(this,A);return await F.setDevice(x),this.videoCaptures.push(new WeakRef(F)),F}playbackSetDevice(x){return this.setPlaybackStrand.enqueue(async()=>{let A=x?.device.deviceId??"";if(A==="default"&&(A=""),this.playbackWorker===void 0){let F=await this.audioContexts.acquire(48e3);this.playbackWorker=await z0(F),this.playbackSink=sF(this.playbackWorker,this.enableHTMLAudioElementFallback),this.playbackWorker.setGlobalVolume(this.globalVolume);for(let[,r]of this.playbacks)r.id!==void 0&&this.playbackWorker.addMedias(r.id.connectionId,[r.id.mediaId],r.volume)}if(x&&this.playbackSink!==void 0)try{await this.playbackSink.setSinkId(A)}catch(F){i("failed to set playback sink",F)}})}playbackSetGlobalVolume(x){this.globalVolume=x,this.playbackWorker?.setGlobalVolume(this.globalVolume)}playbackStart(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.id!==void 0&&this.playbackStop(x,F.id),F.id=A,this.playbackWorker?.addMedias(A.connectionId,[A.mediaId],F.volume))}playbackStop(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.id!==A&&i(`playback media ${A.mediaId} on connection ${A.connectionId} is out of sync`,F.id,A),F.id=void 0,this.playbackWorker?.removeMedias(A.connectionId,[A.mediaId]))}playbackGetActivity(x){let A=this.playbacks.get(x);return A?.id===void 0?I:this.playbackWorker?.getActivity(A.id)??I}playbackGetJitterStats(x){let A=this.playbacks.get(x);return A?.id===void 0?X.JITTER_STATS_INITIAL:this.playbackWorker?.getJitterStats(A.id)??X.JITTER_STATS_INITIAL}playbackSetVolume(x,A){let F=this.playbacks.get(x);F!==void 0&&(F.volume=A,F.id!==void 0&&this.playbackWorker?.setVolume(F.id,F.volume))}playbackGetVolume(x){return this.playbacks.get(x)?.volume??[1,1]}closePlayback(x){let A=this.playbacks.get(x);A!==void 0&&(A.id!==void 0&&this.playbackStop(x,A.id),this.playbacks.delete(x))}close(){this.playbackSink?.dispose(),this.playbackSink=void 0,this.playbackWorker?.close(),this.audioContexts.close()}async dump(){let x=[];for(let r of this.audioCaptures){let t=r.deref();t!==void 0&&x.push(await t.dump())}let A=[];for(let r of this.videoCaptures){let t=r.deref();t!==void 0&&A.push(await t.dump())}let F=[];for(let[r,t]of this.playbacks)F.push({uid:r,id:t.id||null,volume:t.volume});return{globalVolume:this.globalVolume,playbackWorker:await this.playbackWorker?.dump()||null,audioCaptures:x,videoCaptures:A,playbacks:F}}},Ax=class{constructor(x,A=!1){this.device=x;this.isDefault=A}get type(){switch(this.device.kind){case"audioinput":return"AudioCapture";case"track":return"AudioCapture";case"audiooutput":return"AudioPlayback";default:(0,X.assert)(!1,"not supported device")}}get id(){return this.device.deviceId}get name(){return this.device.name}};var ax=require("@4players/odin-common"),rA=require("@msgpack/msgpack");o();var tt=require("@4players/odin-common");o();var J=require("@4players/odin-common"),K=require("@4players/odin-common/api");o();var R=require("@4players/odin-common"),Z=require("@4players/odin-common/api"),gx=require("@msgpack/msgpack");o();var T=class{constructor(x){this.stream=x;this._SendQueue=[];this._RecvQueue=[];this._EventQueue=[];this._Requests=new Map;this._Close=new AbortController;this._NextId=1;x instanceof WebSocket?(x.addEventListener("open",this._OnWebSocketOpen.bind(this)),x.addEventListener("close",this.close.bind(this)),x.addEventListener("message",A=>this._OnRpcMessage(A.data)),x.binaryType="arraybuffer"):(bF(x.readable.getReader(),this._OnRpcMessage.bind(this)).finally(this.close.bind(this)),this._Writer=x.writable.getWriter()),this._Close.signal.addEventListener("abort",this._Cleanup.bind(this),{once:!0})}get closed(){return this._Close.signal.aborted}get closeSignal(){return this._Close.signal}async request(x,A,F){if(this.closed)return Promise.resolve("closed");let r=this._NextId,t=F===void 0?void 0:setTimeout(()=>this._TimeoutRequest(r),F);return this._Send([0,r,x,A]),new Promise(e=>{this._Requests.set(r,{accept:e,timeoutId:t}),this._NextId+=1})}notify(x,A){this.closed||this._Send([2,x,A])}recv(){if(this.closed)return Promise.resolve("closed");let x=this._EventQueue.shift();return x!==void 0?Promise.resolve(x):new Promise(A=>this._RecvQueue.push(A))}close(){this._Close.abort()}_TimeoutRequest(x){let A=this._Requests.get(x);A!==void 0&&(this._Requests.delete(x),clearTimeout(A.timeoutId),A.accept("timeout"))}_Send(x){let A;x instanceof Uint8Array?A=x:A=new Uint8Array((0,gx.encode)(x,{ignoreUndefined:!0,forceFloat32:!0})),this.stream instanceof WebSocket?this.stream.send(A):this._Writer.write(A).catch(()=>{})}_OnWebSocketOpen(x){for(let A of this._SendQueue)this._Send(A);this._SendQueue.length=0}_OnRpcMessage(x){let A=iF(x);if(A.type!=="Success"){this.close();return}switch(A.value[0]){case 0:this._Send([1,A.value[1],"not supported",null]);break;case 1:this._OnResponse(A.value[1],A.value[2],A.value[3]);break;case 2:this._OnEvent(A.value[1],A.value[2]);break}}_OnResponse(x,A,F){let r=this._Requests.get(x);r!==void 0&&(clearTimeout(r.timeoutId),r.accept(A===null?(0,R.success)(F):(0,R.failure)(A)))}_OnEvent(x,A){let F=this._RecvQueue.shift();F!==void 0?F({name:x,properties:A}):this._EventQueue.push({name:x,properties:A})}_Cleanup(){for(let x of this._Requests.values())clearTimeout(x.timeoutId),x.accept("closed");this._Requests.clear();for(let x of this._RecvQueue)x("closed");this._RecvQueue.length=0,this._SendQueue.length=0,this.stream instanceof WebSocket?this.stream.close():this._Writer?.close().catch(()=>{})}},Y=class{constructor(x,A,F){this.rpc=x;this._Commands=A;this._Events=F}get closed(){return this.rpc.closed}get closeSignal(){return this.rpc.closeSignal}async request(x,A,F){A=(0,Z.parseRequest)(x,A,this._Commands);let r=await this.rpc.request(x,A,F);if(r==="closed"||r==="timeout"||r.type==="Failure")return r;let t=(0,Z.parseResponse)(x,r.value,this._Commands);return t!==void 0?(0,R.success)(t):(0,R.failure)("response schema failed validation")}notify(x,A){A=(0,Z.parseRequest)(x,A,this._Commands),this.rpc.notify(x,A)}async recv(){let x=await this.rpc.recv();if(x==="closed")return x;let A=E0(this._Events,x);return A!==void 0?A:(X0(this._Events,x.name)?(u(`schema validation for ${x.name} failed; closing connection`),this.rpc.close()):i(`dropping unknown event ${x.name}`),"closed")}close(){this.rpc.close()}};function iF(D){try{return(0,R.success)(Z.MessagePackRpcSchema.parse((0,gx.decode)(new Uint8Array(D))))}catch(x){return(0,R.failure)(String(x))}}function E0(D,x){if(!X0(D,x.name))return;let A=D[x.name].safeParse(x.properties);if(A.success)return{name:x.name,properties:A.data}}function X0(D,x){return x in D}async function bF(D,x){let A=new Uint8Array;for(;;){let F=q0(A,0);if(F===B){D.cancel("protocol violation");break}if(F!==q&&F<=A.length){x(A.subarray(0,F)),A=A.subarray(F);continue}let r;try{r=await D.read()}catch{break}if(r.done)break;A=oF(A,r.value)}A.length>0&&i("unprocessed bytes left in rpc stream",A)}function oF(D,x){if(D.length===0)return x;if(x.length===0)return D;let A=new Uint8Array(D.length+x.length);return A.set(D,0),A.set(x,D.length),A}var w=require("@4players/odin-common"),Z0=require("@4players/odin-common/api");o();var y=class D{constructor(x,A){this.text=x;this.claims=A;if(A.ups!==void 0){let F=D.parse(A.ups);F.type==="Success"?this._Upstream=F.value:u(`upstream in token can not be parsed; ${F.reason}`)}}static parse(x){let A=x.split(".");if(A.length!==3)return(0,w.failure)("expected three segments");let F=(0,w.fromBase64Url)(A[1]);if(F.type==="Failure")return(0,w.failure)(`invalid token; ${F.reason}`);let r;try{r=JSON.parse(F.value)}catch(e){return(0,w.failure)(`invalid token; ${e}`)}let t=Z0.TokenClaimsSchema.safeParse(r);return t.success===!1?(0,w.failure)(`invalid token; ${t.error}`):(0,w.success)(new D(x,t.data))}get timeLeft(){return this.claims.exp===void 0?1/0:this.claims.exp*1e3-Date.now()}get upstream(){return this._Upstream}get defaultRoomId(){return Array.isArray(this.claims.rid)?this.claims.rid.length===1?this.claims.rid[0]:void 0:this.claims.rid}hasAudience(x){return this.claims.aud===void 0&&x==="gateway"?!0:Array.isArray(this.claims.aud)?this.claims.aud.includes(x):this.claims.aud===x}toString(){return this.text}};var vx=require("@4players/odin-common");o();function Y0(D){typeof globalThis.rtcDataChannels>"u"&&(globalThis.rtcDataChannels=[]),Array.isArray(globalThis.rtcDataChannels)&&globalThis.rtcDataChannels.length<=100&&globalThis.rtcDataChannels.push(D)}function xA(D){let x=globalThis.rtcDataChannels?.indexOf(D);x!==void 0&&x>=0&&globalThis.rtcDataChannels.splice(x,1),D.readyState!=="closed"&&D.close()}function _x(D){typeof globalThis.rtcPeerConnections>"u"&&(globalThis.rtcPeerConnections=[]),Array.isArray(globalThis.rtcPeerConnections)&&globalThis.rtcPeerConnections.length<=100&&globalThis.rtcPeerConnections.push(D)}function Lx(D){let x=globalThis.rtcPeerConnections?.indexOf(D);x!==void 0&&x>=0&&globalThis.rtcPeerConnections.splice(x,1),D.connectionState!=="closed"&&D.close()}var Cx=class{constructor(x,A,F){this._localVideos=new Map;this._remoteVideos=new Map;this._freeLocalVideoTransceivers=[];this._closed=!1;this._negotiationRequested=!1;this._negotiationRunning=!1;this._negotiationCounter=0;this._pendingRemoteCandidates=[];this._WebRtcStatsSnapshot=null;this._peerConnection=x,this._signaling=A,this._answerTimeout=F?.answerTimeout??C.WebRtcAnswerTimeout,this._maxNegotiationAttempts=F?.maxNegotiationAttempts??C.WebRtcMaxNegotiationAttempts,this._peerConnection.ontrack=this._onTrack.bind(this),this._peerConnection.onconnectionstatechange=()=>this._onStatusChanged(),this._peerConnection.onicecandidate=r=>{(r.candidate?this._signaling.sendIceCandidate(r.candidate):this._signaling.sendIceComplete()).catch(e=>{i("failed to send local ice candidate",e)})},this._WebRtcStatsInterval=setInterval(()=>{this._snapshotStats()},C.WebRtcStatsSnapshotInterval)}requestNegotiation(){this._closed||(this._negotiationRequested=!0,!this._negotiationRunning&&(this._negotiationRunning=!0,setTimeout(async()=>{let x=0;for(;this._negotiationRequested&&!this._closed;){this._negotiationRequested=!1;try{await this._negotiate(),x=0}catch(A){if(this._closed)break;if(x+=1,u(`negotiation failed during sdp offer/answer exchange (attempt ${x})`,A),x<this._maxNegotiationAttempts)this._negotiationRequested=!0;else{this._negotiationRunning=!1,this._signaling.closeConnection().catch(()=>{});return}}}this._negotiationRunning=!1})))}async startLocalVideo(x,A,F){if(this._localVideos.has(x))return;f(`starting local video for media ${x}`);let r=this._freeLocalVideoTransceivers.pop();if(r?(await r.sender.replaceTrack(A),r.direction="sendrecv"):r=this._peerConnection.addTransceiver(A),F){let j=r.sender.getParameters(),{maxBitrate:v,maxFramerate:E,scaleResolutionDownBy:l}=F,k={...v!==void 0&&{maxBitrate:v},...E!==void 0&&{maxFramerate:E},...l!==void 0&&{scaleResolutionDownBy:l}};if(j.encodings.length===0)j.encodings.push(k);else for(let ux of j.encodings)Object.assign(ux,k);F.degradationPreference&&(j.degradationPreference=F.degradationPreference),await r.sender.setParameters(j)}let e=new vx.VideoCodec(F?.codec??C.DefaultVideoCodec).isSupported();e&&r.setCodecPreferences([e]),this._localVideos.set(x,{transceiver:r}),this.requestNegotiation()}stopLocalVideo(x){let A=this._localVideos.get(x);A&&(f(`stopping local video for media ${x}`),this._localVideos.delete(x),A.transceiver.sender.track&&(A.transceiver.sender.track.enabled=!1),A.transceiver.direction="inactive",A.transceiver.sender.replaceTrack(null).catch(()=>{}),this._freeLocalVideoTransceivers.push(A.transceiver),this.requestNegotiation())}startRemoteVideo(x){let A=this._remoteVideos.get(x);if(A)return A.track;f(`starting remote video for media ${x}`);let F=this._peerConnection.addTransceiver("video",{direction:"recvonly"}),r,t=new Promise((e,j)=>{r={resolve:e,reject:j}});return t.catch(()=>{}),(0,vx.assert)(r!==void 0,"promise executor must run synchronously"),this._remoteVideos.set(x,{state:"Requested",transceiver:F,promise:r,track:t}),this.requestNegotiation(),t}stopRemoteVideo(x){let A=this._remoteVideos.get(x);if(A){f(`stopping remote video for media ${x}`),this._remoteVideos.delete(x),A.state!=="Active"&&A.promise.reject(new Error("video stopped"));try{A.transceiver.direction="inactive"}catch{}this.requestNegotiation()}}async handleWebRtcUpdate(x){try{switch(x.kind){case"Sdp":await this._updateRemoteSdp(x.type==="Answer"?"answer":"offer",x.sdp,x.media_map,x.negotiation_id);break;case"Trickle":this._addIceCandidate({candidate:x.candidate,sdpMid:x.spd_mid??void 0,sdpMLineIndex:x.spd_mline_index??void 0,usernameFragment:x.username_fragment??void 0});break;case"TrickleFinished":this._addIceCandidate(void 0);break}}catch(A){u("failed to handle webrtc update",A,x)}}startup(){this._peerConnection.connectionState==="new"&&this.requestNegotiation()}cleanup(){this._closed=!0;for(let[,x]of this._remoteVideos)x.state!=="Active"&&x.promise.reject(new Error("connection closed"));this._pendingAnswer?.reject(new Error("connection closed")),this._pendingRemoteCandidates.length=0,clearTimeout(this._WebRtcIceTimeout),clearTimeout(this._WebRtcTimeout),clearInterval(this._WebRtcStatsInterval),this._localVideos.clear(),this._remoteVideos.clear(),this._freeLocalVideoTransceivers.length=0}get stats(){return this._WebRtcStatsSnapshot}get peerConnection(){return this._peerConnection}get localVideos(){return this._localVideos}get remoteVideos(){return this._remoteVideos}get isConnected(){return this._peerConnection.connectionState==="connected"}get isNegotiating(){return this._negotiationRunning}async _snapshotStats(){try{let x=await this._peerConnection.getStats(),A={},F={bytesSent:0,bytesReceived:0,packetsSent:0,packetsReceived:0,rtt:0};x.forEach(r=>{let{type:t,...e}=r;t!=="certificate"&&(t==="candidate-pair"&&r.nominated&&(F.bytesSent+=r.bytesSent??0,F.bytesReceived+=r.bytesReceived??0,F.packetsSent+=r.packetsSent??0,F.packetsReceived+=r.packetsReceived??0,F.rtt=r.currentRoundTripTime??0),A[t]||(A[t]=[]),A[t].push(e))}),this._WebRtcStatsSnapshot={timestamp:Date.now(),status:this._peerConnection.connectionState,stats:F,report:A}}catch{}}_addIceCandidate(x){if(x&&(x.sdpMid===void 0&&x.sdpMLineIndex===void 0&&(x={...x,sdpMid:"0"}),n(`adding new ice ${x.candidate}`,x)),this._peerConnection.remoteDescription===null){this._pendingRemoteCandidates.push(x);return}this._applyIceCandidate(x)}_applyIceCandidate(x){this._peerConnection.addIceCandidate(x).catch(A=>{i("failed to add remote ice candidate",A,x)})}_flushPendingIceCandidates(){let x=this._pendingRemoteCandidates.splice(0);for(let A of x)this._applyIceCandidate(A)}async _negotiate(){let x=++this._negotiationCounter,A=await this._peerConnection.createOffer();(0,vx.assert)(A.type==="offer"&&A.sdp,"generated broken payload"),await this._peerConnection.setLocalDescription(A);let F=[];for(let[t,{transceiver:e}]of this._localVideos)e.mid&&F.push([t,e.mid]);for(let[t,e]of this._remoteVideos)e.state!=="Active"&&e.transceiver.mid&&F.push([t,e.transceiver.mid]);let r=new Promise((t,e)=>{this._pendingAnswer={negotiationId:x,resolve:t,reject:e}});try{await this._signaling.sendOffer(A.sdp,F,x),await aF(r,this._answerTimeout,`timed out waiting for answer to offer ${x}`)}finally{this._pendingAnswer=void 0}}async _updateRemoteSdp(x,A,F,r){if(x==="offer"){i("ignoring unexpected sdp offer from server");return}let t=this._pendingAnswer;if(t===void 0){i("ignoring sdp answer without pending negotiation");return}if(r!==void 0&&r!==t.negotiationId){i(`ignoring stale sdp answer for negotiation ${r}; current is ${t.negotiationId}`);return}if(this._peerConnection.signalingState!=="have-local-offer"){i(`ignoring sdp answer in signaling state ${this._peerConnection.signalingState}`);return}for(let[e,j]of F){let v=this._remoteVideos.get(e);v?.state==="Requested"&&(this._remoteVideos.set(e,{state:"Mapped",transceiver:v.transceiver,mid:j,promise:v.promise,track:v.track}),n(`updated remote video list with media ${e}`,v,this._remoteVideos))}try{await this._peerConnection.setRemoteDescription({type:x,sdp:A})}catch(e){t.reject(e);return}this._flushPendingIceCandidates(),t.resolve()}async _onStatusChanged(){switch(n(`peer connection state changed to ${this._peerConnection.connectionState}`),this._peerConnection.connectionState){case"closed":break;case"connected":clearTimeout(this._WebRtcIceTimeout),this._WebRtcIceTimeout=void 0,clearTimeout(this._WebRtcTimeout),this._WebRtcTimeout=void 0;break;case"failed":this._peerConnection.restartIce(),this.requestNegotiation();case"disconnected":C.MainConnectionPingInterval!==void 0&&await this._signaling.checkConnection();default:this._WebRtcIceTimeout===void 0&&(this._WebRtcIceTimeout=setTimeout(()=>{n("ice connection timeout was reached"),this._peerConnection.restartIce(),this._WebRtcIceTimeout=void 0},C.WebRtcIceTimeout)),this._WebRtcTimeout===void 0&&(this._WebRtcTimeout=setTimeout(async()=>{n("peer connection timeout was reached"),await this._signaling.closeConnection()},C.WebRtcTimeout));break}}_onTrack(x){let A=Array.from(this._remoteVideos).find(([,t])=>t.state==="Mapped"&&t.mid===x.transceiver.mid);if(!A){i(`unexpected track with mid: ${x.transceiver.mid}`);return}let[F,r]=A;(0,vx.assert)(r.state==="Mapped","expected video state to be Mapped"),this._remoteVideos.set(F,{state:"Active",transceiver:x.transceiver,track:r.track}),n(`updated local video list with media ${F}`,A,x.transceiver,this._localVideos),x.track.onended=()=>{n(`video track with mid ${x.transceiver.mid} ended`,A)},r.promise.resolve(x.track)}};function aF(D,x,A){return new Promise((F,r)=>{let t=setTimeout(()=>r(new Error(A)),x);D.then(e=>{clearTimeout(t),F(e)},e=>{clearTimeout(t),r(e)})})}var Px=class D{constructor(x,A,F,r,t,e,j){this.id=x;this.address=A;this.connection=r;this.datagramWritable=t;this.rpc=e;this.closeController=j;this._ConnectionStats={...J.CONNECTION_STATS_INITIAL};this._WebRtcUpdatesRunning=!1;this._WebRtcSessionFlight=new Q;this._PingFlight=new Q;this.status=0;this._ClosePromise=(async()=>{try{await this.connection.closed}catch{}return"closed"})(),C.MainConnectionPingInterval!==void 0&&(this._PingIntervalId=setInterval(async()=>{this.connectionStats.rtt=await this.ping(C.HealthCheckTimeout)},C.MainConnectionPingInterval)),j.signal.addEventListener("abort",()=>this._CleanUp(),{once:!0}),this.datagramWriter=t.getWriter(),this.connection.closed.then(()=>{this.status=2}).catch(()=>{}).finally(()=>{this.closeController.abort("transport closed")}),this.connection.ready.then(()=>{this.status=1}).catch(()=>{}),this.readDatagrams(this.connection,this.id,(v,E)=>{this._ConnectionStats.packetsReceived+=1,F(v,E)})}static async create(x,A,F,r){try{let t=new URL(`https://${A}?version=${$0}&uid=${bx}`),e=new AbortController;r.addEventListener("abort",()=>e.abort(),{once:!0});let j=new WebTransport(t);e.signal.addEventListener("abort",()=>{try{j.close()}catch{}},{once:!0}),await j.ready;let v=j.datagrams,E=v?.createWritable?.()??v?.writable;if(!E)return e.abort(),(0,J.failure)(`connecting to ${A} failed because WebTransport datagrams are not supported by this browser`);let l=await j.createBidirectionalStream(),k=new Y(new T(l),K.MainCommandsRpc,K.MainNotificationsRpc);return e.signal.addEventListener("abort",()=>k.close(),{once:!0}),k.notify("Hello",{stream:"main"}),(0,J.success)(new D(x,A,F,j,E,k,e))}catch(t){return(0,J.failure)(`connecting to ${A} failed with ${t}`)}}get connectionStats(){return this._ConnectionStats}get transport(){return"H3"}get closePromise(){return this._ClosePromise}get closeSignal(){return this.closeController.signal}get closed(){return this.closeSignal.aborted}waitForConnected(){return Promise.race([this.connection.ready,this.connection.closed.then(()=>{throw new Error("connection closed")})])}close(){f(`closing connection to '${this.address}' with id ${this.id}`),this.closeController.abort("request")}async joinRoom(x,A,F,r){try{if(this.closed)return"closed";let t=await this.connection.createBidirectionalStream().catch(()=>"closed");if(t==="closed")return"closed";let e=new Y(new T(t),K.RoomCommandsRpc,K.RoomNotificationsRpc),j=await e.request("Hello",{stream:"room",token:String(x),room_id:A,user_data:F,position:r});return j==="closed"||j.type==="Failure"?j:(0,J.success)(e.rpc)}catch(t){return(0,J.failure)(`JoinRoom failed; ${t}`)}}async getReconnectToken(x){let A=await this._Request("RequestReconnectToken",{peer_id:x});return A.type==="Failure"?A:y.parse(A.value)}async getRtcStats(){return this._PeerConnection?.getStats()}async healthCheck(){let x=await this._RequestPing(C.HealthCheckTimeout);return x||this.close(),x}async ping(x=3e4){let A=Date.now();return await this._RequestPing(x)?Date.now()-A:0}sendDatagram(x){if(!this.closed)try{this.datagramWriter.write(x).catch(()=>{}),this._ConnectionStats.packetsSent+=1;let A=x.byteLength;this.connectionStats.bytesSent+=A}catch{}}async readDatagrams(x,A,F){try{let r=x.datagrams.readable.getReader();for(;;){let t=await r.read();if(t.done)break;let e=t.value.byteLength;this.connectionStats.bytesReceived+=e,F(A,t.value)}}catch{}}_CleanUp(){n(`performing cleanup for connection ${this.id}`),clearInterval(this._PingIntervalId),this._RecycleWebRtcSession("connection closed")}_RecycleWebRtcSession(x){let A=this._WebRtcSession,F=this._PeerConnection;A===void 0&&F===void 0||(i(`recycling webrtc session of connection ${this.id}; ${x}`),this._WebRtcSession=void 0,this._PeerConnection=void 0,A?.cleanup(),F&&Lx(F))}async _EnsureWebRtcSession(){return this._WebRtcSession?this._WebRtcSession:this._WebRtcSessionFlight.run(async()=>(this._PeerConnection=new RTCPeerConnection,_x(this._PeerConnection),this._WebRtcSession=new Cx(this._PeerConnection,{sendOffer:async(x,A,F)=>{let r=await this._Request("WebRtcUpdate",{kind:"Sdp",type:"Offer",sdp:x,media_map:A,negotiation_id:F});if(r.type==="Failure")throw new Error(`failed to send sdp offer; ${r.reason}`)},sendIceCandidate:async x=>{await this._Request("WebRtcUpdate",{kind:"Trickle",candidate:x.candidate,spd_mid:x.sdpMid??void 0,spd_mline_index:x.sdpMLineIndex??void 0,username_fragment:x.usernameFragment??void 0})},sendIceComplete:async()=>{await this._Request("WebRtcUpdate",{kind:"TrickleFinished"})},closeConnection:async()=>{this._RecycleWebRtcSession("negotiation gave up")},checkConnection:async()=>{}}),this._HandleWebRtcUpdates(),this._WebRtcSession))}async _HandleWebRtcUpdates(){if(!this._WebRtcUpdatesRunning){for(this._WebRtcUpdatesRunning=!0;;){let x=await this.rpc.recv();if(x==="closed")break;x.name==="WebRtcUpdate"&&this._WebRtcSession?.handleWebRtcUpdate(x.properties)}this.close()}}async _Request(x,A,F){let r=Date.now(),t=await(F===void 0?this.rpc.request(x,A):this.rpc.request(x,A,F)),e=(Date.now()-r)/1e3;return x!=="Ping"&&n(`sent main rpc '${x}'; took: ${e}s`,{properties:A,timeout:F,result:t}),t==="closed"?(0,J.failure)("connection lost"):t}_RequestPing(x=3e4){return this._PingFlight.run(async()=>{let A=await this._Request("Ping",{},x);return A!=="timeout"&&A.type==="Success"})}async startLocalVideo(x,A,F){await(await this._EnsureWebRtcSession()).startLocalVideo(x,A,F)}stopLocalVideo(x){this._WebRtcSession?.stopLocalVideo(x)}async startRemoteVideo(x){return(await this._EnsureWebRtcSession()).startRemoteVideo(x)}stopRemoteVideo(x){this._WebRtcSession?.stopRemoteVideo(x)}async dump(){return{type:"H3",id:this.id,address:this.address,closed:this.closed,status:this.status,datagrams:{sent:this._ConnectionStats.packetsSent,received:this._ConnectionStats.packetsReceived},webRtc:{signalingState:this._PeerConnection?.signalingState??null,connectionState:this._PeerConnection?.connectionState??null,iceGatheringState:this._PeerConnection?.iceGatheringState??null,iceConnectionState:this._PeerConnection?.iceConnectionState??null,connectionStats:this._WebRtcSession?.stats??null}}}};var h=require("@4players/odin-common"),Nx=require("@4players/odin-common/api");o();var L=require("@4players/odin-common");o();async function f0(D,x){let A=performance.now(),F=(0,L.failure)("no connection was attempted");for(let r=0;r<C.ConnectInterval.length&&!x.aborted;r++){let t=A+uF(r);if(await(0,L.abortableSleep)(t-performance.now(),x)==="aborted")return(0,L.failure)("aborted");if(F=await lF(D,x),F.type==="Success")return F}return F}async function lF(D,x){let A;try{A=new WebSocket(D)}catch(v){return(0,L.failure)(`unable to create websocket; ${v}`)}let F=new AbortController,r=new Promise(v=>A.addEventListener("open",()=>v((0,L.success)(A)),{signal:F.signal})),t=new Promise(v=>A.addEventListener("close",E=>v((0,L.failure)(E.reason!==""?E.reason:"unable to establish websocket connection")),{signal:F.signal})),e=new Promise(v=>x.addEventListener("abort",()=>v((0,L.failure)("aborted")),{signal:F.signal})),j=await Promise.race([r,t,e]);return F.abort(),j}function uF(D){let x=C.ConnectInterval.slice(0,D).reduce((F,r)=>F+r,0),A=C.ConnectInterval[D]*Math.random();return x+A}var Hx=class D{constructor(x,A,F,r,t,e){this.id=x;this.address=A;this.url=F;this.onDatagram=r;this.connection=t;this.webRtc=e;this._PeerIdMap=new WeakMap;this._ConnectionStats={...h.CONNECTION_STATS_INITIAL};this._PingFlight=new Q;f(`creating new webrtc connection to '${this.address}' with id ${this.id}`),this.closeSignal.addEventListener("abort",()=>this._CleanUp(),{once:!0}),this._ClosePromise=new Promise(j=>{this.closeSignal.addEventListener("abort",()=>{j("closed")},{once:!0})}),_x(e),this._AudioChannel=this.webRtc.createDataChannel("audio",{id:2,negotiated:!0,ordered:!1,maxRetransmits:0}),this._AudioChannel.binaryType="arraybuffer",this._AudioChannel.onmessage=j=>{this._ConnectionStats.packetsReceived++;let v=new Uint8Array(j.data);this._ConnectionStats.bytesReceived+=v.byteLength,this.onDatagram(this.id,v)},this._AudioChannel.onerror=j=>i(`webrtc audio data channel for connection with id ${x} raised an error`,j),this._AudioChannel.onclosing=j=>f(`webrtc audio data channel for connection with id ${x} begins shutting down`,j),this._AudioChannel.onclose=j=>f(`webrtc audio data channel for connection with id ${x} has closed`,j),Y0(this._AudioChannel),this._WebRtcSession=new Cx(this.webRtc,{sendOffer:async(j,v,E)=>{let l=await this._Request("WebRtcUpdate",{kind:"Sdp",type:"Offer",sdp:j,media_map:v,negotiation_id:E});if(l.type==="Failure")throw new Error(`failed to send sdp offer; ${l.reason}`)},sendIceCandidate:async j=>{await this._Request("WebRtcUpdate",{kind:"Trickle",candidate:j.candidate,spd_mid:j.sdpMid??void 0,spd_mline_index:j.sdpMLineIndex??void 0,username_fragment:j.usernameFragment??void 0})},sendIceComplete:async()=>{await this._Request("WebRtcUpdate",{kind:"TrickleFinished"})},closeConnection:async()=>{this.close()},checkConnection:async()=>{this.healthCheck().then()}}),this._WebRtcSession.startup(),C.MainConnectionPingInterval!==void 0&&(this._PingIntervalId=setInterval(async()=>{this.connectionStats.rtt=await this.ping(C.HealthCheckTimeout)},C.MainConnectionPingInterval)),this._HandleWebRtcUpdates()}static async create(x,A,F,r){if(r.aborted)return(0,h.failure)("aborted");let t;try{t=new URL(`wss://${A}`)}catch(E){return(0,h.fail)(`address in token(${A}) can not be parsed; ${E}`)}let e=(0,h.extendUrl)(t,`main?uid=${bx}`);if(e.type!=="Success")return e;let j=await f0(e.value,r);if(j.type!=="Success")return j;let v=new Y(new T(j.value),Nx.MainCommandsRpc,Nx.MainNotificationsRpc);try{return(0,h.success)(new D(x,A,t,F,v,new RTCPeerConnection))}catch(E){return v.close(),(0,h.failure)(`unable to create webrtc connection; ${E}`)}}get status(){switch(this.webRtc.connectionState){case"connected":return 1;case"failed":case"closed":return 2;default:return 0}}get connectionStats(){return this._ConnectionStats}get transport(){return"WebRTC"}get closePromise(){return this._ClosePromise}get closeSignal(){return this.connection.closeSignal}get closed(){return this.connection.closed}async waitForConnected(){return new Promise((x,A)=>{let F=()=>{let r=this.status;r!==0&&(this.webRtc.removeEventListener("connectionstatechange",F),r===1?x():A(new Error("connection closed")))};this.webRtc.addEventListener("connectionstatechange",F),F(),this.closePromise.then(()=>{A(new Error("connection closed"))})})}close(){f(`closing ${this.transport} connection to '${this.address}' with id ${this.id}`),this.connection.close()}async joinRoom(x,A,F,r){let t=await this.connection.request("JoinRoom",{token:String(x),room_id:A,user_data:F,position:r});if(t==="closed"||t.type==="Failure")return t;let e=t.value;if(!("token"in e))return(0,h.failure)("JoinRoom responded without token");let j=(0,h.extendUrl)(this.url,`room?token=${e.token}`);if(j.type==="Failure")return j;let v=await f0(j.value,this.closeSignal);return v.type==="Success"?(this._PeerIdMap.set(v.value,e.peer_id),(0,h.success)(new T(v.value))):v}async getReconnectToken(x){let A=await this._Request("RequestReconnectToken",{peer_id:x});return A.type==="Failure"?A:y.parse(A.value)}async getRtcStats(){return this.webRtc.getStats()}async healthCheck(){let x=await this._RequestPing(C.HealthCheckTimeout);return x||this.close(),x}async ping(x=3e4){let A=Date.now();return await this._RequestPing(x)?Date.now()-A:0}sendDatagram(x){if(this._AudioChannel.readyState==="open"){let A=x.byteLength;this._AudioChannel.send(x),this._ConnectionStats.packetsSent+=1,this._ConnectionStats.bytesSent+=A}}_CleanUp(){n(`performing cleanup for connection ${this.id}`),clearInterval(this._PingIntervalId),xA(this._AudioChannel),Lx(this.webRtc),this._WebRtcSession.cleanup(),this.connection.close()}async _HandleWebRtcUpdates(){for(;;){let x=await this.connection.recv();if(x==="closed")break;x.name==="WebRtcUpdate"&&this._WebRtcSession.handleWebRtcUpdate(x.properties)}this.close()}async _Request(x,A,F){let r=Date.now(),t=await(F===void 0?this.connection.request(x,A):this.connection.request(x,A,F)),e=(Date.now()-r)/1e3;return x!=="Ping"&&n(`sent main rpc '${x}'; took: ${e}s`,{properties:A,timeout:F,result:t}),t==="closed"?(0,h.failure)("connection lost"):t}_RequestPing(x=3e4){return this._PingFlight.run(async()=>{let A=await this._Request("Ping",{},x);return A!=="timeout"&&A.type==="Success"})}async startLocalVideo(x,A,F){await this._WebRtcSession.startLocalVideo(x,A,F)}stopLocalVideo(x){this._WebRtcSession.stopLocalVideo(x)}async startRemoteVideo(x){return this._WebRtcSession.startRemoteVideo(x)}stopRemoteVideo(x){this._WebRtcSession.stopRemoteVideo(x)}async dump(){return{type:"WebRtc",id:this.id,address:this.address,url:this.url.toString(),closed:this.closed,audioChannel:{readyState:this._AudioChannel.readyState,bufferedAmount:this._AudioChannel.bufferedAmount},datagrams:{sent:this.connectionStats.packetsSent,received:this.connectionStats.packetsReceived},webRtc:{signalingState:this.webRtc.signalingState,connectionState:this.webRtc.connectionState,iceGatheringState:this.webRtc.iceGatheringState,iceConnectionState:this.webRtc.iceConnectionState,connectionStats:this._WebRtcSession.stats}}}};function FA(D,x,A,F,r){switch(f(`creating ${x} main connection to '${A}'`),x){case"H3":return Px.create(D,A,F,r);case"WebRTC":return Hx.create(D,A,F,r);default:throw new Error(`transport ${x} is not supported`)}}var ox=require("@4players/odin-common"),P=require("@4players/odin-common/api");o();var wx=class{constructor(x,A,F,r){this.id=x;this.connection=A;this.cipher=F;this.mediaMap=r;this._DatagramReceived=0;this._DatagramSent=0;this._DatagramReceivedInvalid=0;this._DatagramSentInvalid=0;A.closeSignal.addEventListener("abort",()=>this.close())}get connectionStats(){return this.connection.connectionStats}get transport(){return this.connection.transport}get address(){return this.connection.address}get status(){return this.closed?2:this.connection.status}get closePromise(){return this.connection.closePromise}get closeSignal(){return this.connection.closeSignal}get closed(){return this.connection.closed}waitForConnected(){return this.connection.waitForConnected()}close(){this.connection.close()}async joinRoom(x,A,F,r){this.cipher.reset();let t=await this.cipher.encryptUserData(F);if(t===B)return(0,ox.failure)("unable to encrypt initial user-data");let e=await this.connection.joinRoom(x,A,t,r);return e==="closed"||e.type==="Failure"?e:(0,ox.success)(new n0(e.value,this.cipher,this))}getReconnectToken(x){return this.connection.getReconnectToken(x)}getRtcStats(){return this.connection.getRtcStats()}healthCheck(){return this.connection.healthCheck()}async sendDatagram(x){let A=await this.cipher.encryptDatagram(x);A!==B?(this._DatagramSent+=1,this.connection.sendDatagram(A)):this._DatagramSentInvalid+=1}async decryptDatagram(x,A){let F=await this.cipher.decryptDatagram(x,A);return F!==B?this._DatagramReceived+=1:this._DatagramReceivedInvalid+=1,F}startLocalVideo(x,A,F){return this.connection.startLocalVideo(x,A,F)}stopLocalVideo(x){return this.connection.stopLocalVideo(x)}startRemoteVideo(x){return this.connection.startRemoteVideo(x)}stopRemoteVideo(x){return this.connection.stopRemoteVideo(x)}async dump(){return{type:"Encrypted",id:this.id,address:this.address,connectionId:this.connection.id,closed:this.closed,transport:this.transport,datagrams:{sent:this._DatagramSent,received:this._DatagramReceived,sentInvalid:this._DatagramSentInvalid,receivedInvalid:this._DatagramReceivedInvalid},cipher:await this.cipher.dump()}}},Jx=class{constructor(x){this.room=x}resendUserData(){this.room.roomConnection?.notify("UpdatePeer",{user_data:this.room.roomConnection.userData})}setUserData(x,A){let F={kind:"UserDataChanged",peer_id:x,user_data:A};this.room.onEvent("PeerUpdated",F)}},n0=class{constructor(x,A,F){this.rpc=x;this.cipher=A;this.connection=F;this.peers=new Map;this.closeSignal.addEventListener("abort",this.cleanup.bind(this),{once:!0})}get closed(){return this.rpc.closed}get closeSignal(){return this.rpc.closeSignal}async request(x,A,F){let r=await this.outgoing(x,A);return r===B?(0,ox.failure)("can not be encrypted"):await this.rpc.request(x,r,F)}async notify(x,A){let F=await this.outgoing(x,A);if(F!==B)return this.rpc.notify(x,F)}async recv(){for(;;){let x=await this.rpc.recv();if(x==="closed")return x;let A=await this.incoming(x.name,x.properties);if(A!==B)return{name:x.name,properties:A}}}close(){return this.rpc.close()}async outgoing(x,A){if(!(x in P.RoomCommandsRpc))return A;let F=(0,P.parseCommand)(x,A,P.RoomCommandsRpc);if(F===void 0)return B;switch(F.name){case"UpdatePeer":{let r=await this.cipher.encryptUserData(F.request.user_data);if(r===B)return B;F.request.user_data=r}break;case"SendMessage":{let r=await this.cipher.encryptMessage(F.request.message);if(r===B)return B;F.request.message=r}break}return F.request}async incoming(x,A){if(!(x in P.RoomNotificationsRpc))return A;let F=(0,P.parseNotification)(x,A,P.RoomNotificationsRpc);if(F===void 0)return B;switch(F.name){case"RoomUpdated":for(let r=0;r<F.properties.updates.length;r++){let t=await this.roomUpdate(F.properties.updates[r]);if(t===B)return B;F.properties.updates[r]=t}break;case"PeerUpdated":{let r=await this.peerUpdate(F.properties);if(r===B)return B;F.properties=r}break;case"MessageReceived":{let r=await this.cipher.decryptMessage(F.properties.sender_peer_id,F.properties.message);if(r===B)return B;F.properties.message=r}break}return F.properties}async peerUpdate(x){switch(x.kind){case"UserDataChanged":{let A=await this.cipher.decryptUserData(x.peer_id,x.user_data);if(A===B)return B;x.user_data=A}break;case"MediaStarted":this.mediaStarted(x.peer_id,x.media.id);break;case"MediaStopped":this.mediaStopped(x.peer_id,x.media_id);break}return x}async roomUpdate(x){switch(x.kind){case"Joined":for(let A of x.room.peers){for(let r of A.medias)this.mediaStarted(A.id,r.id);let F=await this.cipher.decryptUserData(A.id,A.user_data);F!==B?A.user_data=F:A.user_data=new Uint8Array}break;case"PeerJoined":{for(let F of x.peer.medias)this.mediaStarted(x.peer.id,F.id);let A=await this.cipher.decryptUserData(x.peer.id,x.peer.user_data);A!==B?x.peer.user_data=A:x.peer.user_data=new Uint8Array}break;case"PeerLeft":{let A=this.peers.get(x.peer_id);this.peers.delete(x.peer_id),this.cipher.deletePeerKey(x.peer_id);for(let F of A??[])this.mediaStopped(x.peer_id,F)}break}return x}mediaStarted(x,A){let F=this.peers.get(x);F===void 0&&(F=new Set,this.peers.set(x,F)),F.add(A);let r=p({connectionId:this.connection.connection.id,mediaId:A});this.connection.mediaMap.set(r,{peerId:x,connection:this.connection})}mediaStopped(x,A){this.peers.get(x)?.delete(A);let r=p({connectionId:this.connection.connection.id,mediaId:A});this.connection.mediaMap.delete(r)}cleanup(){for(let[x,A]of this.peers)for(let F of A)this.mediaStopped(x,F)}};var Ox=class{constructor(x){this.onDatagram=x;this._LastConnectionId=0;this._Connections=new Map;this._Close=new AbortController;this._MediaMap=new Map;let A=Date.now(),F=setInterval(()=>{Math.abs(Date.now()-A)>C.ClockJumpThreshold&&this.checkHealth(),A=Date.now()},C.ClockJumpCheckInterval);addEventListener("offline",()=>this.checkHealth(),{signal:this._Close.signal}),this._Close.signal.addEventListener("abort",()=>{clearInterval(F);for(let r of this._Connections.values())r.type==="establishing"?r.abort.abort():r.connection.close();this._Connections.clear()},{once:!0})}get closed(){return this._Close.signal.aborted}sendDatagram(x,A){let F=this._Connections.get(x);(F?.type==="established"||F?.type==="virtual")&&F.connection.sendDatagram(A)}async recvDatagram(x,A){let F=kF(A);if(F===void 0||F.length===0)return;let r=this._MediaMap.get(p({connectionId:x,mediaId:F[0]}));if(r===void 0)this.onDatagram(x,A);else{let t=await r.connection.decryptDatagram(r.peerId,A);if(t===B)return;this.onDatagram(r.connection.id,t)}}async acquireConnection(x,A,F,r){if(await(0,ax.nextTick)(),this.closed)return"closed";let t=this.findConnection(x,A),e;switch(t?.type){case"established":n(`reusing existing connection ${t.id}`),e=t;break;case"establishing":{n(`waiting for connecting to '${A}' finish`);let E=await t.finished;if(E.type!=="Success")return E;e=E.value}break;case void 0:{n(`connecting to '${A}'`);let E=await this.createConnection(x,A,r);if(E.type!=="Success")return E;e=E.value}break}let j=e.id,v=new s0(e.connection,()=>this.releaseConnection(j));return e.references+=1,F&&(v=new wx(++this._LastConnectionId,v,F,this._MediaMap),this.addConnection({type:"virtual",id:v.id,connection:v,createdAt:Date.now()})),(0,ax.success)(v)}async createConnection(x,A,F){let r=++this._LastConnectionId,t=Date.now(),e=new AbortController;F.addEventListener("abort",()=>e.abort(),{once:!0}),n(`creating new connection ${r}`);let j=FA(r,x,A,this.recvDatagram.bind(this),F),{promise:v,resolve:E}=Promise.withResolvers();this.addConnection({type:"establishing",id:r,address:A,transport:x,finished:v,createdAt:Date.now(),abort:e});let l=await j;if(this._Connections.delete(r),l.type!=="Success")return E(l),l;let k={type:"established",id:r,address:A,transport:x,createdAt:t,references:0,connection:l.value};return this.addConnection(k),(0,ax.success)(k)}addConnection(x){(x.type==="established"||x.type==="virtual")&&x.connection.closeSignal.addEventListener("abort",()=>{f(`connection ${x.id} has been closed`),this._Connections.delete(x.id)},{once:!0}),this._Connections.set(x.id,x)}releaseConnection(x){let A=this._Connections.get(x);A?.type==="established"&&(A.references-=1,A.references<=0&&A.connection.close())}checkHealth(){for(let x of this._Connections.values())x.type==="established"&&x.connection.healthCheck()}close(){this._Close.abort()}async dump(){let x=[];for(let F of this._Connections.values()){let r;switch(F.type){case"established":r={transport:F.transport,address:F.address,connection:await F.connection.dump(),references:F.references};break;case"establishing":r={transport:F.transport,address:F.address,aborted:F.abort.signal.aborted};break;case"virtual":r={connection:await F.connection.dump()};break}x.push({type:F.type,id:F.id,createdAt:F.createdAt,...r})}let A=[];for(let[F,r]of this._MediaMap)A.push(`${F} -> ${r.peerId} @${r.connection.id} `);return{lastConnectionId:this._LastConnectionId,connections:x,mediaMap:A,closed:this.closed}}findConnection(x,A){for(let F of this._Connections.values())if(F.type!=="virtual"&&F.transport===x&&F.address===A&&(F.type!=="established"||!F.connection.closed))return F}},s0=class{constructor(x,A){this.connection=x;this.release=A;this.closeController=new AbortController;this.closePromise=new Promise(x=>this.closeController.signal.addEventListener("abort",()=>x("closed"),{once:!0}));x.closeSignal.addEventListener("abort",()=>this.close(),{once:!0})}get closeSignal(){return this.closeController.signal}get closed(){return this.closeSignal.aborted}close(){this.release(),this.closeController.abort("closed")}get connectionStats(){return this.connection.connectionStats}get id(){return this.connection.id}get transport(){return this.connection.transport}get address(){return this.connection.address}get status(){return this.connection.status}waitForConnected(){return this.connection.waitForConnected()}joinRoom(x,A,F,r){return this.connection.joinRoom(x,A,F,r)}getReconnectToken(x){return this.connection.getReconnectToken(x)}getRtcStats(){return this.connection.getRtcStats()}healthCheck(){return this.connection.healthCheck()}sendDatagram(x){return this.connection.sendDatagram(x)}startLocalVideo(x,A,F){return this.connection.startLocalVideo(x,A,F)}stopLocalVideo(x){return this.connection.stopLocalVideo(x)}startRemoteVideo(x){return this.connection.startRemoteVideo(x)}stopRemoteVideo(x){return this.connection.stopRemoteVideo(x)}async dump(){let x=await this.connection.dump();return typeof x=="object"&&(x={...x,isShared:!0,referenceClosed:this.closed}),x}};function kF(D){let x;try{x=(0,rA.decode)(D)}catch{return}if(!Array.isArray(x)||x.length<2)return;let A=x[1];if(Array.isArray(A))return A.map(Number)}var Sx=require("@4players/odin-common"),H=class{constructor(x,A){this.uid=x;this.customType=A}#x;#A;get mediaStream(){return this.#x}get audioPlayback(){return(0,Sx.assert)(this.#A,"getting the audioPlayback failed, this video has no Audio"),this.#A}get volume(){return(0,Sx.assert)(this.audioPlayback,"getting the volume failed, this video has no Audio"),this.audioPlayback.volume}setVolume(x){(0,Sx.assert)(this.#A,"Can not set the volume, this video has no Audio"),this.#A.setVolume(x)}setMediaStream(x){this.#x=x}close(){this.#x?.getVideoTracks().forEach(x=>{x.stop(),this.#x?.removeTrack(x)}),this.#x=void 0}};var S=require("@4players/odin-common"),kA=require("@4players/odin-common/api");var b=require("@4players/odin-common"),V=require("@4players/odin-common/api");o();var Ux=class{constructor(x,A,F,r,t,e,j,v,E,l){this.connectionPool=x;this.transport=A;this.onEvent=F;this.gateway=r;this.roomId=e;this.cipher=E;this.disableAutoReconnect=l;this._Close=new AbortController;this._TokenUsed=!1;this._WasConnected=!1;this._FailedConnections=0;this._LastTokenRenew=performance.now();this._LastReconnectStartedAt=0;this._ReconnectingSince=0;this._Closed=new Promise(x=>this._Close.signal.addEventListener("abort",()=>x(this._Close.signal.reason?"disconnected":"closed"),{once:!0}));this._Token=t,this._UserData=j,this._Position=v,this._Main().then(({reason:k})=>n(`_Main() resolved; ${k}`))}get token(){return this._Token}get userData(){return this._UserData}get position(){return this._Position}get closed(){return this._Close.signal.aborted}get mainConnection(){return this._MainConnection}async requestUnsafe(x,A){if(this._RoomConnection===void 0)return(0,b.failure)("currently not connected");let F=await this._RoomConnection.request(x,A,void 0);return(0,b.assert)(F!=="timeout","request should not timeout"),F!=="closed"&&F.type==="Success"&&this._HandleRequests(x,A,F.value),F}async request(x,A){let F=Date.now(),r=await this.requestUnsafe(x,A),t=(Date.now()-F)/1e3;if(n(`sent room rpc '${x}'; took: ${t}s`,{properties:A,result:r}),r==="closed"||r.type==="Failure")return r;let e=(0,V.parseResponse)(x,r.value,V.RoomCommandsRpc);return e!==void 0?(0,b.success)(e):(0,b.failure)(`received invalid response from ${x}`)}notify(x,A){this._RoomConnection!==void 0&&this._RoomConnection.notify(x,A)}close(){this._Close.abort(!0)}get renewTokenIn(){let x=this._LastTokenRenew-performance.now()+C.MinTokenRefreshInterval,A=this._Token.timeLeft-C.MinTokenLifetime;return Math.max(x,A)}async _Main(){let x;for(let A=0;;this._FailedConnections++){if(await(0,b.sleep)(Math.max(A-performance.now(),0)),this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}if(this._WasConnected&&this._ReconnectingSince!==0&&DA(this._ReconnectingSince,C.MaxReconnectDuration)){x="reconnect time limit reached";break}if(A=performance.now()+1e3,this._TokenUsed=!0,this._Token.hasAudience("sfu")){let F=await this._ConnectToServer();if(F.type==="Success"&&F.value==="shutdown"){n("connection closed by user request; shutting down"),x="user requested";break}if(this.disableAutoReconnect&&this._WasConnected){x=F.type==="Failure"?F.reason:"connection lost";break}if(this._LastReconnectStartedAt===0&&(this._LastReconnectStartedAt=performance.now()),this._WasConnected&&this._ReconnectingSince===0&&(this._ReconnectingSince=performance.now()),F.type==="Failure"&&!this._WasConnected&&this._FailedConnections>=3){x=F.reason;break}if(F.type==="Failure"&&!DA(this._LastReconnectStartedAt))continue}if(this.reset(),this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}if(this.gateway!==void 0&&this._Token.hasAudience("gateway")){this._ChangeStatus("Joining",`requesting new token from ${this.gateway}`);let F=await cF(this.gateway,this._Token,this._Close.signal);if(F.type==="Success")if(F.value instanceof y)A=0,this._Token=F.value,this._TokenUsed=!1;else{x=`gateway error; ${F.value}`;break}else if(!this._WasConnected&&this._FailedConnections>=3){x="unable to contact the gateway";break}}if(this._TokenUsed&&this._Token.timeLeft<=0){x="token has expired";break}if(this._Close.signal.aborted||this.connectionPool.closed){x="user requested";break}}return this._ChangeStatus("Closed",x),this.close(),(0,b.failure)(x)}async _ConnectToServer(){let x=this._Token;for(;x.upstream!==void 0;)x=x.upstream;let A=x.claims.adr??this.gateway?.toString();if(!A)return(0,b.success)("continue");if(this._ChangeStatus("Joining",`connecting to ${x.claims.adr}`),this._MainConnection===void 0||this._MainConnection.closed||this._MainConnection.address!==x.claims.adr){this._MainConnection?.close();let t=await this.connectionPool.acquireConnection(this.transport,A,this.cipher,this._Close.signal);if(t==="closed")return(0,b.failure)("connection pool closed");if(t.type==="Failure")return this._ChangeStatus("Joining",`connection failed; ${t.reason}`),(0,b.failure)(`connection failed; ${t.reason}`);this._MainConnection=t.value,this._OwnPeerId=void 0}let F=await Promise.race([Promise.all([this._MainConnection.joinRoom(x,this.roomId,this.userData,this.position)]),(0,b.sleep)(C.ConnectTimeout,"timeout"),this._Closed]);if(F==="closed"||F==="disconnected")return(0,b.success)("continue");if(F==="timeout")return this._ChangeStatus("Joining","timed out"),(0,b.success)("continue");let[r]=F;if(r==="closed")return(0,b.success)("continue");if(r.type==="Failure")return(0,b.failure)(`unable to join room; ${r.reason}`);this._RoomConnection=r.value,this._WasConnected=!0,this._FailedConnections=0,this._ReconnectingSince=0,this._ChangeStatus("Joined",`joined ${this.roomId}`);try{await this._MainConnection.waitForConnected();let t=await this._HandleConnection(this._MainConnection);return(0,b.success)(t?"shutdown":"continue")}catch(t){return(0,b.failure)(`unable to handle connection; ${t}`)}}_ChangeStatus(x,A){let F={status:x,message:A};this.onEvent("RoomStatusChanged",F)}async _HandleConnection(x){if(this._RoomConnection===void 0)return!1;let A=new b.Selector([()=>(0,b.sleep)(this.renewTokenIn,"renewToken"),()=>(0,b.sleep)(500,"tick"),async()=>await this._RoomConnection?.recv(),()=>this._Closed,()=>x.closePromise]);for(;;){let F=await A.next();switch(F){case void 0:case"closed":return this._RoomConnection?.close(),this._MainConnection?.close(),!1;case"disconnected":return this._RoomConnection?.close(),this._MainConnection?.close(),!0;case"renewToken":this._RenewToken();break;case"tick":break;default:this._HandleEvent(F);break}}}_HandleEvent(x){if(x.name==="RoomUpdated"){let A=V.RoomNotificationsRpc.RoomUpdated.safeParse(x.properties);if(!A.success)return;for(let F of A.data.updates)F.kind==="Joined"&&(this._OwnPeerId=F.own_peer_id)}this.onEvent(x.name,x.properties)}_HandleRequests(x,A,F){switch(x){case"SetPeerPosition":{let r=V.RoomCommandsRpc.SetPeerPosition.request.safeParse(A);if(r.success){let t=r.data.position;this._Position=t.length===2?[t[0],t[1],0]:t}else i("unable to process SetPeerPosition command");break}case"UpdatePeer":{let r=V.RoomCommandsRpc.UpdatePeer.request.safeParse(A);r.success?this._UserData=r.data.user_data:i("unable to process UpdatePeer command");break}}}async _RenewToken(x){if(this._LastTokenRenew=performance.now(),!x&&this.token.timeLeft>C.MinTokenLifetime)return;if(this._MainConnection===void 0||this._OwnPeerId===void 0)return(0,b.failure)("connection is not established");let A=await this._MainConnection.getReconnectToken(this._OwnPeerId);return A.type==="Success"?(this._Token=A.value,(0,b.success)()):(0,b.failure)(`${this._MainConnection.address} rejected reconnect token request; ${A.reason}`)}reset(){this._LastReconnectStartedAt=0,this._RoomConnection?.close(),this._RoomConnection=void 0,this._MainConnection?.close(),this._MainConnection=void 0,this._OwnPeerId=void 0}};async function cF(D,x,A){try{let F={jsonrpc:"2.0",id:1,method:"Connect",params:{}};f(`sending authentication request to '${D}'`,F);let t=await(await fetch(D,{body:JSON.stringify(F),method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${x}`},signal:A})).json();if(f(`received authentication response fom '${D}'`,t),"result"in t)return y.parse(t.result.token);{let e=t.error?.message??"malformed response";return u(`gateway rejected token; ${e}`),(0,b.success)(e)}}catch(F){return(0,b.failure)(String(F))}}function DA(D,x=8e3){return performance.now()-D>x}o();var lA=require("@4players/odin-common");var W=require("@4players/odin-common");o();var sA=require("@4players/odin-common");o();var fA=require("@msgpack/msgpack");o();var tA={name:"PBKDF2",hash:"SHA-256",iterations:6e5,salt:new Uint8Array([111,100,105,110,95,99,114,121,112,116,111,95,109,97,115,116,101,114,95,107,101,121])},eA=D=>({name:"PBKDF2",hash:"SHA-256",iterations:600,salt:D}),jA=32,BA=1e6,vA=2147483648,CA=32,O=[79,68,73,78,1,75,105,109],Ex=16,fx=64,EA=16;function nA(D,x){if(D.length!==x.length)return!1;for(let A=0;A<D.length;A++)if(D[A]!==x[A])return!1;return!0}function dF(D){return isFinite(D)}function pF(D){return Array.isArray(D)}function Mx(D){return dF(D)?D:B}function lx(D){return D instanceof Uint8Array?D:B}function hF(D,...x){let A;try{A=(0,fA.decode)(D)}catch{return B}if(!pF(A))return B;let F=new Array(A.length);for(let r in x)if(F[r]=x[r](A[r]),F[r]===B)return B;return F}function Tx(D,...x){if(D.length<O.length)return m;for(let A=0;A<O.length;A++)if(D[A]!==O[A])return m;return hF(D.subarray(O.length),...x)}var nx=class{constructor(x){this.first=1;this.offset=0;this.window=Array(x)}isReplay(x){let A=x-this.first;if(A<0)return!0;if(A>=this.window.length)if(A<this.window.length*2){let t=A-this.window.length+1;A-=t;for(let e=0;e<t;e++)this.advance()}else return this.first=x+1-self.window.length,this.offset=0,this.window.fill(!1),!1;let F=(this.offset+A)%this.window.length,r=this.window[F]===!0;for(this.window[F]=!0;this.window[this.offset]===!0;)this.advance();return r}advance(){this.window[this.offset]=!1,this.first+=1,this.offset=(this.offset+1)%this.window.length}};var Rx=class D{constructor(x){this.key=x}static async create(x){typeof x=="string"&&(x=new TextEncoder().encode(x));let A=await globalThis.crypto.subtle.importKey("raw",x,"PBKDF2",!1,["deriveBits"]),F=await globalThis.crypto.subtle.deriveBits(tA,A,256),r=await globalThis.crypto.subtle.importKey("raw",F,"PBKDF2",!1,["deriveKey"]);return new D(r)}async generatePeerKey(x,A){return await globalThis.crypto.subtle.deriveKey(eA(x),this.key,{name:"AES-GCM",length:256},!1,[A])}},Kx=class D{constructor(x,A){this.seed=x;this.key=A;this.sequenceNumbers={datagram:1,message:1,userData:1};this.number_of_packets=0;this.number_of_bytes=0}static async create(x){let A=globalThis.crypto.getRandomValues(new Uint8Array(jA)),F=await x.generatePeerKey(A,"encrypt");return new D(A,F)}get limitReached(){return this.key===void 0?!1:this.number_of_bytes>=vA||this.number_of_packets>=BA}nextSequenceNumber(x){return this.sequenceNumbers[x]++}};function i0(D,x){return{kind:"encrypted",key:D,material:x,antiReplays:{datagram:new nx(CA),userData:new nx(0),message:new nx(0)}}}var Vx=class D{constructor(x,A,F,r){this.additionalData=x;this.sequenceNumber=A;this.seed=F;this.encrypted=r}static parse(x){let A=Tx(x,lx,Mx,lx);if(A===B||A===m)return A;let[F,r,t]=A,e=x.subarray(0,x.length-t.length);return new D(e,r,F,t)}isSameSeed(x){return nA(this.seed,x.seed)}async generateKey(x){return await x.generatePeerKey(this.seed,"decrypt")}};function Wx(D,x){let A=new Uint8Array(12);switch(A[0]=x&255,A[1]=x>>8&255,A[2]=x>>16&255,A[3]=x>>24&255,D){case"datagram":A[5]=1;break;case"userData":A[5]=2;break;case"message":A[5]=3;break;default:(0,sA.assert)(!1,"missing content implementation")}return A}var b0=require("@msgpack/msgpack"),bA=require("@4players/odin-common");o();var Qx=class{constructor(x){this.actions=x}changeKey(x){this.masterKey!==x&&(this.masterKey=x,this.ownKey=B,this.actions.resendUserData())}async encryptDatagram(x){let A=await this.getKey("datagram");return A===void 0?x:A===U?B:await GF(A,x)}async encryptMessage(x){let A=await this.getKey("message");return A===void 0?x:A===U?U:await iA(A,x,"message")}async encryptUserData(x){let A=await this.getKey("userData");return A===void 0?x:((0,bA.assert)(A!==U,"key unavailable for user data encryption"),await iA(A,x,"userData",A.seed))}async getKey(x){if(this.ownKey===B||this.ownKey?.limitReached)if(x==="userData")this.ownKey=this.masterKey?await Kx.create(this.masterKey):void 0;else return this.ownKey!==B&&(this.ownKey=B,this.actions.resendUserData()),U;return this.ownKey}reset(){this.ownKey=this.masterKey?B:void 0}};async function iA(D,x,A,...F){let r=D.nextSequenceNumber(A),t=x.length+Ex,e=qF(r,F,t),j=e.length-t,v=await oA(D,A,r,e.subarray(0,j),x);return e.set(new Uint8Array(v),j),e}function qF(D,x,A){let F=[];x.forEach(e=>F.push(e)),F.push(D),F.push(new Uint8Array(A));let r=(0,b0.encode)(F),t=new Uint8Array(O.length+r.length);return t.set(O,0),t.set(r,O.length),t}async function GF(D,x){let A=$F(x);if(A===B)return B;if((A.kind&fx)!==0)return B;let F=A.body.length+Ex,r=D.nextSequenceNumber("datagram"),t=(0,b0.encode)([A.kind|fx,A.mediaIds,r,new Uint8Array(F)]),e=t.length-F,j=await oA(D,"datagram",r,t.subarray(0,e),A.body);return t.set(j,e),t}async function oA(D,x,A,F,r){return new Uint8Array(await globalThis.crypto.subtle.encrypt({name:"AES-GCM",iv:Wx(x,A),additionalData:F,tagLength:Ex*8},D.key,r))}function $F(D){let x=new M(D),A=x.readArrayLength();if(s(A)||A<2)return B;let F=x.readNumber(),r=x.readArrayLength();if(s(F)||s(r))return B;if(r>EA)return B;let t=Array(r);for(let j=0;j<t.length;j++){let v=x.readNumber();if(s(v))return B;t[j]=v}let e=D.subarray(x.position);return{kind:F,mediaIds:t,body:e}}var aA=require("@msgpack/msgpack");o();var Xx=class{constructor(x){this.actions=x;this.peerKeys=new Map}async changeKey(x){this.masterKey=x;for(let[A,{kind:F,material:r}]of this.peerKeys)if(x!==void 0){let t=await r.generateKey(x),e=i0(t,r),j=await zx(e,"userData",r.additionalData,r.sequenceNumber,r.encrypted);j!==B?(this.peerKeys.set(A,e),this.actions.setUserData(A,j)):(this.peerKeys.set(A,{kind:"broken",material:r}),this.actions.setUserData(A,new Uint8Array))}else F==="encrypted"&&this.peerKeys.set(A,{kind:"broken",material:r})}async decryptDatagram(x,A){let F=yF(A);if(this.masterKey===void 0)return F===m?A:B;if(F===B||F===m)return B;let r=this.peerKeys.get(x);if(r?.kind!=="encrypted")return B;let t=await zx(r,"datagram",F.additionalData,F.sequenceNumber,F.encrypted);return t===B?B:IF(F.kind&~fx,F.mediaIds,t)}async decryptMessage(x,A){let F=Tx(A,Mx,lx);if(this.masterKey===void 0)return F===m?A:B;if(F===B||F===m)return B;let r=this.peerKeys.get(x);if(r?.kind!=="encrypted")return B;let[t,e]=F,j=A.subarray(0,A.length-e.length);return zx(r,"message",j,t,e)}async decryptUserData(x,A){let F=Vx.parse(A);if(F===B)return B;if(F===m)return this.peerKeys.delete(x),this.masterKey===void 0?A:B;if(this.masterKey===void 0)return this.peerKeys.set(x,{kind:"broken",material:F}),B;let r=this.peerKeys.get(x);if(r?.kind==="encrypted"&&r.material.isSameSeed(F))r.material=F;else{let e=await F.generateKey(this.masterKey);r=i0(e,F)}let t=await zx(r,"userData",F.additionalData,F.sequenceNumber,F.encrypted);return t===B?this.peerKeys.set(x,{kind:"broken",material:F}):r!==void 0&&this.peerKeys.set(x,r),t}reset(){this.peerKeys.clear()}};function yF(D){let x=new M(D),A=x.readArrayLength();if(s(A)||A<1)return B;let F=x.readNumber();if(s(F))return B;if((F&fx)===0)return m;if(A!==4)return B;let r=x.position;x.readObjects(1);let t=D.subarray(r,x.position),e=x.readNumber(),j=x.readBytes();if(s(e)||s(j))return B;let v=D.subarray(0,D.length-j.length);return{kind:F,mediaIds:t,additionalData:v,sequenceNumber:e,encrypted:j}}async function zx(D,x,A,F,r){let t=await globalThis.crypto.subtle.decrypt({name:"AES-GCM",iv:Wx(x,F),additionalData:A,tagLength:Ex*8},D.key,r).catch(()=>B);return t===B?B:D.antiReplays[x].isReplay(F)?B:new Uint8Array(t)}function IF(D,x,A){let F=2;try{let e=new M(A);for(e.position=0;e.position<A.length;)e.readObjects(1),F+=1}catch{return B}let r=(0,aA.encode)(D),t=new Uint8Array(3+r.length+x.length+A.length);return t[0]=220,t[1]=F>>8&255,t[2]=F&255,t.set(r,3),t.set(x,3+r.length),t.set(A,3+r.length+x.length),t}var Zx=class{constructor(x,A){this.active=!1;let F=new Xx(A),r=new Qx(A);this.crypto=new W.Strand({encryption:r,decryption:F}),this.peerKeys=F.peerKeys,this.configure(x)}encryptUserData(x){return this.crypto.enqueue(({encryption:A})=>A.encryptUserData(x))}async encryptMessage(x){let A;do A=await this.crypto.enqueue(({encryption:F})=>F.encryptMessage(x));while(A===U);return A}async encryptDatagram(x){return await this.crypto.enqueue(({encryption:A})=>A.encryptDatagram(x))}decryptUserData(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptUserData(x,A))}decryptMessage(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptMessage(x,A))}decryptDatagram(x,A){return this.crypto.enqueue(({decryption:F})=>F.decryptDatagram(x,A))}configure(x){return this.crypto.enqueue(async A=>{let F=x.password?await Rx.create(x.password):void 0;this.active=F!==void 0,await A.encryption.changeKey(F),await A.decryption.changeKey(F)})}getPeerStatus(x){switch(this.peerKeys.get(x)?.kind??"unencrypted"){case"broken":return W.Backend.PeerCipherStatus.InvalidPassword;case"encrypted":return W.Backend.PeerCipherStatus.Encrypted;case"unencrypted":return this.active?W.Backend.PeerCipherStatus.InvalidPassword:W.Backend.PeerCipherStatus.Unencrypted;default:return W.Backend.PeerCipherStatus.Unknown}}deletePeerKey(x){this.peerKeys.delete(x)}reset(){return this.crypto.enqueue(async({encryption:x,decryption:A})=>{x.reset(),A.reset()})}async dump(){return this.crypto.enqueue(async()=>({active:this.active,peers:Array.from(this.peerKeys).map(([x,A])=>`${x} => ${A.kind}`)}))}};function uA(D,x){return(0,lA.assert)(D.type==="OdinCrypto","only OdinCrypto supported"),new Zx(D,x)}var Yx=class{constructor(x,A,F){this._Captures=new Map;this._Playbacks=new Map;this._Peers=new Map;this._AvailableMediaIds=[];let{url:r,onEvent:t}=A,e=(0,S.unwrap)(y.parse(A.token)),j=A.roomId??e.defaultRoomId,v=A.userData??new Uint8Array(0),E=A.position??[0,0,0];(0,S.assert)(j!==void 0,"room id required for multi-room-tokens"),this.cipher=A.cipher?uA(A.cipher,new Jx(this)):void 0,this.onEvent=t,f(`creating new room '${j}' ${this.cipher?"with":"without"} cipher`,e,v,E),this._Connection=new Ux(x,A.transport??"H3",this._HandleEvent.bind(this),r?new URL(r):void 0,e,j,v,E,this.cipher,F?.disableAutoReconnect??!1)}get connectionStats(){let x={...S.CONNECTION_STATS_INITIAL};return this.mainConnection?this.mainConnection.connectionStats:x}async getRtcStats(){return this.mainConnection?.getRtcStats()}get roomConnection(){return this._Connection}get mainConnection(){return this.roomConnection?.mainConnection}get token(){return this._Connection.token.text}request(x,A){return this._Connection.requestUnsafe(x,A)}async link(x){if(x instanceof _){let A=this._Playbacks.get(x.uid)??{media:void 0,playback:void 0};A.playback!==void 0&&this.unlink(A.playback),A.media!==void 0&&x.start(A.media),A.playback=x,f(`linking audio playback media '${x.uid}' with volume ${x.volume} to room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof N){let A=this._Captures.get(x);A&&this.unlink(x);let F=this.mainConnection!==void 0&&this._AvailableMediaIds.shift();A={media:F?{connectionId:this.mainConnection.id,mediaId:F}:void 0},f(`linking audio capture media '${x.uid}' with volume ${x.volume} to room '${this._Connection.roomId}'`),this._Captures.set(x,A),A.media!==void 0&&await x.start(this._Connection,A.media)}else if(x instanceof H){let A=this._Playbacks.get(x.uid)??{media:void 0,playback:void 0};if(A.playback!==void 0&&A.playback!==x&&(A.playback instanceof H?(A.playback.setMediaStream(void 0),A.playback=void 0):this.unlink(A.playback)),A.media!==void 0){let F=await this.mainConnection?.startRemoteVideo(A.media.mediaId);F&&x.setMediaStream(new MediaStream([F]))}A.playback=x,f(`linking video playback media '${x.uid}' with type '${x.customType}' to room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof $){let A=this._Captures.get(x);A&&this.unlink(x);let F=x.mediaStream?.getVideoTracks()[0];if(F){let r=this.mainConnection!==void 0&&this._AvailableMediaIds.shift();A={media:r?{connectionId:this.mainConnection.id,mediaId:r}:void 0},f(`linking video capture media '${x.uid}' with type '${x.parameters?.customType}' to room '${this._Connection.roomId}'`),this._Captures.set(x,A),A.media!==void 0&&(await x.start(this._Connection,A.media),this.mainConnection?.startLocalVideo(A.media.mediaId,F,x.parameters)),x.audioCapture&&await this.link(x.audioCapture)}}else throw new Error("Linking failed, media was not supported")}unlink(x){if(x instanceof _||x instanceof H){let A=this._Playbacks.get(x.uid);if(A?.playback!==x)return;A.playback=void 0,A.media!==void 0&&(x instanceof _?x.stop(A.media):(this.mainConnection?.stopRemoteVideo(A.media.mediaId),x.setMediaStream(void 0))),f(`unlinking playback media '${x.uid}' from room '${this._Connection.roomId}'`),this._Playbacks.set(x.uid,A)}else if(x instanceof N||x instanceof $){x instanceof $&&x.audioCapture&&this.unlink(x.audioCapture);let A=this._Captures.get(x);if(A===void 0)return;A.media!==void 0&&(x.stop(this._Connection,A.media),this._AvailableMediaIds.push(A.media.mediaId),x instanceof $&&this.mainConnection?.stopLocalVideo(A.media.mediaId)),f(`unlinking capture media '${x.uid}' from room '${this._Connection.roomId}'`),this._Captures.delete(x)}else throw new Error("invalid media")}close(){f(`closing room '${this._Connection.roomId}'`),this._Connection.close()}_HandleEvent(x,A){let F=E0(kA.RoomNotificationsRpc,{name:x,properties:A});F!==void 0&&(this._HandleKnownEvent(F),A=F.properties),this.onEvent(x,A)}_HandleKnownEvent(x){switch(n(`processing event '${x.name}'`,x.properties),x.name){case"RoomStatusChanged":x.properties.status!=="Joined"&&this._HandleConnectionLost();break;case"RoomUpdated":for(let A of x.properties.updates)this._HandleRoomUpdate(A);break;case"PeerUpdated":this._HandlePeerUpdate(x.properties);break}}_HandleConnectionLost(){for(let x of this._Peers.keys())this._HandlePeerLeft(x);for(let[x,A]of this._Captures)A.media!==void 0&&(x instanceof $,x instanceof N&&(x.stop(this._Connection,A.media),A.media=void 0));this._AvailableMediaIds.length=0}_HandleRoomUpdate(x){if(x.kind==="Joined"){(0,S.assert)(this._AvailableMediaIds.length===0,"left over media ids"),this._AvailableMediaIds.push(...x.media_ids),this._HandleRoomJoined();for(let A of x.room.peers)this._HandlePeerJoined(A)}else x.kind==="PeerJoined"?this._HandlePeerJoined(x.peer):x.kind==="PeerLeft"&&this._HandlePeerLeft(x.peer_id)}_HandleRoomJoined(){for(let[x,A]of this._Captures)this._AvailableMediaIds.length===0||this.mainConnection===void 0||(A.media={connectionId:this.mainConnection.id,mediaId:this._AvailableMediaIds.shift()},x instanceof N&&x.start(this._Connection,A.media),x instanceof $)}_HandlePeerUpdate(x){x.kind==="MediaStarted"?this._HandleMediaStart(x.peer_id,x.media):x.kind==="MediaStopped"&&this._HandleMediaStopped(x.peer_id,x.media_id)}_HandlePeerJoined(x){this._Peers.has(x.id)||this._Peers.set(x.id,{mediaIds:new Map});for(let A of x.medias)this._HandleMediaStart(x.id,A)}_HandlePeerLeft(x){let A=this._Peers.get(x);if(A!==void 0){for(let F of A.mediaIds.keys())this._HandleMediaStopped(x,F);this._Peers.delete(x)}}_HandleMediaStart(x,A){if(this.mainConnection===void 0)return;let F=this._Peers.get(x);if(F===void 0||A.properties.kind!=="audio"&&A.properties.kind!=="video")return;let r=String(A.properties.uid??(0,S.generateUUID)());A.properties.uid=r;let t=this._Playbacks.get(r)??{media:void 0,playback:void 0};if(this._Playbacks.set(r,t),F.mediaIds.set(A.id,r),t.media={connectionId:this.mainConnection.id,mediaId:A.id},t.playback!==void 0&&(t.playback instanceof _&&t.playback.start(t.media),t.playback instanceof H)){let e=t.playback;this.mainConnection.startRemoteVideo(t.media.mediaId).then(j=>{e.setMediaStream(new MediaStream([j]))}).catch(j=>{i(`failed to start remote video for media ${A.id}`,j)})}}_HandleMediaStopped(x,A){let F=this._Peers.get(x);if(F===void 0)return;let r=F?.mediaIds.get(A);if(r===void 0)return;let t=this._Playbacks.get(r);t!==void 0&&(t.media!==void 0&&t.media.mediaId===A&&t.playback!==void 0&&(t.playback instanceof _&&t.playback.stop(t.media),t.playback instanceof H&&this.mainConnection?.stopRemoteVideo(t.media.mediaId),t.media=void 0),F.mediaIds.delete(A))}};mx();function _F(D,x){I0(x?.logger,x?.onLogMessage);let A,F=new Ox((t,e)=>A.receivePacket(t,e)),r=new yx(D);return A=new Ix(r,F.sendDatagram.bind(F),x?.enableHTMLAudioElementFallback??!1),new o0(F,A,x)}var bx=(0,gF.generateUUID)(),a0=[],cA=!1;function LF(){cA||typeof window>"u"||(window.addEventListener("beforeunload",()=>{for(let D of a0)D.deref()?.close()}),cA=!0)}var o0=class{constructor(x,A,F){this.version="9";this.supportedTransports=["H3","WebRTC"];this._PlaybackVolume=[1,1];this._CreatedAt=Date.now();this._Options=F??{},this._Options.disableBeforeUnload||LF(),this._ConnectionPool=x,this._MediaController=A,a0.push(new WeakRef(this)),f("plugin initialized")}get playbackVolume(){return this._PlaybackVolume}joinRoom(x){return new Yx(this._ConnectionPool,x,this._Options)}async createAudioPlayback(x){return this._MediaController.createAudioPlayback(x)}async createAudioCapture(x){return this._MediaController.createAudioCapture(x)}async createVideoCapture(x,A){return this._MediaController.createVideoCapture(x,A)}async createVideoPlayback(x){return new H(x.uid,x.customType)}enumerateDevices(){return hx()}setOutputVolume(x){this._MediaController.playbackSetGlobalVolume(x)}async setOutputDevice(x){await this._MediaController.playbackSetDevice(x.device)}close(){this._MediaController.close(),this._ConnectionPool.close(),f("plugin closed")}async dump(){return{createdAt:this._CreatedAt,connections:await this._ConnectionPool.dump(),medias:await this._MediaController.dump()}}};async function dA(){let D=[];for(let x of a0){let A=x.deref();A!==void 0&&D.push(await A.dump())}return JSON.stringify({timestamp:Date.now(),instances:D,background:await N0()})}globalThis.odin_debug_dump_state=dA;window!==void 0&&(window.odin_debug_dump_state=dA);0&&(module.exports={SESSION_ID,createPlugin});