{"version":3,"file":"index.bundle.js","mappings":"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AA0B,kDAAkD,sBAAsB,6BAA6B,8BAA8B,sXAAsX,EAAE,GAAG,yBAAyB,yEAAyE,iBAAiB,8CAA8C,UAAU;;;;;;;;;;ACAv61I;AACa;;AAEb;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB;AACpB,2BAA2B;AAC3B;AACA;AACA;AACA,8DAA8D;AAC9D,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,KAAK;AACL,iDAAiD;AACjD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,kBAAkB,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI,IAA0B;AAC9B;AACA;;;;;;;UCjyBA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;;;;;;;;;ACNyH;AACzH;AACA;AACA;;AAEA;AACA;;AAEO;AACP,wBAAwB;;AAExB,IAAI,kFAAM;AACV;AACA,uBAAuB,kFAAM;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;;AAE/B,iCAAiC,4FAAgB;;AAEjD;AACA,+BAA+B,0FAAc,WAAW,4BAA4B;;AAEpF;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;;AAEL;AACA;AACA,KAAK;;AAEL,8DAA8D,QAAQ,+CAA+C;AACrH;AACA;AACA;AACA;AACA,wCAAwC,4FAAgB;AACxD;;AAEA;AACA,6CAA6C,4FAAgB;AAC7D;AACA,UAAU;AACV;AACA,wCAAwC,4FAAgB;AACxD;;AAEA;AACA,6CAA6C,4FAAgB;AAC7D;AACA,0EAA0E,4FAAgB;AAC1F;AACA,6CAA6C,4FAAgB;AAC7D;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,oBAAoB;AACpB;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA,gDAAgD;;AAEhD;;AAEA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,oDAAoD;AACpD;AACA;AACA;AACA;;;AAGA;AACA,0CAA0C,4BAA4B,qBAAqB,gCAAgC;;AAE3H;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;;AAEA;AACA,kCAAkC;;AAElC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEO;AACP,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B,0BAA0B,iFAAK;AAC/B;;AAEO;AACP;AACA;AACA,KAAK;AACL;AACA,8BAA8B;AAC9B;;AAEA;AACA;AACA,yC","sources":["webpack://npmjs/./node_modules/@epicgames-ps/lib-pixelstreamingfrontend-ue5.4/dist/lib-pixelstreamingfrontend.esm.js","webpack://npmjs/./node_modules/sdp/sdp.js","webpack://npmjs/webpack/bootstrap","webpack://npmjs/webpack/runtime/compat get default export","webpack://npmjs/webpack/runtime/define property getters","webpack://npmjs/webpack/runtime/hasOwnProperty shorthand","webpack://npmjs/webpack/runtime/make namespace object","webpack://npmjs/./index.js"],"sourcesContent":["import*as e from\"sdp\";var t,s,n={d:(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},r={};n.d(r,{Dz:()=>ye,g$:()=>A,Lt:()=>k,Q9:()=>x,qf:()=>L,hV:()=>Ae,z$:()=>Rt,J0:()=>Pe,De:()=>Te,$C:()=>Ee,al:()=>_,_W:()=>W,Gv:()=>se,m:()=>ne,tz:()=>z,Nu:()=>Re,zg:()=>He,vp:()=>he,vU:()=>ge,wF:()=>j,rv:()=>we,Nh:()=>be,ss:()=>_e,qW:()=>re,QL:()=>te,cf:()=>Ne,eM:()=>J,Yd:()=>i,Tk:()=>Ge,iM:()=>S,qy:()=>a,ce:()=>v,sK:()=>me,Ok:()=>Ce,q5:()=>ke,g:()=>bt,xl:()=>q,I:()=>$,bx:()=>X,dD:()=>de,Ib:()=>M,Az:()=>w,Iw:()=>b,qY:()=>P,db:()=>R,mR:()=>ie,Tn:()=>C,rV:()=>Y,gh:()=>V,Mi:()=>N,j:()=>K,YB:()=>Q,Yt:()=>ee,i5:()=>Z,x_:()=>Se,Am:()=>pt,eR:()=>F,r8:()=>H,u3:()=>Ve,vd:()=>O,iV:()=>U,jZ:()=>I,SW:()=>B,ZH:()=>G,Ni:()=>vt,lh:()=>D,ZP:()=>ce,bq:()=>f,$f:()=>Et,eu:()=>le,Ax:()=>oe,Mc:()=>ae});class i{static GetStackTrace(){const e=new Error;let t=\"No Stack Available for this browser\";return e.stack&&(t=e.stack.toString().replace(/Error/g,\"\")),t}static SetLoggerVerbosity(e){null!=this.verboseLogLevel&&(this.verboseLogLevel=e)}static Log(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Log\\nMsg: ${t}\\nCaller: ${e}`;console.log(n)}static Info(e,t,s){if(s>this.verboseLogLevel)return;const n=`Level: Info\\nMsg: ${t}`;console.info(n)}static Error(e,t){const s=`Level: Error\\nMsg: ${t}\\nCaller: ${e}`;console.error(s)}static Warning(e,t){const s=`Level: Warning\\nCaller: ${e}\\nMsg: ${t}`;console.warn(s)}}i.verboseLogLevel=5,function(e){e.LIST_STREAMERS=\"listStreamers\",e.SUBSCRIBE=\"subscribe\",e.UNSUBSCRIBE=\"unsubscribe\",e.ICE_CANDIDATE=\"iceCandidate\",e.OFFER=\"offer\",e.ANSWER=\"answer\",e.DATACHANNELREQUEST=\"dataChannelRequest\",e.SFURECVDATACHANNELREADY=\"peerDataChannelsReady\",e.PONG=\"pong\"}(t||(t={}));class a{sendFilter(e,t){return t}payload(){return i.Log(i.GetStackTrace(),\"Sending => \\n\"+JSON.stringify(this,this.sendFilter,4),6),JSON.stringify(this,this.sendFilter)}}class o extends a{constructor(){super(),this.type=t.LIST_STREAMERS}}class l extends a{constructor(e){super(),this.type=t.SUBSCRIBE,this.streamerId=e}}class d extends a{constructor(){super(),this.type=t.UNSUBSCRIBE}}class c extends a{constructor(e){super(),this.type=t.PONG,this.time=e}}class h extends a{constructor(e,s){super(),this.type=t.OFFER,this.minBitrate=0,this.maxBitrate=0,e&&(this.type=e.type,this.sdp=e.sdp,this.minBitrate=s.minBitrateBps,this.maxBitrate=s.maxBitrateBps)}sendFilter(e,t){if(\"minBitrate\"!=e&&\"maxBitrate\"!=e||!(t<=0))return t}}class g extends a{constructor(e,s){super(),this.type=t.ANSWER,this.minBitrate=0,this.maxBitrate=0,e&&(this.type=e.type,this.sdp=e.sdp,this.minBitrate=s.minBitrateBps,this.maxBitrate=s.maxBitrateBps)}sendFilter(e,t){if(\"minBitrate\"!=e&&\"maxBitrate\"!=e||!(t<=0))return t}}class u extends a{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class m extends a{constructor(){super(),this.type=t.SFURECVDATACHANNELREADY}}class p{constructor(e){this.type=t.ICE_CANDIDATE,this.candidate=e}payload(){return i.Log(i.GetStackTrace(),\"Sending => \\n\"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}!function(e){e.CONFIG=\"config\",e.STREAMER_LIST=\"streamerList\",e.STREAMER_ID_CHANGED=\"streamerIDChanged\",e.PLAYER_COUNT=\"playerCount\",e.OFFER=\"offer\",e.ANSWER=\"answer\",e.ICE_CANDIDATE=\"iceCandidate\",e.PEER_DATA_CHANNELS=\"peerDataChannels\",e.PING=\"ping\",e.WARNING=\"warning\"}(s||(s={}));class S{}class v extends S{}class C{constructor(){this.FromUEMessageHandlers=new Map}addMessageHandler(e,t){this.FromUEMessageHandlers.set(e,t)}handleMessage(e,t){this.FromUEMessageHandlers.has(e)?this.FromUEMessageHandlers.get(e)(t):i.Error(i.GetStackTrace(),`Message type of ${e} does not have a message handler registered on the frontend - ignoring message.`)}static setupDefaultHandlers(e){e.signallingProtocol.addMessageHandler(s.PING,(t=>{const n=new c((new Date).getTime()).payload();i.Log(i.GetStackTrace(),s.PING+\": \"+t,6),e.webSocket.send(n)})),e.signallingProtocol.addMessageHandler(s.CONFIG,(t=>{i.Log(i.GetStackTrace(),s.CONFIG,6);const n=JSON.parse(t);e.onConfig(n)})),e.signallingProtocol.addMessageHandler(s.STREAMER_LIST,(t=>{i.Log(i.GetStackTrace(),s.STREAMER_LIST,6);const n=JSON.parse(t);e.onStreamerList(n)})),e.signallingProtocol.addMessageHandler(s.STREAMER_ID_CHANGED,(t=>{i.Log(i.GetStackTrace(),s.STREAMER_ID_CHANGED,6);const n=JSON.parse(t);e.onStreamerIDChanged(n)})),e.signallingProtocol.addMessageHandler(s.PLAYER_COUNT,(t=>{i.Log(i.GetStackTrace(),s.PLAYER_COUNT,6);const n=JSON.parse(t);i.Log(i.GetStackTrace(),\"Player Count: \"+n.count,6),e.onPlayerCount(n)})),e.signallingProtocol.addMessageHandler(s.ANSWER,(t=>{i.Log(i.GetStackTrace(),s.ANSWER,6);const n=JSON.parse(t);e.onWebRtcAnswer(n)})),e.signallingProtocol.addMessageHandler(s.OFFER,(t=>{i.Log(i.GetStackTrace(),s.OFFER,6);const n=JSON.parse(t);e.onWebRtcOffer(n)})),e.signallingProtocol.addMessageHandler(s.ICE_CANDIDATE,(t=>{i.Log(i.GetStackTrace(),s.ICE_CANDIDATE,6);const n=JSON.parse(t);e.onIceCandidate(n.candidate)})),e.signallingProtocol.addMessageHandler(s.WARNING,(e=>{i.Warning(i.GetStackTrace(),`Warning received: ${e}`)})),e.signallingProtocol.addMessageHandler(s.PEER_DATA_CHANNELS,(t=>{i.Log(i.GetStackTrace(),s.PEER_DATA_CHANNELS,6);const n=JSON.parse(t);e.onWebRtcPeerDataChannels(n)}))}}class f{constructor(){this.WS_OPEN_STATE=1,this.onOpen=new EventTarget,this.onClose=new EventTarget,this.signallingProtocol=new C,C.setupDefaultHandlers(this)}connect(e){i.Log(i.GetStackTrace(),e,6);try{return this.webSocket=new WebSocket(e),this.webSocket.onopen=e=>this.handleOnOpen(e),this.webSocket.onerror=()=>this.handleOnError(),this.webSocket.onclose=e=>this.handleOnClose(e),this.webSocket.onmessage=e=>this.handleOnMessage(e),this.webSocket.onmessagebinary=e=>this.handleOnMessageBinary(e),!0}catch(e){return i.Error(e,e),!1}}handleOnMessageBinary(e){e&&e.data&&e.data.text().then((e=>{const t=new MessageEvent(\"messageFromBinary\",{data:e});this.handleOnMessage(t)})).catch((e=>{i.Error(i.GetStackTrace(),`Failed to parse binary blob from websocket, reason: ${e}`)}))}handleOnMessage(e){if(e.data&&e.data instanceof Blob)return void this.handleOnMessageBinary(e);const t=JSON.parse(e.data);i.Log(i.GetStackTrace(),\"received => \\n\"+JSON.stringify(JSON.parse(e.data),void 0,4),6),this.signallingProtocol.handleMessage(t.type,e.data)}handleOnOpen(e){i.Log(i.GetStackTrace(),\"Connected to the signalling server via WebSocket\",6),this.onOpen.dispatchEvent(new Event(\"open\"))}handleOnError(){i.Error(i.GetStackTrace(),\"WebSocket error\")}handleOnClose(e){i.Log(i.GetStackTrace(),\"Disconnected to the signalling server via WebSocket: \"+JSON.stringify(e.code)+\" - \"+e.reason),this.onClose.dispatchEvent(new CustomEvent(\"close\",{detail:e}))}requestStreamerList(){const e=new o;this.webSocket.send(e.payload())}sendSubscribe(e){const t=new l(e);this.webSocket.send(t.payload())}sendUnsubscribe(){const e=new d;this.webSocket.send(e.payload())}sendWebRtcOffer(e,t){const s=new h(e,t);this.webSocket.send(s.payload())}sendWebRtcAnswer(e,t){const s=new g(e,t);this.webSocket.send(s.payload())}sendWebRtcDatachannelRequest(){const e=new u;this.webSocket.send(e.payload())}sendSFURecvDataChannelReady(){const e=new m;this.webSocket.send(e.payload())}sendIceCandidate(e){if(i.Log(i.GetStackTrace(),\"Sending Ice Candidate\"),this.webSocket&&this.webSocket.readyState===this.WS_OPEN_STATE){const t=new p(e);this.webSocket.send(t.payload())}}close(){var e;null===(e=this.webSocket)||void 0===e||e.close()}onConfig(e){}onStreamerList(e){}onStreamerIDChanged(e){}onIceCandidate(e){}onWebRtcAnswer(e){}onWebRtcOffer(e){}onWebRtcPeerDataChannels(e){}onPlayerCount(e){}}class T{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement(\"Audio\"),this.videoElementProvider.setAudioElement(this.audioElement)}handleOnTrack(e){i.Log(i.GetStackTrace(),\"handleOnTrack \"+JSON.stringify(e.streams),6);const t=this.videoElementProvider.getVideoElement();if(e.track&&i.Log(i.GetStackTrace(),\"Got track - \"+e.track.kind+\" id=\"+e.track.id+\" readyState=\"+e.track.readyState,6),\"audio\"!=e.track.kind)return\"video\"==e.track.kind&&t.srcObject!==e.streams[0]?(t.srcObject=e.streams[0],void i.Log(i.GetStackTrace(),\"Set video source from video track ontrack.\")):void 0;this.CreateAudioTrack(e.streams[0])}CreateAudioTrack(e){const t=this.videoElementProvider.getVideoElement();t.srcObject!=e&&t.srcObject&&t.srcObject!==e&&(this.audioElement.srcObject=e,i.Log(i.GetStackTrace(),\"Created new audio element to play separate audio stream.\"))}}class E{constructor(e){this.freezeFrameHeight=0,this.freezeFrameWidth=0,this.rootDiv=e,this.rootElement=document.createElement(\"div\"),this.rootElement.id=\"freezeFrame\",this.rootElement.style.display=\"none\",this.rootElement.style.pointerEvents=\"none\",this.rootElement.style.position=\"absolute\",this.rootElement.style.zIndex=\"20\",this.imageElement=document.createElement(\"img\"),this.imageElement.style.position=\"absolute\",this.rootElement.appendChild(this.imageElement),this.rootDiv.appendChild(this.rootElement)}setElementForShow(){this.rootElement.style.display=\"block\"}setElementForHide(){this.rootElement.style.display=\"none\"}updateImageElementSource(e){const t=btoa(e.reduce(((e,t)=>e+String.fromCharCode(t)),\"\"));this.imageElement.src=\"data:image/jpeg;base64,\"+t}setDimensionsFromElementAndResize(){this.freezeFrameHeight=this.imageElement.naturalHeight,this.freezeFrameWidth=this.imageElement.naturalWidth,this.resize()}resize(){if(0!==this.freezeFrameWidth&&0!==this.freezeFrameHeight){let e=0,t=0,s=0,n=0;const r=this.rootDiv.clientWidth/this.rootDiv.clientHeight,i=this.freezeFrameWidth/this.freezeFrameHeight;r{this.freezeFrame.setDimensionsFromElementAndResize(),t()}}processFreezeFrameMessage(e,t){this.receiving||(this.receiving=!0,this.valid=!1,this.size=0,this.jpeg=void 0),this.size=new DataView(e.slice(1,5).buffer).getInt32(0,!0);const s=e.slice(5);if(this.jpeg){const e=new Uint8Array(this.jpeg.length+s.length);e.set(this.jpeg,0),e.set(s,this.jpeg.length),this.jpeg=e}else this.jpeg=s,this.receiving=!0,i.Log(i.GetStackTrace(),`received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,6);this.jpeg.length===this.size?(this.receiving=!1,this.valid=!0,i.Log(i.GetStackTrace(),`received complete freeze frame ${this.size}`,6),this.updateFreezeFrameAndShow(this.jpeg,t)):this.jpeg.length>this.size&&(i.Error(i.GetStackTrace(),`received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`),this.jpeg=void 0,this.receiving=!1)}}class M{constructor(e,t,s,n,r=(()=>{})){this.onChange=r,this.onChangeEmit=()=>{},this.id=e,this.description=s,this.label=t,this.value=n}set label(e){this._label=e,this.onChangeEmit(this._value)}get label(){return this._label}get value(){return this._value}set value(e){this._value=e,this.onChange(this._value,this),this.onChangeEmit(this._value)}}class w extends M{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const a=new URLSearchParams(window.location.search);if(r&&a.has(this.id)){const e=this.getUrlParamFlag();this.flag=e}else this.flag=n;this.useUrlParams=r}getUrlParamFlag(){const e=new URLSearchParams(window.location.search);return!!e.has(this.id)&&\"false\"!==e.get(this.id)&&\"False\"!==e.get(this.id)}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);!0===this.flag?e.set(this.id,\"true\"):e.set(this.id,\"false\"),window.history.replaceState({},\"\",\"\"!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}enable(){this.flag=!0}get flag(){return!!this.value}set flag(e){this.value=e}}class b extends M{constructor(e,t,s,n,r,i,a,o=(()=>{})){super(e,t,s,i,o),this._min=n,this._max=r;const l=new URLSearchParams(window.location.search);if(a&&l.has(this.id)){const e=Number.parseFloat(l.get(this.id));this.number=Number.isNaN(e)?i:e}else this.number=i;this.useUrlParams=a}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.number.toString()),window.history.replaceState({},\"\",\"\"!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}set number(e){this.value=this.clamp(e)}get number(){return this.value}clamp(e){return Math.max(Math.min(this._max,e),this._min)}get min(){return this._min}get max(){return this._max}addOnChangedListener(e){this.onChange=e}}class R extends M{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const a=new URLSearchParams(window.location.search);if(r&&a.has(this.id)){const e=this.getUrlParamText();this.text=e}else this.text=n;this.useUrlParams=r}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:\"\"}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.text),window.history.replaceState({},\"\",\"\"!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}get text(){return this.value}set text(e){this.value=e}}class P extends M{constructor(e,t,s,n,r,i,a=(()=>{})){super(e,t,s,n,a),this.options=r;const o=new URLSearchParams(window.location.search),l=i&&o.has(this.id)?this.getUrlParamText():n;this.selected=l,this.useUrlParams=i}getUrlParamText(){var e;const t=new URLSearchParams(window.location.search);return t.has(this.id)&&null!==(e=t.get(this.id))&&void 0!==e?e:\"\"}updateURLParams(){if(this.useUrlParams){const e=new URLSearchParams(window.location.search);e.set(this.id,this.selected),window.history.replaceState({},\"\",\"\"!==e.toString()?`${location.pathname}?${e}`:`${location.pathname}`)}}addOnChangedListener(e){this.onChange=e}get options(){return this._options}set options(e){this._options=e,this.onChangeEmit(this.selected)}get selected(){return this.value}set selected(e){let t=this.options.filter((t=>-1!==t.indexOf(e)));t.length?this.value=t[0]:(t=this.options.filter((t=>-1!==t.indexOf(e.split(\" \")[0]))),t.length&&(this.value=t[0]))}}class k extends Event{constructor(e){super(\"afkWarningActivate\"),this.data=e}}class L extends Event{constructor(e){super(\"afkWarningUpdate\"),this.data=e}}class x extends Event{constructor(){super(\"afkWarningDeactivate\")}}class A extends Event{constructor(){super(\"afkTimedOut\")}}class F extends Event{constructor(e){super(\"videoEncoderAvgQP\"),this.data=e}}class D extends Event{constructor(){super(\"webRtcSdp\")}}class O extends Event{constructor(){super(\"webRtcAutoConnect\")}}class I extends Event{constructor(){super(\"webRtcConnecting\")}}class U extends Event{constructor(){super(\"webRtcConnected\")}}class G extends Event{constructor(){super(\"webRtcFailed\")}}class B extends Event{constructor(e){super(\"webRtcDisconnected\"),this.data=e}}class z extends Event{constructor(e){super(\"dataChannelOpen\"),this.data=e}}class _ extends Event{constructor(e){super(\"dataChannelClose\"),this.data=e}}class W extends Event{constructor(e){super(\"dataChannelError\"),this.data=e}}class H extends Event{constructor(){super(\"videoInitialized\")}}class V extends Event{constructor(){super(\"streamLoading\")}}class N extends Event{constructor(){super(\"streamConnect\")}}class K extends Event{constructor(){super(\"streamDisconnect\")}}class Q extends Event{constructor(){super(\"streamReconnect\")}}class q extends Event{constructor(e){super(\"playStreamError\"),this.data=e}}class $ extends Event{constructor(){super(\"playStream\")}}class X extends Event{constructor(e){super(\"playStreamRejected\"),this.data=e}}class J extends Event{constructor(e){super(\"loadFreezeFrame\"),this.data=e}}class j extends Event{constructor(){super(\"hideFreezeFrame\")}}class Y extends Event{constructor(e){super(\"statsReceived\"),this.data=e}}class Z extends Event{constructor(e){super(\"streamerListMessage\"),this.data=e}}class ee extends Event{constructor(e){super(\"StreamerIDChangedMessage\"),this.data=e}}class te extends Event{constructor(e){super(\"latencyTestResult\"),this.data=e}}class se extends Event{constructor(e){super(\"dataChannelLatencyTestResponse\"),this.data=e}}class ne extends Event{constructor(e){super(\"dataChannelLatencyTestResult\"),this.data=e}}class re extends Event{constructor(e){super(\"initialSettings\"),this.data=e}}class ie extends Event{constructor(e){super(\"settingsChanged\"),this.data=e}}class ae extends Event{constructor(){super(\"xrSessionStarted\")}}class oe extends Event{constructor(){super(\"xrSessionEnded\")}}class le extends Event{constructor(e){super(\"xrFrame\"),this.data=e}}class de extends Event{constructor(e){super(\"playerCount\"),this.data=e}}class ce extends Event{constructor(){super(\"webRtcTCPRelayDetected\")}}class he extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class ge{}ge.AutoConnect=\"AutoConnect\",ge.AutoPlayVideo=\"AutoPlayVideo\",ge.AFKDetection=\"TimeoutIfIdle\",ge.BrowserSendOffer=\"OfferToReceive\",ge.HoveringMouseMode=\"HoveringMouse\",ge.ForceMonoAudio=\"ForceMonoAudio\",ge.ForceTURN=\"ForceTURN\",ge.FakeMouseWithTouches=\"FakeMouseWithTouches\",ge.IsQualityController=\"ControlsQuality\",ge.MatchViewportResolution=\"MatchViewportRes\",ge.StartVideoMuted=\"StartVideoMuted\",ge.SuppressBrowserKeys=\"SuppressBrowserKeys\",ge.UseMic=\"UseMic\",ge.KeyboardInput=\"KeyboardInput\",ge.MouseInput=\"MouseInput\",ge.TouchInput=\"TouchInput\",ge.GamepadInput=\"GamepadInput\",ge.XRControllerInput=\"XRControllerInput\",ge.WaitForStreamer=\"WaitForStreamer\";const ue=e=>Object.getOwnPropertyNames(ge).some((t=>ge[t]===e));class me{}me.AFKTimeoutSecs=\"AFKTimeout\",me.MinQP=\"MinQP\",me.MaxQP=\"MaxQP\",me.WebRTCFPS=\"WebRTCFPS\",me.WebRTCMinBitrate=\"WebRTCMinBitrate\",me.WebRTCMaxBitrate=\"WebRTCMaxBitrate\",me.MaxReconnectAttempts=\"MaxReconnectAttempts\",me.StreamerAutoJoinInterval=\"StreamerAutoJoinInterval\";const pe=e=>Object.getOwnPropertyNames(me).some((t=>me[t]===e));class Se{}Se.SignallingServerUrl=\"ss\";const ve=e=>Object.getOwnPropertyNames(Se).some((t=>Se[t]===e));class Ce{}Ce.PreferredCodec=\"PreferredCodec\",Ce.StreamerId=\"StreamerId\";const fe=e=>Object.getOwnPropertyNames(Ce).some((t=>Ce[t]===e));class Te{constructor(e={}){this.flags=new Map,this.numericParameters=new Map,this.textParameters=new Map,this.optionParameters=new Map;const{initialSettings:t,useUrlParams:s}=e;this._useUrlParams=!!s,this.populateDefaultSettings(this._useUrlParams,t)}get useUrlParams(){return this._useUrlParams}populateDefaultSettings(e,t){this.textParameters.set(Se.SignallingServerUrl,new R(Se.SignallingServerUrl,\"Signalling url\",\"Url of the signalling server\",t&&t.hasOwnProperty(Se.SignallingServerUrl)?t[Se.SignallingServerUrl]:(\"https:\"===location.protocol?\"wss://\":\"ws://\")+window.location.hostname+(\"80\"===window.location.port||\"\"===window.location.port?\"\":`:${window.location.port}`),e)),this.optionParameters.set(Ce.StreamerId,new P(Ce.StreamerId,\"Streamer ID\",\"The ID of the streamer to stream.\",t&&t.hasOwnProperty(Ce.StreamerId)?t[Ce.StreamerId]:\"\",[],e)),this.optionParameters.set(Ce.PreferredCodec,new P(Ce.PreferredCodec,\"Preferred Codec\",\"The preferred codec to be used during codec negotiation\",\"H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\",t&&t.hasOwnProperty(Ce.PreferredCodec)?[t[Ce.PreferredCodec]]:function(){const e=[];if(!RTCRtpReceiver.getCapabilities)return e.push(\"Only available on Chrome\"),e;const t=/(VP\\d|H26\\d|AV1).*/;return RTCRtpReceiver.getCapabilities(\"video\").codecs.forEach((s=>{const n=s.mimeType.split(\"/\")[1]+\" \"+(s.sdpFmtpLine||\"\");null!==t.exec(n)&&e.push(n)})),e}(),e)),this.flags.set(ge.AutoConnect,new w(ge.AutoConnect,\"Auto connect to stream\",\"Whether we should attempt to auto connect to the signalling server or show a click to start prompt.\",!(!t||!t.hasOwnProperty(ge.AutoConnect))&&t[ge.AutoConnect],e)),this.flags.set(ge.AutoPlayVideo,new w(ge.AutoPlayVideo,\"Auto play video\",\"When video is ready automatically start playing it as opposed to showing a play button.\",!t||!t.hasOwnProperty(ge.AutoPlayVideo)||t[ge.AutoPlayVideo],e)),this.flags.set(ge.BrowserSendOffer,new w(ge.BrowserSendOffer,\"Browser send offer\",\"Browser will initiate the WebRTC handshake by sending the offer to the streamer\",!(!t||!t.hasOwnProperty(ge.BrowserSendOffer))&&t[ge.BrowserSendOffer],e)),this.flags.set(ge.UseMic,new w(ge.UseMic,\"Use microphone\",\"Make browser request microphone access and open an input audio track.\",!(!t||!t.hasOwnProperty(ge.UseMic))&&t[ge.UseMic],e)),this.flags.set(ge.StartVideoMuted,new w(ge.StartVideoMuted,\"Start video muted\",\"Video will start muted if true.\",!(!t||!t.hasOwnProperty(ge.StartVideoMuted))&&t[ge.StartVideoMuted],e)),this.flags.set(ge.SuppressBrowserKeys,new w(ge.SuppressBrowserKeys,\"Suppress browser keys\",\"Suppress certain browser keys that we use in UE, for example F5 to show shader complexity instead of refresh the page.\",!t||!t.hasOwnProperty(ge.SuppressBrowserKeys)||t[ge.SuppressBrowserKeys],e)),this.flags.set(ge.IsQualityController,new w(ge.IsQualityController,\"Is quality controller?\",\"True if this peer controls stream quality\",!t||!t.hasOwnProperty(ge.IsQualityController)||t[ge.IsQualityController],e)),this.flags.set(ge.ForceMonoAudio,new w(ge.ForceMonoAudio,\"Force mono audio\",\"Force browser to request mono audio in the SDP\",!(!t||!t.hasOwnProperty(ge.ForceMonoAudio))&&t[ge.ForceMonoAudio],e)),this.flags.set(ge.ForceTURN,new w(ge.ForceTURN,\"Force TURN\",\"Only generate TURN/Relayed ICE candidates.\",!(!t||!t.hasOwnProperty(ge.ForceTURN))&&t[ge.ForceTURN],e)),this.flags.set(ge.AFKDetection,new w(ge.AFKDetection,\"AFK if idle\",\"Timeout the experience if user is AFK for a period.\",!(!t||!t.hasOwnProperty(ge.AFKDetection))&&t[ge.AFKDetection],e)),this.flags.set(ge.MatchViewportResolution,new w(ge.MatchViewportResolution,\"Match viewport resolution\",\"Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.\",!(!t||!t.hasOwnProperty(ge.MatchViewportResolution))&&t[ge.MatchViewportResolution],e)),this.flags.set(ge.HoveringMouseMode,new w(ge.HoveringMouseMode,\"Control Scheme: Locked Mouse\",\"Either locked mouse, where the pointer is consumed by the video and locked to it, or hovering mouse, where the mouse is not consumed.\",!(!t||!t.hasOwnProperty(ge.HoveringMouseMode))&&t[ge.HoveringMouseMode],e,((e,t)=>{t.label=`Control Scheme: ${e?\"Hovering\":\"Locked\"} Mouse`}))),this.flags.set(ge.FakeMouseWithTouches,new w(ge.FakeMouseWithTouches,\"Fake mouse with touches\",\"A single finger touch is converted into a mouse event. This allows a non-touch application to be controlled partially via a touch device.\",!t||!t.hasOwnProperty(ge.FakeMouseWithTouches)||t[ge.FakeMouseWithTouches],e)),this.flags.set(ge.KeyboardInput,new w(ge.KeyboardInput,\"Keyboard input\",\"If enabled, send keyboard events to streamer\",!t||!t.hasOwnProperty(ge.KeyboardInput)||t[ge.KeyboardInput],e)),this.flags.set(ge.MouseInput,new w(ge.MouseInput,\"Mouse input\",\"If enabled, send mouse events to streamer\",!t||!t.hasOwnProperty(ge.MouseInput)||t[ge.MouseInput],e)),this.flags.set(ge.TouchInput,new w(ge.TouchInput,\"Touch input\",\"If enabled, send touch events to streamer\",!t||!t.hasOwnProperty(ge.TouchInput)||t[ge.TouchInput],e)),this.flags.set(ge.GamepadInput,new w(ge.GamepadInput,\"Gamepad input\",\"If enabled, send gamepad events to streamer\",!t||!t.hasOwnProperty(ge.GamepadInput)||t[ge.GamepadInput],e)),this.flags.set(ge.XRControllerInput,new w(ge.XRControllerInput,\"XR controller input\",\"If enabled, send XR controller events to streamer\",!t||!t.hasOwnProperty(ge.XRControllerInput)||t[ge.XRControllerInput],e)),this.flags.set(ge.WaitForStreamer,new w(ge.WaitForStreamer,\"Wait for streamer\",\"Will continue trying to connect to the first streamer available.\",!t||!t.hasOwnProperty(ge.WaitForStreamer)||t[ge.WaitForStreamer],e)),this.numericParameters.set(me.AFKTimeoutSecs,new b(me.AFKTimeoutSecs,\"AFK timeout\",\"The time (in seconds) it takes for the application to time out if AFK timeout is enabled.\",0,600,t&&t.hasOwnProperty(me.AFKTimeoutSecs)?t[me.AFKTimeoutSecs]:120,e)),this.numericParameters.set(me.MaxReconnectAttempts,new b(me.MaxReconnectAttempts,\"Max Reconnects\",\"Maximum number of reconnects the application will attempt when a streamer disconnects.\",0,999,t&&t.hasOwnProperty(me.MaxReconnectAttempts)?t[me.MaxReconnectAttempts]:3,e)),this.numericParameters.set(me.MinQP,new b(me.MinQP,\"Min QP\",\"The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.\",0,51,t&&t.hasOwnProperty(me.MinQP)?t[me.MinQP]:0,e)),this.numericParameters.set(me.MaxQP,new b(me.MaxQP,\"Max QP\",\"The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.\",0,51,t&&t.hasOwnProperty(me.MaxQP)?t[me.MaxQP]:51,e)),this.numericParameters.set(me.WebRTCFPS,new b(me.WebRTCFPS,\"Max FPS\",\"The maximum FPS that WebRTC will try to transmit frames at.\",1,999,t&&t.hasOwnProperty(me.WebRTCFPS)?t[me.WebRTCFPS]:60,e)),this.numericParameters.set(me.WebRTCMinBitrate,new b(me.WebRTCMinBitrate,\"Min Bitrate (kbps)\",\"The minimum bitrate that WebRTC should use.\",0,5e5,t&&t.hasOwnProperty(me.WebRTCMinBitrate)?t[me.WebRTCMinBitrate]:0,e)),this.numericParameters.set(me.WebRTCMaxBitrate,new b(me.WebRTCMaxBitrate,\"Max Bitrate (kbps)\",\"The maximum bitrate that WebRTC should use.\",0,5e5,t&&t.hasOwnProperty(me.WebRTCMaxBitrate)?t[me.WebRTCMaxBitrate]:0,e)),this.numericParameters.set(me.StreamerAutoJoinInterval,new b(me.StreamerAutoJoinInterval,\"Streamer Auto Join Interval (ms)\",\"Delay between retries when waiting for an available streamer.\",500,9e5,t&&t.hasOwnProperty(me.StreamerAutoJoinInterval)?t[me.StreamerAutoJoinInterval]:3e3,e))}_addOnNumericSettingChangedListener(e,t){this.numericParameters.has(e)&&this.numericParameters.get(e).addOnChangedListener(t)}_addOnOptionSettingChangedListener(e,t){this.optionParameters.has(e)&&this.optionParameters.get(e).addOnChangedListener(t)}getNumericSettingValue(e){if(this.numericParameters.has(e))return this.numericParameters.get(e).number;throw new Error(`There is no numeric setting with the id of ${e}`)}getTextSettingValue(e){if(this.textParameters.has(e))return this.textParameters.get(e).value;throw new Error(`There is no numeric setting with the id of ${e}`)}setNumericSetting(e,t){if(!this.numericParameters.has(e))throw new Error(`There is no numeric setting with the id of ${e}`);this.numericParameters.get(e).number=t}_addOnSettingChangedListener(e,t){this.flags.has(e)&&(this.flags.get(e).onChange=t)}_addOnTextSettingChangedListener(e,t){this.textParameters.has(e)&&(this.textParameters.get(e).onChange=t)}getSettingOption(e){return this.optionParameters.get(e)}isFlagEnabled(e){return this.flags.get(e).flag}setFlagEnabled(e,t){this.flags.has(e)?this.flags.get(e).flag=t:i.Warning(i.GetStackTrace(),`Cannot toggle flag called ${e} - it does not exist in the Config.flags map.`)}setTextSetting(e,t){this.textParameters.has(e)?this.textParameters.get(e).text=t:i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.textParameters map.`)}setOptionSettingOptions(e,t){this.optionParameters.has(e)?this.optionParameters.get(e).options=t:i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.optionParameters map.`)}setOptionSettingValue(e,t){if(this.optionParameters.has(e)){const s=this.optionParameters.get(e),n=s.options;n.includes(t)||(n.push(t),s.options=n),s.selected=t}else i.Warning(i.GetStackTrace(),`Cannot set text setting called ${e} - it does not exist in the Config.enumParameters map.`)}setFlagLabel(e,t){this.flags.has(e)?this.flags.get(e).label=t:i.Warning(i.GetStackTrace(),`Cannot set label for flag called ${e} - it does not exist in the Config.flags map.`)}setSettings(e){for(const t of Object.keys(e))ue(t)?this.setFlagEnabled(t,e[t]):pe(t)?this.setNumericSetting(t,e[t]):ve(t)?this.setTextSetting(t,e[t]):fe(t)&&this.setOptionSettingValue(t,e[t])}getSettings(){const e={};for(const[t,s]of this.flags.entries())e[t]=s.flag;for(const[t,s]of this.numericParameters.entries())e[t]=s.number;for(const[t,s]of this.textParameters.entries())e[t]=s.text;for(const[t,s]of this.optionParameters.entries())e[t]=s.selected;return e}getFlags(){return Array.from(this.flags.values())}getTextSettings(){return Array.from(this.textParameters.values())}getNumericSettings(){return Array.from(this.numericParameters.values())}getOptionSettings(){return Array.from(this.optionParameters.values())}_registerOnChangeEvents(e){for(const t of this.flags.keys()){const s=this.flags.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new ie({id:s.id,type:\"flag\",value:t,target:s})))}for(const t of this.numericParameters.keys()){const s=this.numericParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new ie({id:s.id,type:\"number\",value:t,target:s})))}for(const t of this.textParameters.keys()){const s=this.textParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new ie({id:s.id,type:\"text\",value:t,target:s})))}for(const t of this.optionParameters.keys()){const s=this.optionParameters.get(t);s&&(s.onChangeEmit=t=>e.dispatchEvent(new ie({id:s.id,type:\"option\",value:t,target:s})))}}}var Ee;!function(e){e[e.LockedMouse=0]=\"LockedMouse\",e[e.HoveringMouse=1]=\"HoveringMouse\"}(Ee||(Ee={}));class ye{constructor(e,t,s){this.closeTimeout=10,this.active=!1,this.countdownActive=!1,this.warnTimer=void 0,this.countDown=0,this.countDownTimer=void 0,this.config=e,this.pixelStreaming=t,this.onDismissAfk=s,this.onAFKTimedOutCallback=()=>{console.log(\"AFK timed out, did you want to override this callback?\")}}onAfkClick(){clearInterval(this.countDownTimer),(this.active||this.countdownActive)&&(this.startAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new x))}startAfkWarningTimer(){this.config.getNumericSettingValue(me.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(ge.AFKDetection)?this.active=!0:this.active=!1,this.resetAfkWarningTimer()}stopAfkWarningTimer(){this.active=!1,this.countdownActive=!1,clearTimeout(this.warnTimer),clearInterval(this.countDownTimer)}pauseAfkWarningTimer(){this.active=!1}resetAfkWarningTimer(){this.active&&this.config.isFlagEnabled(ge.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(me.AFKTimeoutSecs)))}activateAfkEvent(){this.pauseAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown,dismissAfk:this.onDismissAfk})),this.countDown=this.closeTimeout,this.countdownActive=!0,this.pixelStreaming.dispatchEvent(new L({countDown:this.countDown})),this.config.isFlagEnabled(ge.HoveringMouseMode)||document.exitPointerLock&&document.exitPointerLock(),this.countDownTimer=setInterval((()=>{this.countDown--,0==this.countDown?(this.pixelStreaming.dispatchEvent(new A),this.onAFKTimedOutCallback(),i.Log(i.GetStackTrace(),\"You have been disconnected due to inactivity\"),this.stopAfkWarningTimer()):this.pixelStreaming.dispatchEvent(new L({countDown:this.countDown}))}),1e3)}}class Me{constructor(){this.isReceivingFreezeFrame=!1}getDataChannelInstance(){return this}createDataChannel(e,t,s){this.peerConnection=e,this.label=t,this.datachannelOptions=s,null==s&&(this.datachannelOptions={},this.datachannelOptions.ordered=!0),this.dataChannel=this.peerConnection.createDataChannel(this.label,this.datachannelOptions),this.setupDataChannel()}setupDataChannel(){this.dataChannel.binaryType=\"arraybuffer\",this.dataChannel.onopen=e=>this.handleOnOpen(e),this.dataChannel.onclose=e=>this.handleOnClose(e),this.dataChannel.onmessage=e=>this.handleOnMessage(e),this.dataChannel.onerror=e=>this.handleOnError(e)}handleOnOpen(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) opened.`,7),this.onOpen(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}handleOnClose(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) closed.`,7),this.onClose(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}handleOnMessage(e){i.Log(i.GetStackTrace(),`Data Channel (${this.label}) message: ${e}`,8)}handleOnError(e){var t;i.Log(i.GetStackTrace(),`Data Channel (${this.label}) error: ${e}`,7),this.onError(null===(t=this.dataChannel)||void 0===t?void 0:t.label,e)}onOpen(e,t){}onClose(e,t){}onError(e,t){}}class we{}class be{}class Re{}class Pe{}class ke{}class Le{}class xe{}class Ae{constructor(){this.inboundVideoStats=new be,this.inboundAudioStats=new we,this.DataChannelStats=new Re,this.outBoundVideoStats=new ke,this.sessionStats=new Le,this.streamStats=new xe,this.codecs=new Map}processStats(e){this.localCandidates=new Array,this.remoteCandidates=new Array,this.candidatePairs=new Array,e.forEach((e=>{switch(e.type){case\"candidate-pair\":this.handleCandidatePair(e);break;case\"certificate\":case\"media-source\":case\"media-playout\":case\"outbound-rtp\":case\"peer-connection\":case\"remote-inbound-rtp\":break;case\"codec\":this.handleCodec(e);break;case\"data-channel\":this.handleDataChannel(e);break;case\"inbound-rtp\":this.handleInBoundRTP(e);break;case\"local-candidate\":this.handleLocalCandidate(e);break;case\"remote-candidate\":this.handleRemoteCandidate(e);break;case\"remote-outbound-rtp\":this.handleRemoteOutBound(e);break;case\"track\":this.handleTrack(e);break;case\"transport\":this.handleTransport(e);break;case\"stream\":this.handleStream(e);break;default:i.Error(i.GetStackTrace(),\"unhandled Stat Type\"),i.Log(i.GetStackTrace(),e)}}))}handleStream(e){this.streamStats=e}handleCandidatePair(e){this.candidatePairs.push(e)}handleDataChannel(e){this.DataChannelStats.bytesReceived=e.bytesReceived,this.DataChannelStats.bytesSent=e.bytesSent,this.DataChannelStats.dataChannelIdentifier=e.dataChannelIdentifier,this.DataChannelStats.id=e.id,this.DataChannelStats.label=e.label,this.DataChannelStats.messagesReceived=e.messagesReceived,this.DataChannelStats.messagesSent=e.messagesSent,this.DataChannelStats.protocol=e.protocol,this.DataChannelStats.state=e.state,this.DataChannelStats.timestamp=e.timestamp}handleLocalCandidate(e){const t=new Pe;t.label=\"local-candidate\",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.candidateType=e.candidateType,t.id=e.id,t.relayProtocol=e.relayProtocol,t.transportId=e.transportId,this.localCandidates.push(t)}handleRemoteCandidate(e){const t=new Pe;t.label=\"remote-candidate\",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.id=e.id,t.candidateType=e.candidateType,t.relayProtocol=e.relayProtocol,t.transportId=e.transportId,this.remoteCandidates.push(t)}handleInBoundRTP(e){switch(e.kind){case\"video\":this.inboundVideoStats=e,null!=this.lastVideoStats&&(this.inboundVideoStats.bitrate=8*(this.inboundVideoStats.bytesReceived-this.lastVideoStats.bytesReceived)/(this.inboundVideoStats.timestamp-this.lastVideoStats.timestamp),this.inboundVideoStats.bitrate=Math.floor(this.inboundVideoStats.bitrate)),this.lastVideoStats=Object.assign({},this.inboundVideoStats);break;case\"audio\":this.inboundAudioStats=e,null!=this.lastAudioStats&&(this.inboundAudioStats.bitrate=8*(this.inboundAudioStats.bytesReceived-this.lastAudioStats.bytesReceived)/(this.inboundAudioStats.timestamp-this.lastAudioStats.timestamp),this.inboundAudioStats.bitrate=Math.floor(this.inboundAudioStats.bitrate)),this.lastAudioStats=Object.assign({},this.inboundAudioStats);break;default:i.Log(i.GetStackTrace(),\"Kind is not handled\")}}handleRemoteOutBound(e){\"video\"===e.kind&&(this.outBoundVideoStats.bytesSent=e.bytesSent,this.outBoundVideoStats.id=e.id,this.outBoundVideoStats.localId=e.localId,this.outBoundVideoStats.packetsSent=e.packetsSent,this.outBoundVideoStats.remoteTimestamp=e.remoteTimestamp,this.outBoundVideoStats.timestamp=e.timestamp)}handleTrack(e){\"track\"!==e.type||\"video_label\"!==e.trackIdentifier&&\"video\"!==e.kind||(this.inboundVideoStats.framesDropped=e.framesDropped,this.inboundVideoStats.framesReceived=e.framesReceived,this.inboundVideoStats.frameHeight=e.frameHeight,this.inboundVideoStats.frameWidth=e.frameWidth)}handleTransport(e){this.transportStats=e}handleCodec(e){const t=e.id,s=`${e.mimeType.replace(\"video/\",\"\").replace(\"audio/\",\"\")}${e.sdpFmtpLine?` ${e.sdpFmtpLine}`:\"\"}`;this.codecs.set(t,s)}handleSessionStatistics(e,t,s){const n=Date.now()-e;this.sessionStats.runTime=new Date(n).toISOString().substr(11,8).toString();const r=null===t?\"Not sent yet\":t?\"true\":\"false\";this.sessionStats.controlsStreamInput=r,this.sessionStats.videoEncoderAvgQP=s}isNumber(e){return\"number\"==typeof e&&isFinite(e)}getActiveCandidatePair(){return this.transportStats?this.candidatePairs.find((e=>e.id===this.transportStats.selectedCandidatePairId),null):this.candidatePairs.find((e=>e.selected),null)}}const Fe=(De={parseRtpParameters:()=>e.parseRtpParameters,splitSections:()=>e.splitSections},Oe={},n.d(Oe,De),Oe);var De,Oe;class Ie{static isVideoTransciever(e){return this.canTransceiverReceiveVideo(e)||this.canTransceiverSendVideo(e)}static canTransceiverReceiveVideo(e){return!!e&&(\"sendrecv\"===e.direction||\"recvonly\"===e.direction)&&e.receiver&&e.receiver.track&&\"video\"===e.receiver.track.kind}static canTransceiverSendVideo(e){return!!e&&(\"sendrecv\"===e.direction||\"sendonly\"===e.direction)&&e.sender&&e.sender.track&&\"video\"===e.sender.track.kind}static isAudioTransciever(e){return this.canTransceiverReceiveAudio(e)||this.canTransceiverSendAudio(e)}static canTransceiverReceiveAudio(e){return!!e&&(\"sendrecv\"===e.direction||\"recvonly\"===e.direction)&&e.receiver&&e.receiver.track&&\"audio\"===e.receiver.track.kind}static canTransceiverSendAudio(e){return!!e&&(\"sendrecv\"===e.direction||\"sendonly\"===e.direction)&&e.sender&&e.sender.track&&\"audio\"===e.sender.track.kind}}var Ue,Ge,Be=function(e,t,s,n){return new(s||(s=Promise))((function(r,i){function a(e){try{l(n.next(e))}catch(e){i(e)}}function o(e){try{l(n.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}l((n=n.apply(e,t||[])).next())}))};class ze{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(e,t){this.config.isFlagEnabled(ge.ForceTURN)&&(e.iceTransportPolicy=\"relay\",i.Log(i.GetStackTrace(),\"Forcing TURN usage by setting ICE Transport Policy in peer connection config.\")),this.peerConnection=new RTCPeerConnection(e),this.peerConnection.onsignalingstatechange=e=>this.handleSignalStateChange(e),this.peerConnection.oniceconnectionstatechange=e=>this.handleIceConnectionStateChange(e),this.peerConnection.onicegatheringstatechange=e=>this.handleIceGatheringStateChange(e),this.peerConnection.ontrack=e=>this.handleOnTrack(e),this.peerConnection.onicecandidate=e=>this.handleIceCandidate(e),this.peerConnection.ondatachannel=e=>this.handleDataChannel(e),this.aggregatedStats=new Ae,this.preferredCodec=t,this.updateCodecSelection=!0}createOffer(e,t){return Be(this,void 0,void 0,(function*(){i.Log(i.GetStackTrace(),\"Create Offer\",6);const s=\"localhost\"===location.hostname||\"127.0.0.1\"===location.hostname,n=\"https:\"===location.protocol;let r=t.isFlagEnabled(ge.UseMic);!r||s||n||(r=!1,i.Error(i.GetStackTrace(),\"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access.\"),i.Error(i.GetStackTrace(),\"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'\")),this.setupTransceiversAsync(r).finally((()=>{var t;null===(t=this.peerConnection)||void 0===t||t.createOffer(e).then((e=>{var t;this.showTextOverlayConnecting(),e.sdp=this.mungeSDP(e.sdp,r),null===(t=this.peerConnection)||void 0===t||t.setLocalDescription(e),this.onSendWebRTCOffer(e)})).catch((()=>{this.showTextOverlaySetupFailure()}))}))}))}receiveOffer(e,t){var s;return Be(this,void 0,void 0,(function*(){i.Log(i.GetStackTrace(),\"Receive Offer\",6),null===(s=this.peerConnection)||void 0===s||s.setRemoteDescription(e).then((()=>{const e=\"localhost\"===location.hostname||\"127.0.0.1\"===location.hostname,s=\"https:\"===location.protocol;let n=t.isFlagEnabled(ge.UseMic);!n||e||s||(n=!1,i.Error(i.GetStackTrace(),\"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access.\"),i.Error(i.GetStackTrace(),\"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'\")),this.setupTransceiversAsync(n).finally((()=>{var e;null===(e=this.peerConnection)||void 0===e||e.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,n),null===(t=this.peerConnection)||void 0===t?void 0:t.setLocalDescription(e)})).then((()=>{var e;this.onSendWebRTCAnswer(null===(e=this.peerConnection)||void 0===e?void 0:e.currentLocalDescription)})).catch((()=>{i.Error(i.GetStackTrace(),\"createAnswer() failed\")}))}))})),this.config.setOptionSettingOptions(Ce.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(Ce.PreferredCodec).options.includes(e))))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(Ce.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(Ce.PreferredCodec).options.includes(e))))}generateStats(){var e;null===(e=this.peerConnection)||void 0===e||e.getStats(null).then((e=>{this.aggregatedStats.processStats(e),this.onVideoStats(this.aggregatedStats),this.updateCodecSelection&&this.aggregatedStats.inboundVideoStats.codecId&&this.config.setOptionSettingValue(Ce.PreferredCodec,this.aggregatedStats.codecs.get(this.aggregatedStats.inboundVideoStats.codecId))}))}close(){this.peerConnection&&(this.peerConnection.close(),this.peerConnection=null)}mungeSDP(e,t){let s=e.replace(/(a=fmtp:\\d+ .*level-asymmetry-allowed=.*)\\r\\n/gm,\"$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\\r\\n\"),n=\"maxaveragebitrate=510000;\";return t&&(n+=\"sprop-maxcapturerate=48000;\"),n+=this.config.isFlagEnabled(ge.ForceMonoAudio)?\"stereo=0;\":\"stereo=1;\",n+=\"useinbandfec=1\",s=s.replace(\"useinbandfec=1\",n),s}handleOnIce(e){var t;i.Log(i.GetStackTrace(),\"peerconnection handleOnIce\",6),this.config.isFlagEnabled(ge.ForceTURN)&&e.candidate.indexOf(\"relay\")<0?i.Info(i.GetStackTrace(),`Dropping candidate because it was not TURN relay. | Type= ${e.type} | Protocol= ${e.protocol} | Address=${e.address} | Port=${e.port} |`,6):null===(t=this.peerConnection)||void 0===t||t.addIceCandidate(e)}handleSignalStateChange(e){i.Log(i.GetStackTrace(),\"signaling state change: \"+e,6)}handleIceConnectionStateChange(e){i.Log(i.GetStackTrace(),\"ice connection state change: \"+e,6),this.onIceConnectionStateChange(e)}handleIceGatheringStateChange(e){i.Log(i.GetStackTrace(),\"ice gathering state change: \"+JSON.stringify(e),6)}handleOnTrack(e){this.onTrack(e)}handleIceCandidate(e){this.onPeerIceCandidate(e)}handleDataChannel(e){this.onDataChannel(e)}onTrack(e){}onIceConnectionStateChange(e){}onPeerIceCandidate(e){}onDataChannel(e){}setupTransceiversAsync(e){var t,s,n,r,i,a,o,l,d;return Be(this,void 0,void 0,(function*(){const c=(null===(t=this.peerConnection)||void 0===t?void 0:t.getTransceivers().length)>0;if(null===(s=this.peerConnection)||void 0===s||s.addTransceiver(\"video\",{direction:\"recvonly\"}),RTCRtpReceiver.getCapabilities&&\"\"!=this.preferredCodec)for(const e of null!==(r=null===(n=this.peerConnection)||void 0===n?void 0:n.getTransceivers())&&void 0!==r?r:[])if(e&&e.receiver&&e.receiver.track&&\"video\"===e.receiver.track.kind&&e.setCodecPreferences){const t=this.preferredCodec.split(\" \"),s=[{mimeType:\"video/\"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:\"\"}];this.config.getSettingOption(Ce.PreferredCodec).options.filter((e=>e!=this.preferredCodec)).forEach((e=>{const t=e.split(\" \");s.push({mimeType:\"video/\"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:\"\"})}));for(const e of s)\"\"===e.sdpFmtpLine&&delete e.sdpFmtpLine;e.setCodecPreferences(s)}if(e){const e={video:!1,audio:{autoGainControl:!1,channelCount:1,echoCancellation:!1,latency:0,noiseSuppression:!1,sampleRate:48e3,sampleSize:16,volume:1}},t=yield navigator.mediaDevices.getUserMedia(e);if(t)if(c){for(const e of null!==(o=null===(a=this.peerConnection)||void 0===a?void 0:a.getTransceivers())&&void 0!==o?o:[])if(Ie.canTransceiverReceiveAudio(e))for(const s of t.getTracks())s.kind&&\"audio\"==s.kind&&(e.sender.replaceTrack(s),e.direction=\"sendrecv\")}else for(const e of t.getTracks())e.kind&&\"audio\"==e.kind&&(null===(l=this.peerConnection)||void 0===l||l.addTransceiver(e,{direction:\"sendrecv\"}));else null===(d=this.peerConnection)||void 0===d||d.addTransceiver(\"audio\",{direction:\"recvonly\"})}else null===(i=this.peerConnection)||void 0===i||i.addTransceiver(\"audio\",{direction:\"recvonly\"})}))}onVideoStats(e){}onSendWebRTCOffer(e){}onSendWebRTCAnswer(e){}showTextOverlayConnecting(){}showTextOverlaySetupFailure(){}parseAvailableCodecs(e){if(!RTCRtpReceiver.getCapabilities)return[\"Only available on Chrome\"];const t=[],s=(0,Fe.splitSections)(e.sdp);return s.shift(),s.forEach((e=>{const{codecs:s}=(0,Fe.parseRtpParameters)(e),n=/(VP\\d|H26\\d|AV1).*/;s.forEach((e=>{const s=e.name+\" \"+Object.keys(e.parameters||{}).map((t=>t+\"=\"+e.parameters[t])).join(\";\");if(null!==n.exec(s)){\"VP9\"==e.name&&(e.parameters={\"profile-id\":\"0\"});const s=e.name+\" \"+Object.keys(e.parameters||{}).map((t=>t+\"=\"+e.parameters[t])).join(\";\");t.push(s)}}))})),t}}class _e{constructor(){this.PixelStreamingSettings=new We,this.EncoderSettings=new He,this.WebRTCSettings=new Ve}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class We{}class He{}class Ve{}class Ne{constructor(){this.ReceiptTimeMs=null,this.TransmissionTimeMs=null,this.PreCaptureTimeMs=null,this.PostCaptureTimeMs=null,this.PreEncodeTimeMs=null,this.PostEncodeTimeMs=null,this.EncodeMs=null,this.CaptureToSendMs=null,this.testStartTimeMs=0,this.browserReceiptTimeMs=0,this.latencyExcludingDecode=0,this.testDuration=0,this.networkLatency=0,this.browserSendLatency=0,this.frameDisplayDeltaTimeMs=0,this.endToEndLatency=0,this.encodeLatency=0}setFrameDisplayDeltaTime(e){0==this.frameDisplayDeltaTimeMs&&(this.frameDisplayDeltaTimeMs=Math.round(e))}processFields(){null!=this.EncodeMs||null==this.PreEncodeTimeMs&&null==this.PostEncodeTimeMs||(i.Log(i.GetStackTrace(),`Setting Encode Ms \\n ${this.PostEncodeTimeMs} \\n ${this.PreEncodeTimeMs}`,6),this.EncodeMs=this.PostEncodeTimeMs-this.PreEncodeTimeMs),null!=this.CaptureToSendMs||null==this.PreCaptureTimeMs&&null==this.PostCaptureTimeMs||(i.Log(i.GetStackTrace(),`Setting CaptureToSendMs Ms \\n ${this.PostCaptureTimeMs} \\n ${this.PreCaptureTimeMs}`,6),this.CaptureToSendMs=this.PostCaptureTimeMs-this.PreCaptureTimeMs)}}class Ke{static setExtensionFromBytes(e,t){t.receiving||(t.mimetype=\"\",t.extension=\"\",t.receiving=!0,t.valid=!1,t.size=0,t.data=[],t.timestampStart=(new Date).getTime(),i.Log(i.GetStackTrace(),\"Received first chunk of file\",6));const s=new TextDecoder(\"utf-16\").decode(e.slice(1));i.Log(i.GetStackTrace(),s,6),t.extension=s}static setMimeTypeFromBytes(e,t){t.receiving||(t.mimetype=\"\",t.extension=\"\",t.receiving=!0,t.valid=!1,t.size=0,t.data=[],t.timestampStart=(new Date).getTime(),i.Log(i.GetStackTrace(),\"Received first chunk of file\",6));const s=new TextDecoder(\"utf-16\").decode(e.slice(1));i.Log(i.GetStackTrace(),s,6),t.mimetype=s}static setContentsFromBytes(e,t){if(!t.receiving)return;t.size=Math.ceil(new DataView(e.slice(1,5).buffer).getInt32(0,!0)/16379);const s=e.slice(5);if(t.data.push(s),i.Log(i.GetStackTrace(),`Received file chunk: ${t.data.length}/${t.size}`,6),t.data.length===t.size){t.receiving=!1,t.valid=!0,i.Log(i.GetStackTrace(),\"Received complete file\",6);const e=(new Date).getTime()-t.timestampStart,s=Math.round(16*t.size*1024/e);i.Log(i.GetStackTrace(),`Average transfer bitrate: ${s}kb/s over ${e/1e3} seconds`,6);const n=new Blob(t.data,{type:t.mimetype}),r=document.createElement(\"a\");r.setAttribute(\"href\",URL.createObjectURL(n)),r.setAttribute(\"download\",`transfer.${t.extension}`),document.body.append(r),r.remove()}else t.data.length>t.size&&(t.receiving=!1,i.Error(i.GetStackTrace(),`Received bigger file than advertised: ${t.data.length}/${t.size}`))}}class Qe{constructor(){this.mimetype=\"\",this.extension=\"\",this.receiving=!1,this.size=0,this.data=[],this.valid=!1}}class qe{}qe.mainButton=0,qe.auxiliaryButton=1,qe.secondaryButton=2,qe.fourthButton=3,qe.fifthButton=4;class $e{}$e.primaryButton=1,$e.secondaryButton=2,$e.auxiliaryButton=4,$e.fourthButton=8,$e.fifthButton=16;class Xe{constructor(){this.unregisterCallbacks=[]}addUnregisterCallback(e){this.unregisterCallbacks.push(e)}unregisterAll(){for(const e of this.unregisterCallbacks)e();this.unregisterCallbacks=[]}}class Je{constructor(e,t,s){this.touchEventListenerTracker=new Xe,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s;const n=e=>this.onTouchStart(e),r=e=>this.onTouchEnd(e),i=e=>this.onTouchMove(e);document.addEventListener(\"touchstart\",n,{passive:!1}),document.addEventListener(\"touchend\",r,{passive:!1}),document.addEventListener(\"touchmove\",i,{passive:!1}),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"touchstart\",n))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"touchend\",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"touchmove\",i)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}setVideoElementParentClientRect(e){this.videoElementParentClientRect=e}onTouchStart(e){if(this.videoElementProvider.isVideoReady()&&e.target===this.videoElementProvider.getVideoElement()){if(null==this.fakeTouchFinger){const t=e.changedTouches[0];this.fakeTouchFinger=new je(t.identifier,t.clientX-this.videoElementParentClientRect.left,t.clientY-this.videoElementParentClientRect.top);const s=this.videoElementProvider.getVideoParentElement(),n=new MouseEvent(\"mouseenter\",t);s.dispatchEvent(n);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(this.fakeTouchFinger.x,this.fakeTouchFinger.y);this.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDown\")([qe.mainButton,r.x,r.y])}e.preventDefault()}}onTouchEnd(e){if(!this.videoElementProvider.isVideoReady()||null==this.fakeTouchFinger)return;const t=this.videoElementProvider.getVideoParentElement(),s=this.toStreamerMessagesProvider.toStreamerHandlers;for(let n=0;nthis.handleOnCompositionEnd(e),t=e=>this.handleOnKeyDown(e),s=e=>this.handleOnKeyUp(e),n=e=>this.handleOnKeyPress(e);document.addEventListener(\"compositionend\",e),document.addEventListener(\"keydown\",t),document.addEventListener(\"keyup\",s),document.addEventListener(\"keypress\",n),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"compositionend\",e))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"keydown\",t))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"keyup\",s))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"keypress\",n)))}unregisterKeyBoardEvents(){this.keyboardEventListenerTracker.unregisterAll()}handleOnKeyDown(e){const t=this.getKeycode(e);t&&229!==t&&(i.Log(i.GetStackTrace(),`key down ${t}, repeat = ${e.repeat}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get(\"KeyDown\")([this.getKeycode(e),e.repeat?1:0]),this.activeKeysProvider.getActiveKeys().push(t),t===Ye.backSpace&&document.dispatchEvent(new KeyboardEvent(\"keypress\",{charCode:Ye.backSpace})),this.config.isFlagEnabled(ge.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(t)&&e.preventDefault())}handleOnKeyUp(e){const t=this.getKeycode(e);t&&(i.Log(i.GetStackTrace(),`key up ${t}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get(\"KeyUp\")([t]),this.config.isFlagEnabled(ge.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(t)&&e.preventDefault())}handleOnKeyPress(e){if(!(\"charCode\"in e))return void i.Warning(i.GetStackTrace(),\"KeyboardEvent.charCode is deprecated in this browser, cannot send key press.\");const t=e.charCode;i.Log(i.GetStackTrace(),`key press ${t}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get(\"KeyPress\")([t])}handleOnCompositionEnd(e){e.data&&e.data.length&&e.data.split(\"\").forEach((e=>{this.handleOnKeyDown(new KeyboardEvent(\"keydown\",{keyCode:e.toUpperCase().charCodeAt(0),charCode:e.charCodeAt(0)})),this.handleOnKeyPress(new KeyboardEvent(\"keypress\",{keyCode:e.toUpperCase().charCodeAt(0),charCode:e.charCodeAt(0)})),this.handleOnKeyUp(new KeyboardEvent(\"keyup\",{keyCode:e.toUpperCase().charCodeAt(0),charCode:e.charCodeAt(0)}))}))}getKeycode(e){if(!(\"keyCode\"in e)){const t=e;return t.code in this.CodeToKeyCode?this.CodeToKeyCode[t.code]:(i.Warning(i.GetStackTrace(),`Keyboard code of ${t.code} is not supported in our mapping, ignoring this key.`),null)}return e.keyCode===Ye.shift&&\"ShiftRight\"===e.code?Ye.rightShift:e.keyCode===Ye.control&&\"ControlRight\"===e.code?Ye.rightControl:e.keyCode===Ye.alt&&\"AltRight\"===e.code?Ye.rightAlt:e.keyCode}isKeyCodeBrowserKey(e){return e>=112&&e<=123||9===e}}class et{constructor(e,t,s){this.x=0,this.y=0,this.updateMouseMovePositionEvent=e=>{this.updateMouseMovePosition(e)},this.mouseEventListenerTracker=new Xe,this.videoElementProvider=e,this.mouseController=t,this.activeKeysProvider=s;const n=this.videoElementProvider.getVideoParentElement();this.x=n.getBoundingClientRect().width/2,this.y=n.getBoundingClientRect().height/2,this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y)}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}lockStateChange(){const e=this.videoElementProvider.getVideoParentElement(),t=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;if(document.pointerLockElement===e||document.mozPointerLockElement===e)i.Log(i.GetStackTrace(),\"Pointer locked\",6),document.addEventListener(\"mousemove\",this.updateMouseMovePositionEvent,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"mousemove\",this.updateMouseMovePositionEvent,!1)));else{i.Log(i.GetStackTrace(),\"The pointer lock status is now unlocked\",6),document.removeEventListener(\"mousemove\",this.updateMouseMovePositionEvent,!1);let e=this.activeKeysProvider.getActiveKeys();const s=new Set(e),n=[];s.forEach((e=>{n[e]})),n.forEach((e=>{t.get(\"KeyUp\")([e])})),e=[]}}updateMouseMovePosition(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers,s=this.videoElementProvider.getVideoParentElement().clientWidth,n=this.videoElementProvider.getVideoParentElement().clientHeight;this.x+=e.movementX,this.y+=e.movementY,this.x>s&&(this.x-=s),this.y>n&&(this.y-=n),this.x<0&&(this.x=s+this.x),this.y<0&&(this.y=n-this.y),this.coord=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(this.x,this.y);const r=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(e.movementX,e.movementY);t.get(\"MouseMove\")([this.coord.x,this.coord.y,r.x,r.y])}handleMouseDown(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDown\")([e.button,this.coord.x,this.coord.y])}handleMouseUp(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseUp\")([e.button,this.coord.x,this.coord.y])}handleMouseWheel(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseWheel\")([e.wheelDelta,this.coord.x,this.coord.y])}handleMouseDouble(e){this.videoElementProvider.isVideoReady()&&this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDouble\")([e.button,this.coord.x,this.coord.y])}handlePressMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.pressMouseButtons(e.buttons,this.x,this.y)}handleReleaseMouseButtons(e){this.videoElementProvider.isVideoReady()&&this.mouseController.releaseMouseButtons(e.buttons,this.x,this.y)}}class tt{constructor(e){this.mouseController=e}unregisterMouseEvents(){}updateMouseMovePosition(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),\"MouseMove\",6);const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY),s=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(e.movementX,e.movementY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseMove\")([t.x,t.y,s.x,s.y]),e.preventDefault()}handleMouseDown(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),\"onMouse Down\",6);const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDown\")([e.button,t.x,t.y]),e.preventDefault()}handleMouseUp(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),\"onMouse Up\",6);const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseUp\")([e.button,t.x,t.y]),e.preventDefault()}handleContextMenu(e){this.mouseController.videoElementProvider.isVideoReady()&&e.preventDefault()}handleMouseWheel(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseWheel\")([e.wheelDelta,t.x,t.y]),e.preventDefault()}handleMouseDouble(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDouble\")([e.button,t.x,t.y])}handlePressMouseButtons(e){this.mouseController.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),\"onMouse press\",6),this.mouseController.pressMouseButtons(e.buttons,e.offsetX,e.offsetY))}handleReleaseMouseButtons(e){this.mouseController.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),\"onMouse release\",6),this.mouseController.releaseMouseButtons(e.buttons,e.offsetX,e.offsetY))}}class st{constructor(e,t,s,n){this.mouseEventListenerTracker=new Xe,this.toStreamerMessagesProvider=e,this.coordinateConverter=s,this.videoElementProvider=t,this.activeKeysProvider=n,this.registerMouseEnterAndLeaveEvents()}unregisterMouseEvents(){this.mouseEventListenerTracker.unregisterAll()}registerLockedMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new et(this.videoElementProvider,e,this.activeKeysProvider);if(t.requestPointerLock=t.requestPointerLock||t.mozRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock,t.requestPointerLock){const e=()=>{t.requestPointerLock()};t.addEventListener(\"click\",e),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"click\",e)))}const n=()=>s.lockStateChange();document.addEventListener(\"pointerlockchange\",n,!1),document.addEventListener(\"mozpointerlockchange\",n,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"pointerlockchange\",n,!1))),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"mozpointerlockchange\",n,!1)));const r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),a=e=>s.handleMouseWheel(e),o=e=>s.handleMouseDouble(e);t.addEventListener(\"mousedown\",r),t.addEventListener(\"mouseup\",i),t.addEventListener(\"wheel\",a),t.addEventListener(\"dblclick\",o),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"mousedown\",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"mouseup\",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"wheel\",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"dblclick\",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents())),this.mouseEventListenerTracker.addUnregisterCallback((()=>{!document.exitPointerLock||document.pointerLockElement!==t&&document.mozPointerLockElement!==t||document.exitPointerLock()}))}registerHoveringMouseEvents(e){const t=this.videoElementProvider.getVideoParentElement(),s=new tt(e),n=e=>s.updateMouseMovePosition(e),r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),a=e=>s.handleContextMenu(e),o=e=>s.handleMouseWheel(e),l=e=>s.handleMouseDouble(e);t.addEventListener(\"mousemove\",n),t.addEventListener(\"mousedown\",r),t.addEventListener(\"mouseup\",i),t.addEventListener(\"contextmenu\",a),t.addEventListener(\"wheel\",o),t.addEventListener(\"dblclick\",l),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"mousemove\",n))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"mousedown\",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"mouseup\",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"contextmenu\",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"wheel\",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener(\"dblclick\",l))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents()))}registerMouseEnterAndLeaveEvents(){const e=this.videoElementProvider.getVideoParentElement(),t=e=>{this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),\"Mouse Entered\",6),this.sendMouseEnter(),this.pressMouseButtons(e.buttons,e.x,e.y))},s=e=>{this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),\"Mouse Left\",6),this.sendMouseLeave(),this.releaseMouseButtons(e.buttons,e.x,e.y))};e.addEventListener(\"mouseenter\",t),e.addEventListener(\"mouseleave\",s),this.mouseEventListenerTracker.addUnregisterCallback((()=>e.removeEventListener(\"mouseenter\",t))),this.mouseEventListenerTracker.addUnregisterCallback((()=>e.removeEventListener(\"mouseleave\",s)))}releaseMouseButtons(e,t,s){const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&$e.primaryButton&&this.sendMouseUp(qe.mainButton,n.x,n.y),e&$e.secondaryButton&&this.sendMouseUp(qe.secondaryButton,n.x,n.y),e&$e.auxiliaryButton&&this.sendMouseUp(qe.auxiliaryButton,n.x,n.y),e&$e.fourthButton&&this.sendMouseUp(qe.fourthButton,n.x,n.y),e&$e.fifthButton&&this.sendMouseUp(qe.fifthButton,n.x,n.y)}pressMouseButtons(e,t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&$e.primaryButton&&this.sendMouseDown(qe.mainButton,n.x,n.y),e&$e.secondaryButton&&this.sendMouseDown(qe.secondaryButton,n.x,n.y),e&$e.auxiliaryButton&&this.sendMouseDown(qe.auxiliaryButton,n.x,n.y),e&$e.fourthButton&&this.sendMouseDown(qe.fourthButton,n.x,n.y),e&$e.fifthButton&&this.sendMouseDown(qe.fifthButton,n.x,n.y)}sendMouseEnter(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseEnter\")()}sendMouseLeave(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseLeave\")()}sendMouseDown(e,t,s){this.videoElementProvider.isVideoReady()&&(i.Log(i.GetStackTrace(),`mouse button ${e} down at (${t}, ${s})`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseDown\")([e,t,s]))}sendMouseUp(e,t,s){if(!this.videoElementProvider.isVideoReady())return;i.Log(i.GetStackTrace(),`mouse button ${e} up at (${t}, ${s})`,6);const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);this.toStreamerMessagesProvider.toStreamerHandlers.get(\"MouseUp\")([e,n.x,n.y])}}class nt{constructor(e,t,s){this.fingers=[9,8,7,6,5,4,3,2,1,0],this.fingerIds=new Map,this.maxByteValue=255,this.touchEventListenerTracker=new Xe,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s,this.videoElementParent=t.getVideoElement();const n=e=>this.onTouchStart(e),r=e=>this.onTouchEnd(e),a=e=>this.onTouchMove(e);this.videoElementParent.addEventListener(\"touchstart\",n),this.videoElementParent.addEventListener(\"touchend\",r),this.videoElementParent.addEventListener(\"touchmove\",a),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener(\"touchstart\",n))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener(\"touchend\",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener(\"touchmove\",a))),i.Log(i.GetStackTrace(),\"Touch Events Registered\",6);const o=e=>{e.preventDefault()};document.addEventListener(\"touchmove\",o),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener(\"touchmove\",o)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}rememberTouch(e){const t=this.fingers.pop();void 0===t&&i.Log(i.GetStackTrace(),\"exhausted touch identifiers\",6),this.fingerIds.set(e.identifier,t)}forgetTouch(e){this.fingers.push(this.fingerIds.get(e.identifier)),this.fingers.sort((function(e,t){return t-e})),this.fingerIds.delete(e.identifier)}onTouchStart(e){if(this.videoElementProvider.isVideoReady()){for(let t=0;t0?o.force:1),c.inRange?1:0]);break;case\"TouchEnd\":n.get(\"TouchEnd\")([a,c.x,c.y,this.fingerIds.get(o.identifier),this.maxByteValue*o.force,c.inRange?1:0]);break;case\"TouchMove\":n.get(\"TouchMove\")([a,c.x,c.y,this.fingerIds.get(o.identifier),this.maxByteValue*(o.force>0?o.force:1),c.inRange?1:0])}}}}class rt{constructor(e){this.gamePadEventListenerTracker=new Xe,this.toStreamerMessagesProvider=e,this.requestAnimationFrame=(window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.requestAnimationFrame).bind(window);const t=window;if(window.addEventListener(\"beforeunload\",(e=>this.onBeforeUnload(e))),\"GamepadEvent\"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener(\"gamepadconnected\",e),window.addEventListener(\"gamepaddisconnected\",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener(\"gamepadconnected\",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener(\"gamepaddisconnected\",t)))}else if(\"WebKitGamepadEvent\"in t){const e=e=>this.gamePadConnectHandler(e),t=e=>this.gamePadDisconnectHandler(e);window.addEventListener(\"webkitgamepadconnected\",e),window.addEventListener(\"webkitgamepaddisconnected\",t),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener(\"webkitgamepadconnected\",e))),this.gamePadEventListenerTracker.addUnregisterCallback((()=>window.removeEventListener(\"webkitgamepaddisconnected\",t)))}if(this.controllers=[],navigator.getGamepads)for(const e of navigator.getGamepads())e&&this.gamePadConnectHandler(new GamepadEvent(\"gamepadconnected\",{gamepad:e}))}unregisterGamePadEvents(){this.gamePadEventListenerTracker.unregisterAll();for(const e of this.controllers)void 0!==e.id&&this.onGamepadDisconnected(e.id);this.controllers=[],this.onGamepadConnected=()=>{},this.onGamepadDisconnected=()=>{}}gamePadConnectHandler(e){i.Log(i.GetStackTrace(),\"Gamepad connect handler\",6);const t=e.gamepad,s={currentState:t,prevState:t,id:void 0};this.controllers.push(s),this.controllers[t.index].currentState=t,this.controllers[t.index].prevState=t,i.Log(i.GetStackTrace(),\"gamepad: \"+t.id+\" connected\",6),window.requestAnimationFrame((()=>this.updateStatus())),this.onGamepadConnected()}gamePadDisconnectHandler(e){i.Log(i.GetStackTrace(),\"Gamepad disconnect handler\",6),i.Log(i.GetStackTrace(),\"gamepad: \"+e.gamepad.id+\" disconnected\",6);const t=this.controllers[e.gamepad.index];delete this.controllers[e.gamepad.index],this.controllers=this.controllers.filter((e=>void 0!==e)),this.onGamepadDisconnected(t.id)}scanGamePads(){const e=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():[];for(let t=0;t0&&this.requestAnimationFrame((()=>this.updateStatus()))}onGamepadResponseReceived(e){for(const t of this.controllers)if(void 0===t.id){t.id=e;break}}onGamepadConnected(){}onGamepadDisconnected(e){}onBeforeUnload(e){for(const e of this.controllers)this.onGamepadDisconnected(e.id)}}!function(e){e[e.RightClusterBottomButton=0]=\"RightClusterBottomButton\",e[e.RightClusterRightButton=1]=\"RightClusterRightButton\",e[e.RightClusterLeftButton=2]=\"RightClusterLeftButton\",e[e.RightClusterTopButton=3]=\"RightClusterTopButton\",e[e.LeftShoulder=4]=\"LeftShoulder\",e[e.RightShoulder=5]=\"RightShoulder\",e[e.LeftTrigger=6]=\"LeftTrigger\",e[e.RightTrigger=7]=\"RightTrigger\",e[e.SelectOrBack=8]=\"SelectOrBack\",e[e.StartOrForward=9]=\"StartOrForward\",e[e.LeftAnalogPress=10]=\"LeftAnalogPress\",e[e.RightAnalogPress=11]=\"RightAnalogPress\",e[e.LeftClusterTopButton=12]=\"LeftClusterTopButton\",e[e.LeftClusterBottomButton=13]=\"LeftClusterBottomButton\",e[e.LeftClusterLeftButton=14]=\"LeftClusterLeftButton\",e[e.LeftClusterRightButton=15]=\"LeftClusterRightButton\",e[e.CentreButton=16]=\"CentreButton\",e[e.LeftStickHorizontal=0]=\"LeftStickHorizontal\",e[e.LeftStickVertical=1]=\"LeftStickVertical\",e[e.RightStickHorizontal=2]=\"RightStickHorizontal\",e[e.RightStickVertical=3]=\"RightStickVertical\"}(Ue||(Ue={}));class it{constructor(e,t,s){this.activeKeys=new at,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s}registerKeyBoard(e){i.Log(i.GetStackTrace(),\"Register Keyboard Events\",7);const t=new Ze(this.toStreamerMessagesProvider,e,this.activeKeys);return t.registerKeyBoardEvents(),t}registerMouse(e){i.Log(i.GetStackTrace(),\"Register Mouse Events\",7);const t=new st(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter,this.activeKeys);switch(e){case Ee.LockedMouse:t.registerLockedMouseEvents(t);break;case Ee.HoveringMouse:t.registerHoveringMouseEvents(t);break;default:i.Info(i.GetStackTrace(),\"unknown Control Scheme Type Defaulting to Locked Mouse Events\"),t.registerLockedMouseEvents(t)}return t}registerTouch(e,t){if(i.Log(i.GetStackTrace(),\"Registering Touch\",6),e){const e=new Je(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter);return e.setVideoElementParentClientRect(t),e}return new nt(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter)}registerGamePad(){return i.Log(i.GetStackTrace(),\"Register Game Pad\",7),new rt(this.toStreamerMessagesProvider)}}class at{constructor(){this.activeKeys=[],this.activeKeys=[]}getActiveKeys(){return this.activeKeys}}class ot{constructor(e,t){this.lastTimeResized=(new Date).getTime(),this.videoElement=document.createElement(\"video\"),this.config=t,this.videoElement.id=\"streamingVideo\",this.videoElement.disablePictureInPicture=!0,this.videoElement.playsInline=!0,this.videoElement.style.width=\"100%\",this.videoElement.style.height=\"100%\",this.videoElement.style.position=\"absolute\",this.videoElement.style.pointerEvents=\"all\",e.appendChild(this.videoElement),this.onResizePlayerCallback=()=>{console.log(\"Resolution changed, restyling player, did you forget to override this function?\")},this.onMatchViewportResolutionCallback=()=>{console.log(\"Resolution changed and match viewport resolution is turned on, did you forget to override this function?\")},this.videoElement.onclick=()=>{null!=this.audioElement&&this.audioElement.paused&&this.audioElement.play(),this.videoElement.paused&&this.videoElement.play()},this.videoElement.onloadedmetadata=()=>{this.onVideoInitialized()},window.addEventListener(\"resize\",(()=>this.resizePlayerStyle()),!0),window.addEventListener(\"orientationchange\",(()=>this.onOrientationChange()))}setAudioElement(e){this.audioElement=e}play(){return this.videoElement.muted=this.config.isFlagEnabled(ge.StartVideoMuted),this.videoElement.autoplay=this.config.isFlagEnabled(ge.AutoPlayVideo),this.videoElement.play()}isPaused(){return this.videoElement.paused}isVideoReady(){return void 0!==this.videoElement.readyState&&this.videoElement.readyState>0}hasVideoSource(){return void 0!==this.videoElement.srcObject&&null!==this.videoElement.srcObject}getVideoElement(){return this.videoElement}getVideoParentElement(){return this.videoElement.parentElement}setVideoEnabled(e){this.videoElement.srcObject.getTracks().forEach((t=>t.enabled=e))}onVideoInitialized(){}onOrientationChange(){clearTimeout(this.orientationChangeTimeout),this.orientationChangeTimeout=window.setTimeout((()=>{this.resizePlayerStyle()}),500)}resizePlayerStyle(){const e=this.getVideoParentElement();e&&(this.updateVideoStreamSize(),e.classList.contains(\"fixed-size\")||this.resizePlayerStyleToFillParentElement(),this.onResizePlayerCallback())}resizePlayerStyleToFillParentElement(){this.getVideoParentElement().setAttribute(\"style\",\"top: 0px; left: 0px; width: 100%; height: 100%; cursor: default;\")}updateVideoStreamSize(){if(this.config.isFlagEnabled(ge.MatchViewportResolution))if((new Date).getTime()-this.lastTimeResized>300){const e=this.getVideoParentElement();if(!e)return;this.onMatchViewportResolutionCallback(e.clientWidth,e.clientHeight),this.lastTimeResized=(new Date).getTime()}else i.Log(i.GetStackTrace(),\"Resizing too often - skipping\",6),clearTimeout(this.resizeTimeoutHandle),this.resizeTimeoutHandle=window.setTimeout((()=>this.updateVideoStreamSize()),100)}}class lt{constructor(){this.toStreamerHandlers=new Map,this.fromStreamerHandlers=new Map,this.toStreamerMessages=new Map,this.fromStreamerMessages=new Map}populateDefaultProtocol(){this.toStreamerMessages.set(\"IFrameRequest\",{id:0,structure:[]}),this.toStreamerMessages.set(\"RequestQualityControl\",{id:1,structure:[]}),this.toStreamerMessages.set(\"FpsRequest\",{id:2,structure:[]}),this.toStreamerMessages.set(\"AverageBitrateRequest\",{id:3,structure:[]}),this.toStreamerMessages.set(\"StartStreaming\",{id:4,structure:[]}),this.toStreamerMessages.set(\"StopStreaming\",{id:5,structure:[]}),this.toStreamerMessages.set(\"LatencyTest\",{id:6,structure:[\"string\"]}),this.toStreamerMessages.set(\"RequestInitialSettings\",{id:7,structure:[]}),this.toStreamerMessages.set(\"TestEcho\",{id:8,structure:[]}),this.toStreamerMessages.set(\"DataChannelLatencyTest\",{id:9,structure:[]}),this.toStreamerMessages.set(\"UIInteraction\",{id:50,structure:[\"string\"]}),this.toStreamerMessages.set(\"Command\",{id:51,structure:[\"string\"]}),this.toStreamerMessages.set(\"KeyDown\",{id:60,structure:[\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"KeyUp\",{id:61,structure:[\"uint8\"]}),this.toStreamerMessages.set(\"KeyPress\",{id:62,structure:[\"uint16\"]}),this.toStreamerMessages.set(\"MouseEnter\",{id:70,structure:[]}),this.toStreamerMessages.set(\"MouseLeave\",{id:71,structure:[]}),this.toStreamerMessages.set(\"MouseDown\",{id:72,structure:[\"uint8\",\"uint16\",\"uint16\"]}),this.toStreamerMessages.set(\"MouseUp\",{id:73,structure:[\"uint8\",\"uint16\",\"uint16\"]}),this.toStreamerMessages.set(\"MouseMove\",{id:74,structure:[\"uint16\",\"uint16\",\"int16\",\"int16\"]}),this.toStreamerMessages.set(\"MouseWheel\",{id:75,structure:[\"int16\",\"uint16\",\"uint16\"]}),this.toStreamerMessages.set(\"MouseDouble\",{id:76,structure:[\"uint8\",\"uint16\",\"uint16\"]}),this.toStreamerMessages.set(\"TouchStart\",{id:80,structure:[\"uint8\",\"uint16\",\"uint16\",\"uint8\",\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"TouchEnd\",{id:81,structure:[\"uint8\",\"uint16\",\"uint16\",\"uint8\",\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"TouchMove\",{id:82,structure:[\"uint8\",\"uint16\",\"uint16\",\"uint8\",\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"GamepadConnected\",{id:93,structure:[]}),this.toStreamerMessages.set(\"GamepadButtonPressed\",{id:90,structure:[\"uint8\",\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"GamepadButtonReleased\",{id:91,structure:[\"uint8\",\"uint8\",\"uint8\"]}),this.toStreamerMessages.set(\"GamepadAnalog\",{id:92,structure:[\"uint8\",\"uint8\",\"double\"]}),this.toStreamerMessages.set(\"GamepadDisconnected\",{id:94,structure:[\"uint8\"]}),this.fromStreamerMessages.set(0,\"QualityControlOwnership\"),this.fromStreamerMessages.set(1,\"Response\"),this.fromStreamerMessages.set(2,\"Command\"),this.fromStreamerMessages.set(3,\"FreezeFrame\"),this.fromStreamerMessages.set(4,\"UnfreezeFrame\"),this.fromStreamerMessages.set(5,\"VideoEncoderAvgQP\"),this.fromStreamerMessages.set(6,\"LatencyTest\"),this.fromStreamerMessages.set(7,\"InitialSettings\"),this.fromStreamerMessages.set(8,\"FileExtension\"),this.fromStreamerMessages.set(9,\"FileMimeType\"),this.fromStreamerMessages.set(10,\"FileContents\"),this.fromStreamerMessages.set(11,\"TestEcho\"),this.fromStreamerMessages.set(12,\"InputControlOwnership\"),this.fromStreamerMessages.set(13,\"GamepadResponse\"),this.fromStreamerMessages.set(14,\"DataChannelLatencyTest\"),this.fromStreamerMessages.set(255,\"Protocol\")}registerMessageHandler(e,t,s){switch(e){case Ge.ToStreamer:this.toStreamerHandlers.set(t,s);break;case Ge.FromStreamer:this.fromStreamerHandlers.set(t,s);break;default:i.Log(i.GetStackTrace(),`Unknown message direction ${e}`)}}}!function(e){e[e.ToStreamer=0]=\"ToStreamer\",e[e.FromStreamer=1]=\"FromStreamer\"}(Ge||(Ge={}));class dt{constructor(){this.responseEventListeners=new Map}addResponseEventListener(e,t){this.responseEventListeners.set(e,t)}removeResponseEventListener(e){this.responseEventListeners.delete(e)}onResponse(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.Response\",6);const t=new TextDecoder(\"utf-16\").decode(e.slice(1));i.Log(i.GetStackTrace(),t,6),this.responseEventListeners.forEach((e=>{e(t)}))}}class ct{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendMessageToStreamer(e,t){void 0===t&&(t=[]);const s=this.toStreamerMessagesMapProvider.toStreamerMessages.get(e);if(void 0===s)return void i.Error(i.GetStackTrace(),`Attempted to send a message to the streamer with message type: ${e}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`);if(s.structure&&t&&s.structure.length!==t.length)return void i.Error(i.GetStackTrace(),`Provided message data doesn't match expected layout. Expected [ ${s.structure.map((e=>{switch(e){case\"uint8\":case\"uint16\":case\"int16\":case\"float\":case\"double\":return\"number\";case\"string\":return\"string\"}})).toString()} ] but received [ ${t.map((e=>typeof e)).toString()} ]`);let n=0;const r=new TextEncoder;t.forEach(((e,t)=>{switch(s.structure[t]){case\"uint8\":n+=1;break;case\"uint16\":case\"int16\":n+=2;break;case\"float\":n+=4;break;case\"double\":n+=8;break;case\"string\":n+=2,n+=2*r.encode(e).length}}));const a=new DataView(new ArrayBuffer(n+1));a.setUint8(0,s.id);let o=1;t.forEach(((e,t)=>{switch(s.structure[t]){case\"uint8\":a.setUint8(o,e),o+=1;break;case\"uint16\":a.setUint16(o,e,!0),o+=2;break;case\"int16\":a.setInt16(o,e,!0),o+=2;break;case\"float\":a.setFloat32(o,e,!0),o+=4;break;case\"double\":a.setFloat64(o,e,!0),o+=8;break;case\"string\":a.setUint16(o,e.length,!0),o+=2;for(let t=0;t{throw new Error(\"Normalize and quantize unsigned, method not implemented.\")},this.normalizeAndQuantizeSignedFunc=()=>{throw new Error(\"Normalize and unquantize signed, method not implemented.\")},this.denormalizeAndUnquantizeUnsignedFunc=()=>{throw new Error(\"Denormalize and unquantize unsigned, method not implemented.\")}}normalizeAndQuantizeUnsigned(e,t){return this.normalizeAndQuantizeUnsignedFunc(e,t)}unquantizeAndDenormalizeUnsigned(e,t){return this.denormalizeAndUnquantizeUnsignedFunc(e,t)}normalizeAndQuantizeSigned(e,t){return this.normalizeAndQuantizeSignedFunc(e,t)}setupNormalizeAndQuantize(){if(this.videoElementParent=this.videoElementProvider.getVideoParentElement(),this.videoElement=this.videoElementProvider.getVideoElement(),this.videoElementParent&&this.videoElement){const e=this.videoElementParent.clientHeight/this.videoElementParent.clientWidth,t=this.videoElement.videoHeight/this.videoElement.videoWidth;e>t?(i.Log(i.GetStackTrace(),\"Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio\",6),this.ratio=e/t,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerBigger(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerBigger(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerBigger(e,t)):(i.Log(i.GetStackTrace(),\"Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio\",6),this.ratio=t/e,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerSmaller(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerSmaller(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t))}}normalizeAndQuantizeUnsignedPlayerBigger(e,t){const s=e/this.videoElementParent.clientWidth,n=this.ratio*(t/this.videoElementParent.clientHeight-.5)+.5;return s<0||s>1||n<0||n>1?new mt(!1,65535,65535):new mt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerBigger(e,t){const s=e/65536,n=(t/65536-.5)/this.ratio+.5;return new pt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerBigger(e,t){const s=e/(.5*this.videoElementParent.clientWidth),n=this.ratio*t/(.5*this.videoElementParent.clientHeight);return new St(32767*s,32767*n)}normalizeAndQuantizeUnsignedPlayerSmaller(e,t){const s=this.ratio*(e/this.videoElementParent.clientWidth-.5)+.5,n=t/this.videoElementParent.clientHeight;return s<0||s>1||n<0||n>1?new mt(!1,65535,65535):new mt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t){const s=(e/65536-.5)/this.ratio+.5,n=t/65536;return new pt(s*this.videoElementParent.clientWidth,n*this.videoElementParent.clientHeight)}normalizeAndQuantizeSignedPlayerSmaller(e,t){const s=this.ratio*e/(.5*this.videoElementParent.clientWidth),n=t/(.5*this.videoElementParent.clientHeight);return new St(32767*s,32767*n)}}class mt{constructor(e,t,s){this.inRange=e,this.x=t,this.y=s}}class pt{constructor(e,t){this.x=e,this.y=t}}class St{constructor(e,t){this.x=e,this.y=t}}class vt{constructor(e,t){this.shouldShowPlayOverlay=!0,this.autoJoinTimer=void 0,this.config=e,this.pixelStreaming=t,this.responseController=new dt,this.file=new Qe,this.sdpConstraints={offerToReceiveAudio:!0,offerToReceiveVideo:!0},this.afkController=new ye(this.config,this.pixelStreaming,this.onAfkTriggered.bind(this)),this.afkController.onAFKTimedOutCallback=()=>{this.closeSignalingServer(\"You have been disconnected due to inactivity\")},this.freezeFrameController=new y(this.pixelStreaming.videoElementParent),this.videoPlayer=new ot(this.pixelStreaming.videoElementParent,this.config),this.videoPlayer.onVideoInitialized=()=>this.handleVideoInitialized(),this.videoPlayer.onMatchViewportResolutionCallback=(e,t)=>{const s={\"Resolution.Width\":e,\"Resolution.Height\":t};this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify(s)])},this.videoPlayer.onResizePlayerCallback=()=>{this.setUpMouseAndFreezeFrame()},this.streamController=new T(this.videoPlayer),this.coordinateConverter=new ut(this.videoPlayer),this.sendrecvDataChannelController=new Me,this.recvDataChannelController=new Me,this.registerDataChannelEventEmitters(this.sendrecvDataChannelController),this.registerDataChannelEventEmitters(this.recvDataChannelController),this.dataChannelSender=new gt(this.sendrecvDataChannelController),this.dataChannelSender.resetAfkWarningTimerOnDataSend=()=>this.afkController.resetAfkWarningTimer(),this.streamMessageController=new lt,this.webSocketController=new f,this.webSocketController.onConfig=e=>this.handleOnConfigMessage(e),this.webSocketController.onStreamerList=e=>this.handleStreamerListMessage(e),this.webSocketController.onStreamerIDChanged=e=>this.handleStreamerIDChangedMessage(e),this.webSocketController.onPlayerCount=e=>{this.pixelStreaming._onPlayerCount(e.count)},this.webSocketController.onOpen.addEventListener(\"open\",(()=>{this.config.isFlagEnabled(ge.BrowserSendOffer)||this.webSocketController.requestStreamerList()})),this.webSocketController.onClose.addEventListener(\"close\",(e=>{const t=this.shouldReconnect&&1001!=e.detail.code&&this.config.getNumericSettingValue(me.MaxReconnectAttempts)>0,s=this.disconnectMessage?this.disconnectMessage:e.detail.reason;this.pixelStreaming._onDisconnect(s,!t&&!this.isReconnecting),this.afkController.stopAfkWarningTimer(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.setVideoEncoderAvgQP(0),this.setTouchInputEnabled(!1),this.setMouseInputEnabled(!1),this.setKeyboardInputEnabled(!1),this.setGamePadInputEnabled(!1),t&&setTimeout((()=>{this.isReconnecting=!0,this.reconnectAttempt++,this.tryReconnect(e.detail.reason)}),2e3)})),this.sendMessageController=new ct(this.dataChannelSender,this.streamMessageController),this.toStreamerMessagesController=new ht(this.sendMessageController),this.registerMessageHandlers(),this.streamMessageController.populateDefaultProtocol(),this.inputClassesFactory=new it(this.streamMessageController,this.videoPlayer,this.coordinateConverter),this.isUsingSFU=!1,this.isQualityController=!1,this.preferredCodec=\"\",this.shouldReconnect=!0,this.isReconnecting=!1,this.reconnectAttempt=0,this.config._addOnOptionSettingChangedListener(Ce.StreamerId,(e=>{\"\"!==e&&(this.peerConnectionController.peerConnection.close(),this.peerConnectionController.createPeerConnection(this.peerConfig,this.preferredCodec),this.subscribedStream=e,this.webSocketController.sendSubscribe(e))})),this.setVideoEncoderAvgQP(-1),this.signallingUrlBuilder=()=>{let e=this.config.getTextSettingValue(Se.SignallingServerUrl);return this.config.isFlagEnabled(ge.BrowserSendOffer)&&(e+=\"?\"+ge.BrowserSendOffer+\"=true\"),e}}requestUnquantizedAndDenormalizeUnsigned(e,t){return this.coordinateConverter.unquantizeAndDenormalizeUnsigned(e,t)}handleOnMessage(e){const t=new Uint8Array(e.data);i.Log(i.GetStackTrace(),\"Message incoming:\"+t,6);const s=this.streamMessageController.fromStreamerMessages.get(t[0]);this.streamMessageController.fromStreamerHandlers.get(s)(e.data)}registerMessageHandlers(){this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"QualityControlOwnership\",(e=>this.onQualityControlOwnership(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"Response\",(e=>this.responseController.onResponse(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"Command\",(e=>{this.onCommand(e)})),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"FreezeFrame\",(e=>this.onFreezeFrameMessage(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"UnfreezeFrame\",(()=>this.invalidateFreezeFrameAndEnableVideo())),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"VideoEncoderAvgQP\",(e=>this.handleVideoEncoderAvgQP(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"LatencyTest\",(e=>this.handleLatencyTestResult(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"DataChannelLatencyTest\",(e=>this.handleDataChannelLatencyTestResponse(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"InitialSettings\",(e=>this.handleInitialSettings(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"FileExtension\",(e=>this.onFileExtension(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"FileMimeType\",(e=>this.onFileMimeType(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"FileContents\",(e=>this.onFileContents(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"TestEcho\",(()=>{})),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"InputControlOwnership\",(e=>this.onInputControlOwnership(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"GamepadResponse\",(e=>this.onGamepadResponse(e))),this.streamMessageController.registerMessageHandler(Ge.FromStreamer,\"Protocol\",(e=>this.onProtocolMessage(e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"IFrameRequest\",(()=>this.sendMessageController.sendMessageToStreamer(\"IFrameRequest\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"RequestQualityControl\",(()=>this.sendMessageController.sendMessageToStreamer(\"RequestQualityControl\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"FpsRequest\",(()=>this.sendMessageController.sendMessageToStreamer(\"FpsRequest\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"AverageBitrateRequest\",(()=>this.sendMessageController.sendMessageToStreamer(\"AverageBitrateRequest\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"StartStreaming\",(()=>this.sendMessageController.sendMessageToStreamer(\"StartStreaming\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"StopStreaming\",(()=>this.sendMessageController.sendMessageToStreamer(\"StopStreaming\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"LatencyTest\",(e=>this.sendMessageController.sendMessageToStreamer(\"LatencyTest\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"RequestInitialSettings\",(()=>this.sendMessageController.sendMessageToStreamer(\"RequestInitialSettings\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"TestEcho\",(()=>{})),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"UIInteraction\",(e=>this.sendMessageController.sendMessageToStreamer(\"UIInteraction\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"Command\",(e=>this.sendMessageController.sendMessageToStreamer(\"Command\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"TextboxEntry\",(e=>this.sendMessageController.sendMessageToStreamer(\"TextboxEntry\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"KeyDown\",(e=>this.sendMessageController.sendMessageToStreamer(\"KeyDown\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"KeyUp\",(e=>this.sendMessageController.sendMessageToStreamer(\"KeyUp\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"KeyPress\",(e=>this.sendMessageController.sendMessageToStreamer(\"KeyPress\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseEnter\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseEnter\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseLeave\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseLeave\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseDown\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseDown\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseUp\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseUp\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseMove\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseMove\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseWheel\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseWheel\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"MouseDouble\",(e=>this.sendMessageController.sendMessageToStreamer(\"MouseDouble\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"TouchStart\",(e=>this.sendMessageController.sendMessageToStreamer(\"TouchStart\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"TouchEnd\",(e=>this.sendMessageController.sendMessageToStreamer(\"TouchEnd\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"TouchMove\",(e=>this.sendMessageController.sendMessageToStreamer(\"TouchMove\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"GamepadConnected\",(()=>this.sendMessageController.sendMessageToStreamer(\"GamepadConnected\"))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"GamepadButtonPressed\",(e=>this.sendMessageController.sendMessageToStreamer(\"GamepadButtonPressed\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"GamepadButtonReleased\",(e=>this.sendMessageController.sendMessageToStreamer(\"GamepadButtonReleased\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"GamepadAnalog\",(e=>this.sendMessageController.sendMessageToStreamer(\"GamepadAnalog\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"GamepadDisconnected\",(e=>this.sendMessageController.sendMessageToStreamer(\"GamepadDisconnected\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRHMDTransform\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRHMDTransform\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRControllerTransform\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRControllerTransform\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRSystem\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRSystem\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRButtonTouched\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRButtonTouched\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRButtonPressed\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRButtonPressed\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRButtonReleased\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRButtonReleased\",e))),this.streamMessageController.registerMessageHandler(Ge.ToStreamer,\"XRAnalog\",(e=>this.sendMessageController.sendMessageToStreamer(\"XRAnalog\",e)))}onCommand(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.Command\",6);const t=new TextDecoder(\"utf-16\").decode(e.slice(1));i.Log(i.GetStackTrace(),\"Data Channel Command: \"+t,6);const s=JSON.parse(t);\"onScreenKeyboard\"===s.command&&this.pixelStreaming._activateOnScreenKeyboard(s)}onProtocolMessage(e){try{const t=new TextDecoder(\"utf-16\").decode(e.slice(1)),s=JSON.parse(t);Object.prototype.hasOwnProperty.call(s,\"Direction\")||i.Error(i.GetStackTrace(),\"Malformed protocol received. Ensure the protocol message contains a direction\");const n=s.Direction;delete s.Direction,i.Log(i.GetStackTrace(),`Received new ${n==Ge.FromStreamer?\"FromStreamer\":\"ToStreamer\"} protocol. Updating existing protocol...`),Object.keys(s).forEach((e=>{const t=s[e];switch(n){case Ge.ToStreamer:if(!Object.prototype.hasOwnProperty.call(t,\"id\"))return void i.Error(i.GetStackTrace(),`ToStreamer->${e} protocol definition was malformed as it didn't contain at least an id\\n\\n Definition was: ${JSON.stringify(t,null,2)}`);if(\"UIInteraction\"===e||\"Command\"===e||\"LatencyTest\"===e)return;this.streamMessageController.toStreamerHandlers.get(e)?this.streamMessageController.toStreamerMessages.set(e,t):i.Error(i.GetStackTrace(),`There was no registered handler for \"${e}\" - try adding one using registerMessageHandler(MessageDirection.ToStreamer, \"${e}\", myHandler)`);break;case Ge.FromStreamer:if(!Object.prototype.hasOwnProperty.call(t,\"id\"))return void i.Error(i.GetStackTrace(),`FromStreamer->${e} protocol definition was malformed as it didn't contain at least an id\\n\\n Definition was: ${JSON.stringify(t,null,2)}`);this.streamMessageController.fromStreamerHandlers.get(e)?this.streamMessageController.fromStreamerMessages.set(t.id,e):i.Error(i.GetStackTrace(),`There was no registered handler for \"${t}\" - try adding one using registerMessageHandler(MessageDirection.FromStreamer, \"${e}\", myHandler)`);break;default:i.Error(i.GetStackTrace(),`Unknown direction: ${n}`)}})),this.toStreamerMessagesController.SendRequestInitialSettings(),this.toStreamerMessagesController.SendRequestQualityControl()}catch(e){i.Log(i.GetStackTrace(),e)}}onInputControlOwnership(e){const t=new Uint8Array(e);i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.InputControlOwnership\",6);const s=new Boolean(t[1]).valueOf();i.Log(i.GetStackTrace(),`Received input controller message - will your input control the stream: ${s}`),this.pixelStreaming._onInputControlOwnership(s)}onGamepadResponse(e){const t=new TextDecoder(\"utf-16\").decode(e.slice(1)),s=JSON.parse(t);this.gamePadController.onGamepadResponseReceived(s.controllerId)}onAfkTriggered(){this.afkController.onAfkClick(),this.videoPlayer.isPaused()&&this.videoPlayer.hasVideoSource()&&this.playStream()}setAfkEnabled(e){e?this.onAfkTriggered():this.afkController.stopAfkWarningTimer()}tryReconnect(e){this.webSocketController?(this.isReconnecting=!0,this.webSocketController.webSocket&&this.webSocketController.webSocket.readyState!=WebSocket.CLOSED?(this.closeSignalingServer(`${e} Restarting stream...`),setTimeout((()=>{this.tryReconnect(e)}),3e3)):(this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer())):i.Log(i.GetStackTrace(),\"The Web Socket Controller does not exist so this will not work right now.\")}loadFreezeFrameOrShowPlayOverlay(){this.pixelStreaming.dispatchEvent(new J({shouldShowPlayOverlay:this.shouldShowPlayOverlay,isValid:this.freezeFrameController.valid,jpegData:this.freezeFrameController.jpeg})),!0===this.shouldShowPlayOverlay?(i.Log(i.GetStackTrace(),\"showing play overlay\"),this.resizePlayerStyle()):(i.Log(i.GetStackTrace(),\"showing freeze frame\"),this.freezeFrameController.showFreezeFrame()),setTimeout((()=>{this.videoPlayer.setVideoEnabled(!1)}),this.freezeFrameController.freezeFrameDelay)}onFreezeFrameMessage(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.FreezeFrame\",6);const t=new Uint8Array(e);this.freezeFrameController.processFreezeFrameMessage(t,(()=>this.loadFreezeFrameOrShowPlayOverlay()))}invalidateFreezeFrameAndEnableVideo(){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.FreezeFrame\",6),setTimeout((()=>{this.pixelStreaming.dispatchEvent(new j),this.freezeFrameController.hideFreezeFrame()}),this.freezeFrameController.freezeFrameDelay),this.videoPlayer.getVideoElement()&&this.videoPlayer.setVideoEnabled(!0)}onFileExtension(e){const t=new Uint8Array(e);Ke.setExtensionFromBytes(t,this.file)}onFileMimeType(e){const t=new Uint8Array(e);Ke.setMimeTypeFromBytes(t,this.file)}onFileContents(e){const t=new Uint8Array(e);Ke.setContentsFromBytes(t,this.file)}playStream(){if(!this.videoPlayer.getVideoElement()){const e=\"Could not play video stream because the video player was not initialized correctly.\";return this.pixelStreaming.dispatchEvent(new q({message:e})),i.Error(i.GetStackTrace(),e),void this.closeSignalingServer(\"Stream not initialized correctly\")}if(this.videoPlayer.hasVideoSource()){if(this.setTouchInputEnabled(this.config.isFlagEnabled(ge.TouchInput)),this.pixelStreaming.dispatchEvent(new $),this.streamController.audioElement.srcObject){const e=this.config.isFlagEnabled(ge.StartVideoMuted);this.streamController.audioElement.muted=e,e?this.playVideo():this.streamController.audioElement.play().then((()=>{this.playVideo()})).catch((e=>{i.Log(i.GetStackTrace(),e),i.Log(i.GetStackTrace(),\"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay.\"),this.pixelStreaming.dispatchEvent(new X({reason:e}))}))}else this.playVideo();this.shouldShowPlayOverlay=!1,this.freezeFrameController.showFreezeFrame()}else i.Warning(i.GetStackTrace(),\"Cannot play stream, the video element has no srcObject to play.\")}playVideo(){this.videoPlayer.play().catch((e=>{this.streamController.audioElement.srcObject&&this.streamController.audioElement.pause(),i.Log(i.GetStackTrace(),e),i.Log(i.GetStackTrace(),\"Browser does not support autoplaying video without interaction - to resolve this we are going to show the play button overlay.\"),this.pixelStreaming.dispatchEvent(new X({reason:e}))}))}autoPlayVideoOrSetUpPlayOverlay(){this.config.isFlagEnabled(ge.AutoPlayVideo)&&this.playStream(),this.resizePlayerStyle()}connectToSignallingServer(){this.locallyClosed=!1,this.shouldReconnect=!0,this.disconnectMessage=null;const e=this.signallingUrlBuilder();this.webSocketController.connect(e)}startSession(e){if(this.peerConfig=e,this.config.isFlagEnabled(ge.ForceTURN)&&!this.checkTurnServerAvailability(e))return i.Info(i.GetStackTrace(),\"No turn server was found in the Peer Connection Options. TURN cannot be forced, closing connection. Please use STUN instead\"),void this.closeSignalingServer(\"TURN cannot be forced, closing connection. Please use STUN instead.\");this.peerConnectionController=new ze(this.peerConfig,this.config,this.preferredCodec),this.peerConnectionController.onVideoStats=e=>this.handleVideoStats(e),this.peerConnectionController.onSendWebRTCOffer=e=>this.handleSendWebRTCOffer(e),this.peerConnectionController.onSendWebRTCAnswer=e=>this.handleSendWebRTCAnswer(e),this.peerConnectionController.onPeerIceCandidate=e=>this.handleSendIceCandidate(e),this.peerConnectionController.onDataChannel=e=>this.handleDataChannel(e),this.peerConnectionController.showTextOverlayConnecting=()=>this.pixelStreaming._onWebRtcConnecting(),this.peerConnectionController.showTextOverlaySetupFailure=()=>this.pixelStreaming._onWebRtcFailed();let t=!1;this.peerConnectionController.onIceConnectionStateChange=()=>{!t&&[\"connected\",\"completed\"].includes(this.peerConnectionController.peerConnection.iceConnectionState)&&(this.pixelStreaming._onWebRtcConnected(),t=!0)},this.peerConnectionController.onTrack=e=>this.streamController.handleOnTrack(e),this.config.isFlagEnabled(ge.BrowserSendOffer)&&(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,\"cirrus\",this.datachannelOptions),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e),this.peerConnectionController.createOffer(this.sdpConstraints,this.config))}checkTurnServerAvailability(e){if(!e.iceServers)return i.Info(i.GetStackTrace(),\"A turn sever was not found\"),!1;for(const t of e.iceServers)for(const e of t.urls)if(e.includes(\"turn\"))return i.Log(i.GetStackTrace(),`A turn sever was found at ${e}`),!0;return i.Info(i.GetStackTrace(),\"A turn sever was not found\"),!1}handleOnConfigMessage(e){this.resizePlayerStyle(),this.startSession(e.peerConnectionOptions),this.webSocketController.onWebRtcAnswer=e=>this.handleWebRtcAnswer(e),this.webSocketController.onWebRtcOffer=e=>this.handleWebRtcOffer(e),this.webSocketController.onWebRtcPeerDataChannels=e=>this.handleWebRtcSFUPeerDatachannels(e),this.webSocketController.onIceCandidate=e=>this.handleIceCandidate(e)}handleStreamerListMessage(e){i.Log(i.GetStackTrace(),`Got streamer list ${e.ids}`,6);let t=null;var s=this.config.getSettingOption(Ce.StreamerId);s.selected.toString().trim()&&(t=s.selected);const n=[...e.ids];n.unshift(\"\"),this.config.setOptionSettingOptions(Ce.StreamerId,n);let r=null;const a=this.config.isFlagEnabled(ge.WaitForStreamer),o=this.config.getNumericSettingValue(me.MaxReconnectAttempts),l=this.config.getNumericSettingValue(me.StreamerAutoJoinInterval),d=this.config.useUrlParams,c=new URLSearchParams(window.location.search);d&&c.has(Ce.StreamerId)?t=c.get(Ce.StreamerId):this.subscribedStream&&(t=this.subscribedStream),t&&e.ids.includes(t)?r=t:t&&a||1!=e.ids.length||(r=e.ids[0]),r?(this.isReconnecting=!1,this.reconnectAttempt=0,this.config.setOptionSettingValue(Ce.StreamerId,r)):a&&(this.reconnectAttempt{this.webSocketController.requestStreamerList()}),l)):(this.reconnectAttempt=0,this.isReconnecting=!1,this.shouldReconnect=!1)),this.pixelStreaming.dispatchEvent(new Z({messageStreamerList:e,autoSelectedStreamerId:r,wantedStreamerId:t}))}handleStreamerIDChangedMessage(e){const t=e.newID;var s=this.config.getSettingOption(Ce.StreamerId),n=s.onChange;s.onChange=()=>{};for(var r=s.options,i=0;ithis.webSocketController.sendSFURecvDataChannelReady(),this.recvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}else this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handlePostWebrtcNegotiation(){this.afkController.startAfkWarningTimer(),this.pixelStreaming._onWebRtcSdp(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.statsTimerHandle=window.setInterval((()=>this.getStats()),1e3),this.setMouseInputEnabled(this.config.isFlagEnabled(ge.MouseInput)),this.setKeyboardInputEnabled(this.config.isFlagEnabled(ge.KeyboardInput)),this.setGamePadInputEnabled(this.config.isFlagEnabled(ge.GamepadInput))}handleIceCandidate(e){i.Log(i.GetStackTrace(),\"Web RTC Controller: onWebRtcIce\",6);const t=new RTCIceCandidate(e);this.peerConnectionController.handleOnIce(t)}handleSendIceCandidate(e){i.Log(i.GetStackTrace(),\"OnIceCandidate\",6),e.candidate&&e.candidate.candidate&&this.webSocketController.sendIceCandidate(e.candidate)}handleDataChannel(e){i.Log(i.GetStackTrace(),\"Data channel created for us by browser as we are a receiving peer.\",6),this.sendrecvDataChannelController.dataChannel=e.channel,this.sendrecvDataChannelController.setupDataChannel(),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handleSendWebRTCOffer(e){i.Log(i.GetStackTrace(),\"Sending the offer to the Server\",6);const t={minBitrateBps:1e3*this.config.getNumericSettingValue(me.WebRTCMinBitrate),maxBitrateBps:1e3*this.config.getNumericSettingValue(me.WebRTCMaxBitrate)};this.webSocketController.sendWebRtcOffer(e,t)}handleSendWebRTCAnswer(e){i.Log(i.GetStackTrace(),\"Sending the answer to the Server\",6);const t={minBitrateBps:1e3*this.config.getNumericSettingValue(me.WebRTCMinBitrate),maxBitrateBps:1e3*this.config.getNumericSettingValue(me.WebRTCMaxBitrate)};this.webSocketController.sendWebRtcAnswer(e,t),this.isUsingSFU&&this.webSocketController.sendWebRtcDatachannelRequest()}setUpMouseAndFreezeFrame(){this.videoElementParentClientRect=this.videoPlayer.getVideoParentElement().getBoundingClientRect(),this.coordinateConverter.setupNormalizeAndQuantize(),this.freezeFrameController.freezeFrame.resize()}closeSignalingServer(e){var t;this.locallyClosed=!0,this.shouldReconnect=!1,this.disconnectMessage=e,null===(t=this.webSocketController)||void 0===t||t.close()}closePeerConnection(){var e;null===(e=this.peerConnectionController)||void 0===e||e.close()}close(){this.closeSignalingServer(\"\"),this.closePeerConnection()}getStats(){this.peerConnectionController.generateStats()}sendLatencyTest(){this.latencyStartTime=Date.now(),this.streamMessageController.toStreamerHandlers.get(\"LatencyTest\")([JSON.stringify({StartTime:this.latencyStartTime})])}sendDataChannelLatencyTest(e){this.streamMessageController.toStreamerHandlers.get(\"DataChannelLatencyTest\")([JSON.stringify(e)])}sendEncoderMinQP(e){i.Log(i.GetStackTrace(),`MinQP=${e}\\n`,6),null!=e&&this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"Encoder.MinQP\":e})])}sendEncoderMaxQP(e){i.Log(i.GetStackTrace(),`MaxQP=${e}\\n`,6),null!=e&&this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"Encoder.MaxQP\":e})])}sendWebRTCMinBitrate(e){i.Log(i.GetStackTrace(),`WebRTC Min Bitrate=${e}`,6),null!=e&&this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"WebRTC.MinBitrate\":e})])}sendWebRTCMaxBitrate(e){i.Log(i.GetStackTrace(),`WebRTC Max Bitrate=${e}`,6),null!=e&&this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"WebRTC.MaxBitrate\":e})])}sendWebRTCFps(e){i.Log(i.GetStackTrace(),`WebRTC FPS=${e}`,6),null!=e&&(this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"WebRTC.Fps\":e})]),this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"WebRTC.MaxFps\":e})]))}sendShowFps(){i.Log(i.GetStackTrace(),\"---- Sending show stat to UE ----\",6),this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({\"stat.fps\":\"\"})])}sendIframeRequest(){i.Log(i.GetStackTrace(),\"---- Sending Request for an IFrame ----\",6),this.streamMessageController.toStreamerHandlers.get(\"IFrameRequest\")()}emitUIInteraction(e){i.Log(i.GetStackTrace(),\"---- Sending custom UIInteraction message ----\",6),this.streamMessageController.toStreamerHandlers.get(\"UIInteraction\")([JSON.stringify(e)])}emitCommand(e){i.Log(i.GetStackTrace(),\"---- Sending custom Command message ----\",6),this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify(e)])}emitConsoleCommand(e){i.Log(i.GetStackTrace(),\"---- Sending custom Command:ConsoleCommand message ----\",6),this.streamMessageController.toStreamerHandlers.get(\"Command\")([JSON.stringify({ConsoleCommand:e})])}sendRequestQualityControlOwnership(){i.Log(i.GetStackTrace(),\"---- Sending Request to Control Quality ----\",6),this.toStreamerMessagesController.SendRequestQualityControl()}handleLatencyTestResult(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.latencyTest\",6);const t=new TextDecoder(\"utf-16\").decode(e.slice(1)),s=new Ne;Object.assign(s,JSON.parse(t)),s.processFields(),s.testStartTimeMs=this.latencyStartTime,s.browserReceiptTimeMs=Date.now(),s.latencyExcludingDecode=~~(s.browserReceiptTimeMs-s.testStartTimeMs),s.testDuration=~~(s.TransmissionTimeMs-s.ReceiptTimeMs),s.networkLatency=~~(s.latencyExcludingDecode-s.testDuration),s.frameDisplayDeltaTimeMs&&s.browserReceiptTimeMs&&(s.endToEndLatency=(s.frameDisplayDeltaTimeMs,s.networkLatency,~~+s.CaptureToSendMs)),this.pixelStreaming._onLatencyTestResult(s)}handleDataChannelLatencyTestResponse(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.dataChannelLatencyResponse\",6);const t=new TextDecoder(\"utf-16\").decode(e.slice(1)),s=JSON.parse(t);this.pixelStreaming._onDataChannelLatencyTestResponse(s)}handleInitialSettings(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.InitialSettings\",6);const t=new TextDecoder(\"utf-16\").decode(e.slice(1)),s=JSON.parse(t),n=new _e;s.Encoder&&(n.EncoderSettings=s.Encoder),s.WebRTC&&(n.WebRTCSettings=s.WebRTC),s.PixelStreaming&&(n.PixelStreamingSettings=s.PixelStreaming),s.ConfigOptions&&void 0!==s.ConfigOptions.DefaultToHover&&this.config.setFlagEnabled(ge.HoveringMouseMode,!!s.ConfigOptions.DefaultToHover),n.ueCompatible(),i.Log(i.GetStackTrace(),t,6),this.pixelStreaming._onInitialSettings(n)}handleVideoEncoderAvgQP(e){i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.VideoEncoderAvgQP\",6);const t=Number(new TextDecoder(\"utf-16\").decode(e.slice(1)));this.setVideoEncoderAvgQP(t)}handleVideoInitialized(){this.pixelStreaming._onVideoInitialized(),this.autoPlayVideoOrSetUpPlayOverlay(),this.resizePlayerStyle(),this.videoPlayer.updateVideoStreamSize()}onQualityControlOwnership(e){const t=new Uint8Array(e);i.Log(i.GetStackTrace(),\"DataChannelReceiveMessageType.QualityControlOwnership\",6),this.isQualityController=new Boolean(t[1]).valueOf(),i.Log(i.GetStackTrace(),`Received quality controller message, will control quality: ${this.isQualityController}`),this.pixelStreaming._onQualityControlOwnership(this.isQualityController)}handleVideoStats(e){this.pixelStreaming._onVideoStats(e)}resizePlayerStyle(){this.videoPlayer.resizePlayerStyle()}setPreferredCodec(e){this.preferredCodec=e,this.peerConnectionController&&(this.peerConnectionController.preferredCodec=e,this.peerConnectionController.updateCodecSelection=!1)}setVideoEncoderAvgQP(e){this.videoAvgQp=e,this.pixelStreaming._onVideoEncoderAvgQP(this.videoAvgQp)}setKeyboardInputEnabled(e){var t;null===(t=this.keyboardController)||void 0===t||t.unregisterKeyBoardEvents(),e&&(this.keyboardController=this.inputClassesFactory.registerKeyBoard(this.config))}setMouseInputEnabled(e){var t;if(null===(t=this.mouseController)||void 0===t||t.unregisterMouseEvents(),e){const e=this.config.isFlagEnabled(ge.HoveringMouseMode)?Ee.HoveringMouse:Ee.LockedMouse;this.mouseController=this.inputClassesFactory.registerMouse(e)}}setTouchInputEnabled(e){var t;null===(t=this.touchController)||void 0===t||t.unregisterTouchEvents(),e&&(this.touchController=this.inputClassesFactory.registerTouch(this.config.isFlagEnabled(ge.FakeMouseWithTouches),this.videoElementParentClientRect))}setGamePadInputEnabled(e){var t;null===(t=this.gamePadController)||void 0===t||t.unregisterGamePadEvents(),e&&(this.gamePadController=this.inputClassesFactory.registerGamePad(),this.gamePadController.onGamepadConnected=()=>{this.streamMessageController.toStreamerHandlers.get(\"GamepadConnected\")()},this.gamePadController.onGamepadDisconnected=e=>{this.streamMessageController.toStreamerHandlers.get(\"GamepadDisconnected\")([e])})}registerDataChannelEventEmitters(e){e.onOpen=(e,t)=>this.pixelStreaming.dispatchEvent(new z({label:e,event:t})),e.onClose=(e,t)=>this.pixelStreaming.dispatchEvent(new _({label:e,event:t})),e.onError=(e,t)=>this.pixelStreaming.dispatchEvent(new W({label:e,event:t}))}registerMessageHandler(e,t,s){t===Ge.FromStreamer&&void 0===s&&i.Warning(i.GetStackTrace(),`Unable to register handler for ${e} as no handler was passed`),this.streamMessageController.registerMessageHandler(t,e,(n=>void 0===s&&t===Ge.ToStreamer?this.sendMessageController.sendMessageToStreamer(e,n):s(n)))}}class Ct{static vertexShader(){return\"\\n\\t\\tattribute vec2 a_position;\\n\\t\\tattribute vec2 a_texCoord;\\n\\n\\t\\t// input\\n\\t\\tuniform vec2 u_resolution;\\n\\t\\tuniform vec4 u_offset;\\n\\n\\t\\t//\\n\\t\\tvarying vec2 v_texCoord;\\n\\n\\t\\tvoid main() {\\n\\t\\t // convert the rectangle from pixels to 0.0 to 1.0\\n\\t\\t vec2 zeroToOne = a_position / u_resolution;\\n\\n\\t\\t // convert from 0->1 to 0->2\\n\\t\\t vec2 zeroToTwo = zeroToOne * 2.0;\\n\\n\\t\\t // convert from 0->2 to -1->+1 (clipspace)\\n\\t\\t vec2 clipSpace = zeroToTwo - 1.0;\\n\\n\\t\\t gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\\n\\t\\t // pass the texCoord to the fragment shader\\n\\t\\t // The GPU will interpolate this value between points.\\n\\t\\t v_texCoord = (a_texCoord * u_offset.xy) + u_offset.zw;\\n\\t\\t}\\n\\t\\t\"}static fragmentShader(){return\"\\n\\t\\tprecision mediump float;\\n\\n\\t\\t// our texture\\n\\t\\tuniform sampler2D u_image;\\n\\n\\t\\t// the texCoords passed in from the vertex shader.\\n\\t\\tvarying vec2 v_texCoord;\\n\\n\\t\\tvoid main() {\\n\\t\\t gl_FragColor = texture2D(u_image, v_texCoord);\\n\\t\\t}\\n\\t\\t\"}}class ft{static deepCopyGamepad(e){return JSON.parse(JSON.stringify({buttons:e.buttons.map((e=>JSON.parse(JSON.stringify({pressed:e.pressed,touched:e.touched})))),axes:e.axes}))}}class Tt{constructor(e){this.toStreamerMessagesProvider=e,this.controllers=[]}updateStatus(e,t,s){if(e.gamepad){const n=t.getPose(e.gripSpace,s);if(!n)return;let r=0;e.profiles.includes(\"htc-vive\")?r=1:e.profiles.includes(\"oculus-touch\")&&(r=2),this.toStreamerMessagesProvider.toStreamerHandlers.get(\"XRSystem\")([r]);let i=2;switch(e.handedness){case\"left\":i=0;break;case\"right\":i=1}const a=n.transform.matrix,o=[];for(let e=0;e<16;e++)o[e]=new Float32Array([a[e]])[0];this.toStreamerMessagesProvider.toStreamerHandlers.get(\"XRControllerTransform\")([o[0],o[4],o[8],o[12],o[1],o[5],o[9],o[13],o[2],o[6],o[10],o[14],o[3],o[7],o[11],o[15],i]),void 0===this.controllers[i]&&(this.controllers[i]={prevState:void 0,currentState:void 0,id:void 0},this.controllers[i].prevState=ft.deepCopyGamepad(e.gamepad)),this.controllers[i].currentState=ft.deepCopyGamepad(e.gamepad);const l=this.controllers[i],d=l.currentState,c=l.prevState;for(let e=0;e{this.onXrSessionStarted(e)}))}onXrSessionEnded(){i.Log(i.GetStackTrace(),\"XR Session ended\"),this.xrSession=null,this.onSessionEnded.dispatchEvent(new Event(\"xrSessionEnded\"))}onXrSessionStarted(e){i.Log(i.GetStackTrace(),\"XR Session started\"),this.xrSession=e,this.xrSession.addEventListener(\"end\",(()=>{this.onXrSessionEnded()}));const t=document.createElement(\"canvas\");this.gl=t.getContext(\"webgl2\",{xrCompatible:!0}),this.xrSession.updateRenderState({baseLayer:new XRWebGLLayer(this.xrSession,this.gl)});const s=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(s,Ct.vertexShader()),this.gl.compileShader(s);const n=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(n,Ct.fragmentShader()),this.gl.compileShader(n);const r=this.gl.createProgram();this.gl.attachShader(r,s),this.gl.attachShader(r,n),this.gl.linkProgram(r),this.gl.useProgram(r),this.positionLocation=this.gl.getAttribLocation(r,\"a_position\"),this.texcoordLocation=this.gl.getAttribLocation(r,\"a_texCoord\"),this.positionBuffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.enableVertexAttribArray(this.positionLocation);const a=this.gl.createTexture();this.gl.bindTexture(this.gl.TEXTURE_2D,a),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.NEAREST),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.NEAREST),this.texcoordBuffer=this.gl.createBuffer(),this.resolutionLocation=this.gl.getUniformLocation(r,\"u_resolution\"),this.offsetLocation=this.gl.getUniformLocation(r,\"u_offset\"),e.requestReferenceSpace(\"local\").then((e=>{this.xrRefSpace=e,this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t)))})),this.onSessionStarted.dispatchEvent(new Event(\"xrSessionStarted\"))}onXrFrame(e,t){const s=t.getViewerPose(this.xrRefSpace);if(s){const e=s.transform.matrix,t=[];for(let s=0;s<16;s++)t[s]=new Float32Array([e[s]])[0];this.webRtcController.streamMessageController.toStreamerHandlers.get(\"XRHMDTransform\")([t[0],t[4],t[8],t[12],t[1],t[5],t[9],t[13],t[2],t[6],t[10],t[14],t[3],t[7],t[11],t[15]]);const n=this.xrSession.renderState.baseLayer;this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,n.framebuffer),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,this.webRtcController.videoPlayer.getVideoElement()),this.render(this.webRtcController.videoPlayer.getVideoElement())}this.webRtcController.config.isFlagEnabled(ge.XRControllerInput)&&this.xrSession.inputSources.forEach(((e,s,n)=>{this.xrGamepadController.updateStatus(e,t,this.xrRefSpace)}),this),this.xrSession.requestAnimationFrame(((e,t)=>this.onXrFrame(e,t))),this.onFrame.dispatchEvent(new le({time:e,frame:t}))}render(e){if(!this.gl)return;const t=this.xrSession.renderState.baseLayer;let s,n,r,i,a;this.gl.viewport(0,0,t.framebufferWidth,t.framebufferHeight),this.gl.uniform4f(this.offsetLocation,1,1,0,0),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,e.videoWidth,0,0,e.videoHeight,0,e.videoHeight,e.videoWidth,0,e.videoWidth,e.videoHeight]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array([0,0,1,0,0,1,0,1,1,0,1,1]),this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,a=0,this.gl.vertexAttribPointer(this.positionLocation,s,n,r,i,a),this.gl.enableVertexAttribArray(this.texcoordLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,a=0,this.gl.vertexAttribPointer(this.texcoordLocation,s,n,r,i,a),this.gl.uniform2f(this.resolutionLocation,e.videoWidth,e.videoHeight);const o=this.gl.TRIANGLES;a=0,this.gl.drawArrays(o,a,6)}static isSessionSupported(e){return navigator.xr?navigator.xr.isSessionSupported(e):new Promise((()=>!1))}}class yt{constructor(e){this.editTextButton=null,this.hiddenInput=null,\"ontouchstart\"in document.documentElement&&this.createOnScreenKeyboardHelpers(e)}unquantizeAndDenormalizeUnsigned(e,t){return null}createOnScreenKeyboardHelpers(e){this.hiddenInput||(this.hiddenInput=document.createElement(\"input\"),this.hiddenInput.id=\"hiddenInput\",this.hiddenInput.maxLength=0,e.appendChild(this.hiddenInput)),this.editTextButton||(this.editTextButton=document.createElement(\"button\"),this.editTextButton.id=\"editTextButton\",this.editTextButton.innerHTML=\"edit text\",e.appendChild(this.editTextButton),this.editTextButton.classList.add(\"hiddenState\"),this.editTextButton.addEventListener(\"touchend\",(e=>{this.hiddenInput.focus(),e.preventDefault()})))}showOnScreenKeyboard(e){if(e.showOnScreenKeyboard){this.editTextButton.classList.remove(\"hiddenState\");const t=this.unquantizeAndDenormalizeUnsigned(e.x,e.y);this.editTextButton.style.top=t.y.toString()+\"px\",this.editTextButton.style.left=(t.x-40).toString()+\"px\"}else this.editTextButton.classList.add(\"hiddenState\"),this.hiddenInput.blur()}}class Mt{constructor(e){this.seq=e.Seq,this.playerSentTimestamp=Date.now(),this.requestFillerSize=e.Filler?e.Filler.length:0}update(e){this.playerReceivedTimestamp=Date.now(),this.streamerReceivedTimestamp=e.ReceivedTimestamp,this.streamerSentTimestamp=e.SentTimestamp,this.responseFillerSize=e.Filler?e.Filler.length:0}}class wt{constructor(e,t){this.sink=e,this.callback=t,this.records=new Map,this.seq=0}start(e){return!this.isRunning()&&(this.startTime=Date.now(),this.records.clear(),this.interval=setInterval((()=>{Date.now()-this.startTime>=e.duration?this.stop():this.sendRequest(e.requestSize,e.responseSize)}).bind(this),Math.floor(1e3/e.rps)),!0)}stop(){this.interval&&(clearInterval(this.interval),this.interval=void 0,this.callback(this.produceResult()))}produceResult(){const e=new Map(this.records);return{records:e,dataChannelRtt:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.playerReceivedTimestamp-t.playerSentTimestamp)),0)/this.records.size),playerToStreamerTime:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.streamerReceivedTimestamp-t.playerSentTimestamp)),0)/this.records.size),streamerToPlayerTime:Math.ceil(Array.from(this.records.values()).reduce(((e,t)=>e+(t.playerReceivedTimestamp-t.streamerSentTimestamp)),0)/this.records.size),exportLatencyAsCSV:()=>{let t=\"Timestamp;RTT;PlayerToStreamer;StreamerToPlayer;\\n\";return e.forEach((e=>{t+=e.playerSentTimestamp+\";\",t+=e.playerReceivedTimestamp-e.playerSentTimestamp+\";\",t+=e.streamerReceivedTimestamp-e.playerSentTimestamp+\";\",t+=e.playerReceivedTimestamp-e.streamerSentTimestamp+\";\",t+=\"\\n\"})),t}}}isRunning(){return!!this.interval}receive(e){if(!this.isRunning())return;if(!e)return void i.Error(i.GetStackTrace(),\"Undefined response from server\");let t=this.records.get(e.Seq);t&&t.update(e)}sendRequest(e,t){let s=this.createRequest(e,t),n=new Mt(s);this.records.set(n.seq,n),this.sink(s)}createRequest(e,t){return{Seq:this.seq++,FillResponseSize:t,Filler:e?\"A\".repeat(e):\"\"}}}class bt{constructor(e,t){this.allowConsoleCommands=!1,this.config=e,(null==t?void 0:t.videoElementParent)&&(this._videoElementParent=t.videoElementParent),this._eventEmitter=new he,this.configureSettings(),this.setWebRtcPlayerController(new vt(this.config,this)),this.onScreenKeyboardHelper=new yt(this.videoElementParent),this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned=(e,t)=>this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(e,t),this._activateOnScreenKeyboard=e=>this.onScreenKeyboardHelper.showOnScreenKeyboard(e),this._webXrController=new Et(this._webRtcController),this._setupWebRtcTCPRelayDetection=this._setupWebRtcTCPRelayDetection.bind(this),this._eventEmitter.addEventListener(\"webRtcConnected\",(e=>{this._eventEmitter.addEventListener(\"statsReceived\",this._setupWebRtcTCPRelayDetection)}))}get videoElementParent(){return this._videoElementParent||(this._videoElementParent=document.createElement(\"div\"),this._videoElementParent.id=\"videoElementParent\"),this._videoElementParent}configureSettings(){this.config._addOnSettingChangedListener(ge.IsQualityController,(e=>{!0!==e||this._webRtcController.isQualityController||this._webRtcController.sendRequestQualityControlOwnership()})),this.config._addOnSettingChangedListener(ge.AFKDetection,(e=>{this._webRtcController.setAfkEnabled(e)})),this.config._addOnSettingChangedListener(ge.MatchViewportResolution,(()=>{this._webRtcController.videoPlayer.updateVideoStreamSize()})),this.config._addOnSettingChangedListener(ge.HoveringMouseMode,(e=>{this.config.setFlagLabel(ge.HoveringMouseMode,`Control Scheme: ${e?\"Hovering\":\"Locked\"} Mouse`),this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(ge.MouseInput))})),this.config._addOnSettingChangedListener(ge.KeyboardInput,(e=>{this._webRtcController.setKeyboardInputEnabled(e)})),this.config._addOnSettingChangedListener(ge.MouseInput,(e=>{this._webRtcController.setMouseInputEnabled(e)})),this.config._addOnSettingChangedListener(ge.TouchInput,(e=>{this._webRtcController.setTouchInputEnabled(e)})),this.config._addOnSettingChangedListener(ge.GamepadInput,(e=>{this._webRtcController.setGamePadInputEnabled(e)})),this.config._addOnNumericSettingChangedListener(me.MinQP,(e=>{i.Log(i.GetStackTrace(),\"-------- Sending MinQP --------\",7),this._webRtcController.sendEncoderMinQP(e),i.Log(i.GetStackTrace(),\"-------------------------------------------\",7)})),this.config._addOnNumericSettingChangedListener(me.MaxQP,(e=>{i.Log(i.GetStackTrace(),\"-------- Sending encoder settings --------\",7),this._webRtcController.sendEncoderMaxQP(e),i.Log(i.GetStackTrace(),\"-------------------------------------------\",7)})),this.config._addOnNumericSettingChangedListener(me.WebRTCMinBitrate,(e=>{i.Log(i.GetStackTrace(),\"-------- Sending web rtc settings --------\",7),this._webRtcController.sendWebRTCMinBitrate(1e3*e),i.Log(i.GetStackTrace(),\"-------------------------------------------\",7)})),this.config._addOnNumericSettingChangedListener(me.WebRTCMaxBitrate,(e=>{i.Log(i.GetStackTrace(),\"-------- Sending web rtc settings --------\",7),this._webRtcController.sendWebRTCMaxBitrate(1e3*e),i.Log(i.GetStackTrace(),\"-------------------------------------------\",7)})),this.config._addOnNumericSettingChangedListener(me.WebRTCFPS,(e=>{i.Log(i.GetStackTrace(),\"-------- Sending web rtc settings --------\",7),this._webRtcController.sendWebRTCFps(e),i.Log(i.GetStackTrace(),\"-------------------------------------------\",7)})),this.config._addOnOptionSettingChangedListener(Ce.PreferredCodec,(e=>{this._webRtcController&&this._webRtcController.setPreferredCodec(e)})),this.config._registerOnChangeEvents(this._eventEmitter)}_activateOnScreenKeyboard(e){throw new Error(\"Method not implemented.\")}_onInputControlOwnership(e){this._inputController=e}setWebRtcPlayerController(e){this._webRtcController=e,this._webRtcController.setPreferredCodec(this.config.getSettingOption(Ce.PreferredCodec).selected),this._webRtcController.resizePlayerStyle(),this.checkForAutoConnect()}connect(){this._eventEmitter.dispatchEvent(new N),this._webRtcController.connectToSignallingServer()}reconnect(){this._eventEmitter.dispatchEvent(new Q),this._webRtcController.tryReconnect(\"Reconnecting...\")}disconnect(){this._eventEmitter.dispatchEvent(new K),this._webRtcController.close()}play(){this._onStreamLoading(),this._webRtcController.playStream()}checkForAutoConnect(){this.config.isFlagEnabled(ge.AutoConnect)&&(this._onWebRtcAutoConnect(),this._webRtcController.connectToSignallingServer())}unmuteMicrophone(e=!1){if(!this.config.isFlagEnabled(\"UseMic\"))return e?(this.config.setFlagEnabled(\"UseMic\",!0),void this.reconnect()):void i.Warning(i.GetStackTrace(),\"Trying to unmute mic, but PixelStreaming was initialized with no microphone track. Call with forceEnable == true to re-connect with a mic track.\");this.setMicrophoneMuted(!1)}muteMicrophone(){this.config.isFlagEnabled(\"UseMic\")?this.setMicrophoneMuted(!0):i.Info(i.GetStackTrace(),\"Trying to mute mic, but PixelStreaming has no microphone track, so sending sound is already disabled.\")}setMicrophoneMuted(e){var t,s,n,r;for(const i of null!==(r=null===(n=null===(s=null===(t=this._webRtcController)||void 0===t?void 0:t.peerConnectionController)||void 0===s?void 0:s.peerConnection)||void 0===n?void 0:n.getTransceivers())&&void 0!==r?r:[])Ie.canTransceiverSendAudio(i)&&(i.sender.track.enabled=!e)}_onWebRtcAutoConnect(){this._eventEmitter.dispatchEvent(new O)}_onWebRtcSdp(){this._eventEmitter.dispatchEvent(new D)}_onStreamLoading(){this._eventEmitter.dispatchEvent(new V)}_onDisconnect(e,t){this._eventEmitter.dispatchEvent(new B({eventString:e,allowClickToReconnect:t}))}_onWebRtcConnecting(){this._eventEmitter.dispatchEvent(new I)}_onWebRtcConnected(){this._eventEmitter.dispatchEvent(new U)}_onWebRtcFailed(){this._eventEmitter.dispatchEvent(new G)}_onVideoInitialized(){this._eventEmitter.dispatchEvent(new H),this._videoStartTime=Date.now()}_onLatencyTestResult(e){this._eventEmitter.dispatchEvent(new te({latencyTimings:e}))}_onDataChannelLatencyTestResponse(e){this._eventEmitter.dispatchEvent(new se({response:e}))}_onVideoStats(e){this._videoStartTime&&void 0!==this._videoStartTime||(this._videoStartTime=Date.now()),e.handleSessionStatistics(this._videoStartTime,this._inputController,this._webRtcController.videoAvgQp),this._eventEmitter.dispatchEvent(new Y({aggregatedStats:e}))}_onVideoEncoderAvgQP(e){this._eventEmitter.dispatchEvent(new F({avgQP:e}))}_onInitialSettings(e){var t;this._eventEmitter.dispatchEvent(new re({settings:e})),e.PixelStreamingSettings&&(this.allowConsoleCommands=null!==(t=e.PixelStreamingSettings.AllowPixelStreamingCommands)&&void 0!==t&&t,!1===this.allowConsoleCommands&&i.Info(i.GetStackTrace(),\"-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled.\"));const s=this.config.useUrlParams,n=new URLSearchParams(window.location.search);i.Info(i.GetStackTrace(),`using URL parameters ${s}`),e.EncoderSettings&&(this.config.setNumericSetting(me.MinQP,s&&n.has(me.MinQP)?Number.parseFloat(n.get(me.MinQP)):e.EncoderSettings.MinQP),this.config.setNumericSetting(me.MaxQP,s&&n.has(me.MaxQP)?Number.parseFloat(n.get(me.MaxQP)):e.EncoderSettings.MaxQP)),e.WebRTCSettings&&(this.config.setNumericSetting(me.WebRTCMinBitrate,s&&n.has(me.WebRTCMinBitrate)?Number.parseFloat(n.get(me.WebRTCMinBitrate)):e.WebRTCSettings.MinBitrate/1e3),this.config.setNumericSetting(me.WebRTCMaxBitrate,s&&n.has(me.WebRTCMaxBitrate)?Number.parseFloat(n.get(me.WebRTCMaxBitrate)):e.WebRTCSettings.MaxBitrate/1e3),this.config.setNumericSetting(me.WebRTCFPS,s&&n.has(me.WebRTCFPS)?Number.parseFloat(n.get(me.WebRTCFPS)):e.WebRTCSettings.FPS))}_onQualityControlOwnership(e){this.config.setFlagEnabled(ge.IsQualityController,e)}_onPlayerCount(e){this._eventEmitter.dispatchEvent(new de({count:e}))}_setupWebRtcTCPRelayDetection(e){let t=e.data.aggregatedStats.getActiveCandidatePair();if(null!=t){let s=e.data.aggregatedStats.localCandidates.find((e=>e.id==t.localCandidateId),null);null!=s&&\"relay\"==s.candidateType&&\"tcp\"==s.relayProtocol&&this._eventEmitter.dispatchEvent(new ce),this._eventEmitter.removeEventListener(\"statsReceived\",this._setupWebRtcTCPRelayDetection)}}requestLatencyTest(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendLatencyTest(),!0)}requestDataChannelLatencyTest(e){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._dataChannelLatencyTestController||(this._dataChannelLatencyTestController=new wt(this._webRtcController.sendDataChannelLatencyTest.bind(this._webRtcController),(e=>{this._eventEmitter.dispatchEvent(new ne({result:e}))})),this.addEventListener(\"dataChannelLatencyTestResponse\",(({data:{response:e}})=>{this._dataChannelLatencyTestController.receive(e)}))),this._dataChannelLatencyTestController.start(e))}requestShowFps(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendShowFps(),!0)}requestIframe(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendIframeRequest(),!0)}emitUIInteraction(e){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.emitUIInteraction(e),!0)}emitCommand(e){return!(!this._webRtcController.videoPlayer.isVideoReady()||!this.allowConsoleCommands&&\"ConsoleCommand\"in e||(this._webRtcController.emitCommand(e),0))}emitConsoleCommand(e){return!(!this.allowConsoleCommands||!this._webRtcController.videoPlayer.isVideoReady()||(this._webRtcController.emitConsoleCommand(e),0))}addResponseEventListener(e,t){this._webRtcController.responseController.addResponseEventListener(e,t)}removeResponseEventListener(e){this._webRtcController.responseController.removeResponseEventListener(e)}dispatchEvent(e){return this._eventEmitter.dispatchEvent(e)}addEventListener(e,t){this._eventEmitter.addEventListener(e,t)}removeEventListener(e,t){this._eventEmitter.removeEventListener(e,t)}toggleXR(){this.webXrController.xrClicked()}setSignallingUrlBuilder(e){this._webRtcController.signallingUrlBuilder=e}get webSocketController(){return this._webRtcController.webSocketController}get webXrController(){return this._webXrController}registerMessageHandler(e,t,s){t!==Ge.FromStreamer||void 0!==s?t===Ge.ToStreamer&&void 0===s?this._webRtcController.streamMessageController.registerMessageHandler(t,e,(t=>this._webRtcController.sendMessageController.sendMessageToStreamer(e,t))):this._webRtcController.streamMessageController.registerMessageHandler(t,e,(e=>s(e))):i.Warning(i.GetStackTrace(),`Unable to register an undefined handler for ${e}`)}get toStreamerHandlers(){return this._webRtcController.streamMessageController.toStreamerHandlers}isReconnecting(){return this._webRtcController.isReconnecting}}class Rt{}var Pt=r.Dz,kt=r.g$,Lt=r.Lt,xt=r.Q9,At=r.qf,Ft=r.hV,Dt=r.z$,Ot=r.J0,It=r.De,Ut=r.$C,Gt=r.al,Bt=r._W,zt=r.Gv,_t=r.m,Wt=r.tz,Ht=r.Nu,Vt=r.zg,Nt=r.vp,Kt=r.vU,Qt=r.wF,qt=r.rv,$t=r.Nh,Xt=r.ss,Jt=r.qW,jt=r.QL,Yt=r.cf,Zt=r.eM,es=r.Yd,ts=r.Tk,ss=r.iM,ns=r.qy,rs=r.ce,is=r.sK,as=r.Ok,os=r.q5,ls=r.g,ds=r.xl,cs=r.I,hs=r.bx,gs=r.dD,us=r.Ib,ms=r.Az,ps=r.Iw,Ss=r.qY,vs=r.db,Cs=r.mR,fs=r.Tn,Ts=r.rV,Es=r.gh,ys=r.Mi,Ms=r.j,ws=r.YB,bs=r.Yt,Rs=r.i5,Ps=r.x_,ks=r.Am,Ls=r.eR,xs=r.r8,As=r.u3,Fs=r.vd,Ds=r.iV,Os=r.jZ,Is=r.SW,Us=r.ZH,Gs=r.Ni,Bs=r.lh,zs=r.ZP,_s=r.bq,Ws=r.$f,Hs=r.eu,Vs=r.Ax,Ns=r.Mc;export{Pt as AfkLogic,kt as AfkTimedOutEvent,Lt as AfkWarningActivateEvent,xt as AfkWarningDeactivateEvent,At as AfkWarningUpdateEvent,Ft as AggregatedStats,Dt as CandidatePairStats,Ot as CandidateStat,It as Config,Ut as ControlSchemeType,Gt as DataChannelCloseEvent,Bt as DataChannelErrorEvent,zt as DataChannelLatencyTestResponseEvent,_t as DataChannelLatencyTestResultEvent,Wt as DataChannelOpenEvent,Ht as DataChannelStats,Vt as EncoderSettings,Nt as EventEmitter,Kt as Flags,Qt as HideFreezeFrameEvent,qt as InboundAudioStats,$t as InboundVideoStats,Xt as InitialSettings,Jt as InitialSettingsEvent,jt as LatencyTestResultEvent,Yt as LatencyTestResults,Zt as LoadFreezeFrameEvent,es as Logger,ts as MessageDirection,ss as MessageRecv,ns as MessageSend,rs as MessageStreamerList,is as NumericParameters,as as OptionParameters,os as OutBoundVideoStats,ls as PixelStreaming,ds as PlayStreamErrorEvent,cs as PlayStreamEvent,hs as PlayStreamRejectedEvent,gs as PlayerCountEvent,us as SettingBase,ms as SettingFlag,ps as SettingNumber,Ss as SettingOption,vs as SettingText,Cs as SettingsChangedEvent,fs as SignallingProtocol,Ts as StatsReceivedEvent,Es as StreamLoadingEvent,ys as StreamPreConnectEvent,Ms as StreamPreDisconnectEvent,ws as StreamReconnectEvent,bs as StreamerIDChangedMessageEvent,Rs as StreamerListMessageEvent,Ps as TextParameters,ks as UnquantizedAndDenormalizeUnsigned,Ls as VideoEncoderAvgQPEvent,xs as VideoInitializedEvent,As as WebRTCSettings,Fs as WebRtcAutoConnectEvent,Ds as WebRtcConnectedEvent,Os as WebRtcConnectingEvent,Is as WebRtcDisconnectedEvent,Us as WebRtcFailedEvent,Gs as WebRtcPlayerController,Bs as WebRtcSdpEvent,zs as WebRtcTCPRelayDetectedEvent,_s as WebSocketController,Ws as WebXRController,Hs as XrFrameEvent,Vs as XrSessionEndedEvent,Ns as XrSessionStartedEvent};","/* eslint-env node */\n'use strict';\n\n// SDP helpers.\nconst SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substring(2, 12);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(line => line.trim());\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n const parts = blob.split('\\nm=');\n return parts.map((part, index) => (index > 0 ?\n 'm=' + part : part).trim() + '\\r\\n');\n};\n\n// Returns the session description.\nSDPUtils.getDescription = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// Returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\n// Input can be prefixed with a=.\nSDPUtils.parseCandidate = function(line) {\n let parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n const candidate = {\n foundation: parts[0],\n component: {1: 'rtp', 2: 'rtcp'}[parts[1]] || parts[1],\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7],\n };\n\n for (let i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compatibility.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag. Don't overwrite.\n if (candidate[parts[i]] === undefined) {\n candidate[parts[i]] = parts[i + 1];\n }\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\n// This does not include the a= prefix!\nSDPUtils.writeCandidate = function(candidate) {\n const sdp = [];\n sdp.push(candidate.foundation);\n\n const component = candidate.component;\n if (component === 'rtp') {\n sdp.push(1);\n } else if (component === 'rtcp') {\n sdp.push(2);\n } else {\n sdp.push(component);\n }\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n const type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// Sample input:\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substring(14).split(' ');\n};\n\n// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n let parts = line.substring(9).split(' ');\n const parsed = {\n payloadType: parseInt(parts.shift(), 10), // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generates a rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n const channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses a extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1],\n attributes: parts.slice(2).join(' '),\n };\n};\n\n// Generates an extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri +\n (headerExtension.attributes ? ' ' + headerExtension.attributes : '') +\n '\\r\\n';\n};\n\n// Parses a fmtp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n const parsed = {};\n let kv;\n const parts = line.substring(line.indexOf(' ') + 1).split(';');\n for (let j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n let line = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n const params = [];\n Object.keys(codec.parameters).forEach(param => {\n if (codec.parameters[param] !== undefined) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n const parts = line.substring(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' '),\n };\n};\n\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n let lines = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(fb => {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses a RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n const sp = line.indexOf(' ');\n const parts = {\n ssrc: parseInt(line.substring(7, sp), 10),\n };\n const colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substring(sp + 1, colon);\n parts.value = line.substring(colon + 1);\n } else {\n parts.attribute = line.substring(sp + 1);\n }\n return parts;\n};\n\n// Parse a ssrc-group line (see RFC 5576). Sample input:\n// a=ssrc-group:semantics 12 34\nSDPUtils.parseSsrcGroup = function(line) {\n const parts = line.substring(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(ssrc => parseInt(ssrc, 10)),\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// Returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substring(6);\n }\n};\n\n// Parses a fingerprint line for DTLS-SRTP.\nSDPUtils.parseFingerprint = function(line) {\n const parts = line.substring(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1].toUpperCase(), // the definition is upper-case in RFC 4572.\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint),\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n let sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(fp => {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n\n// Parses a=crypto lines into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members\nSDPUtils.parseCryptoLine = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n tag: parseInt(parts[0], 10),\n cryptoSuite: parts[1],\n keyParams: parts[2],\n sessionParams: parts.slice(3),\n };\n};\n\nSDPUtils.writeCryptoLine = function(parameters) {\n return 'a=crypto:' + parameters.tag + ' ' +\n parameters.cryptoSuite + ' ' +\n (typeof parameters.keyParams === 'object'\n ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)\n : parameters.keyParams) +\n (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +\n '\\r\\n';\n};\n\n// Parses the crypto key parameters into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*\nSDPUtils.parseCryptoKeyParams = function(keyParams) {\n if (keyParams.indexOf('inline:') !== 0) {\n return null;\n }\n const parts = keyParams.substring(7).split('|');\n return {\n keyMethod: 'inline',\n keySalt: parts[0],\n lifeTime: parts[1],\n mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,\n mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,\n };\n};\n\nSDPUtils.writeCryptoKeyParams = function(keyParams) {\n return keyParams.keyMethod + ':'\n + keyParams.keySalt +\n (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +\n (keyParams.mkiValue && keyParams.mkiLength\n ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength\n : '');\n};\n\n// Extracts all SDES parameters.\nSDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=crypto:');\n return lines.map(SDPUtils.parseCryptoLine);\n};\n\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-ufrag:')[0];\n const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-pwd:')[0];\n if (!(ufrag && pwd)) {\n return null;\n }\n return {\n usernameFragment: ufrag.substring(12),\n password: pwd.substring(10),\n };\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n if (params.iceLite) {\n sdp += 'a=ice-lite\\r\\n';\n }\n return sdp;\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n const description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: [],\n };\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n description.profile = mline[2];\n for (let i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n const pt = mline[i];\n const rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n const codec = SDPUtils.parseRtpMap(rtpmapline);\n const fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp: is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.forEach(codec => {\n wildcardRtcpFb.forEach(fb=> {\n const duplicate = codec.rtcpFeedback.find(existingFeedback => {\n return existingFeedback.type === fb.type &&\n existingFeedback.parameter === fb.parameter;\n });\n if (!duplicate) {\n codec.rtcpFeedback.push(fb);\n }\n });\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n let sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';\n sdp += caps.codecs.map(codec => {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(codec => {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n let maxptime = 0;\n caps.codecs.forEach(codec => {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(extension => {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n const encodingParameters = [];\n const description = SDPUtils.parseRtpParameters(mediaSection);\n const hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(parts => parts.attribute === 'cname');\n const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n let secondarySsrc;\n\n const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(line => {\n const parts = line.substring(17).split(' ');\n return parts.map(part => parseInt(part, 10));\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(codec => {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n let encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10),\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red',\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc,\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substring(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(params => {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n const rtcpParameters = {};\n\n // Gets the first SSRC. Note that with RTX there might be multiple\n // SSRCs.\n const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(obj => obj.attribute === 'cname')[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrŅ–bute.\n // Note that Edge does not support unmuxed RTCP.\n const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\nSDPUtils.writeRtcpParameters = function(rtcpParameters) {\n let sdp = '';\n if (rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n if (rtcpParameters.mux) {\n sdp += 'a=rtcp-mux\\r\\n';\n }\n if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {\n sdp += 'a=ssrc:' + rtcpParameters.ssrc +\n ' cname:' + rtcpParameters.cname + '\\r\\n';\n }\n return sdp;\n};\n\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n let parts;\n const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substring(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(msidParts => msidParts.attribute === 'msid');\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n const mline = SDPUtils.parseMLine(mediaSection);\n const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n let maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substring(12), 10),\n protocol: mline.fmt,\n maxMessageSize,\n };\n }\n const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n const parts = sctpMapLines[0]\n .substring(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize,\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n let output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n',\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n',\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 22);\n};\n\n// Write boiler plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n let sessionId;\n const version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n const user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n const lines = SDPUtils.splitLines(mediaSection);\n for (let i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substring(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n return mline[0].substring(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const parts = lines[0].substring(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' '),\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n const parts = line.substring(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5],\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n const lines = SDPUtils.splitLines(blob);\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { Config, PixelStreaming, Flags, OptionParameters, Logger } from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.4';\nlet activePixelStreams = [];\nlet currentAudioContext = null;\nlet requestId = null;\n\n// Tracks the current muted state, so we don't have to spam duplicate messages via interop\nlet mutedViaHighVolume = false;\n\nexport function RTS_PS_Connect(url, parent, enableInput, isQualityController, simpleTeleconferenceService, dotNetObjectReference) {\n RTS_PS_ClearAll(); // Ensure clean slate before creating new session\n\n Logger.verboseLogLevel = 0;\n \n const config = new Config({\n initialSettings: {\n AutoPlayVideo: true,\n AutoConnect: true,\n ss: url,\n StartVideoMuted: false,\n ControlsQuality: isQualityController,\n ForceTURN: false,\n MaxReconnectAttempts: 10000,\n StreamerAutoJoinInterval: 2000,\n TimeoutIfIdle: false,\n UseMic: false\n }\n });\n\n config.setFlagEnabled(Flags.MouseInput, enableInput);\n config.setFlagEnabled(Flags.KeyboardInput, enableInput);\n config.setFlagEnabled(Flags.TouchInput, false);\n config.setFlagEnabled(Flags.GamepadInput, false);\n config.setFlagEnabled(Flags.XRControllerInput, false);\n config.setFlagEnabled(Flags.HoveringMouseMode, false);\n\n config.setOptionSettingValue(OptionParameters.StreamerId, \"SFU\");\n\n // Create a PixelStreaming instance and attach the video element to an existing parent div\n const pixelStreaming = new PixelStreaming(config, { videoElementParent: parent });\n\n activePixelStreams.push(pixelStreaming);\n\n window.addEventListener('online', () => {\n if (activePixelStreams.length > 0) {\n activePixelStreams.forEach(pixelStreaming => {\n pixelStreaming.reconnect();\n });\n }\n });\n\n window.addEventListener('offline', () => {\n dotNetObjectReference.invokeMethodAsync('PixelStreamingDisconnected');\n });\n\n pixelStreaming.addEventListener(\"streamerListMessage\", ({ data: { messageStreamerList, autoSelectedStreamerId } }) => {\n console.log(messageStreamerList);\n // Check if SFU is in the list of streamer IDs\n if (messageStreamerList.ids.includes(\"SFU\")) {\n // Check that it's not already connected to SFU. Connecting multiple times has no effect for SFU, but breaks for DefaultStreamer\n if (config.getSettingOption(OptionParameters.StreamerId).selected != \"SFU\") {\n console.log(\"SFU streamer found. Setting SFU as the streamer ID\");\n\n // Set SFU as the selected streamer ID\n config.setOptionSettingValue(OptionParameters.StreamerId, \"SFU\");\n }\n } else if (messageStreamerList.ids.includes(\"DefaultStreamer\")) {\n // Check that it's not already connected to DefaultStreamer. Connecting multiple times has no effect for SFU, but breaks for DefaultStreamer\n if (config.getSettingOption(OptionParameters.StreamerId).selected != \"DefaultStreamer\") {\n console.log(\"Default Streamer found. Setting Default Streamer as the streamer ID\");\n\n // Set DefaultStreamer as the selected streamer ID\n config.setOptionSettingValue(OptionParameters.StreamerId, \"DefaultStreamer\");\n }\n if (!messageStreamerList.ids.includes(config.getSettingOption(OptionParameters.StreamerId).selected)) {\n const newStreamerId = messageStreamerList.ids[0];\n config.setOptionSettingValue(OptionParameters.StreamerId, newStreamerId);\n console.log(\"Streamer ID set to:\", newStreamerId);\n }\n }\n });\n\n async function monitorAudio(videoElement, analyserNode, dataArray, volumeHistory, volumeSum) {\n if (!document.body.contains(videoElement)) {\n console.log(\"Video element has been removed, stopping audio monitoring.\");\n return; // Exit the animation frame loop\n }\n\n // if (!grantedMicPermission) {\n // return;\n // }\n\n analyserNode.getByteFrequencyData(dataArray);\n\n let sum = 0;\n for (let i = 0; i < dataArray.length / 2; i++) {\n sum += dataArray[i];\n }\n let average = sum / (dataArray.length / 2);\n let normalizedVolume = average / 128.0; // Normalize the volume\n\n const samplesPerQuarterSecond = Math.floor((44100 / 512) / 2);\n\n if (volumeHistory.length > 0 && volumeHistory[volumeHistory.length - 1] < 0.01 && normalizedVolume > 0.1) {\n // Rapid response: Fill the buffer with current normalized volume to react immediately to sound\n volumeHistory = new Array(samplesPerQuarterSecond).fill(normalizedVolume);\n volumeSum = normalizedVolume * samplesPerQuarterSecond;\n } else {\n if (volumeHistory.length >= samplesPerQuarterSecond) {\n volumeSum -= volumeHistory.shift(); // Remove the oldest volume entry\n }\n volumeHistory.push(normalizedVolume);\n volumeSum += normalizedVolume;\n }\n\n\n let runningAverageVolume = volumeSum / volumeHistory.length;\n // console.log(`Current volume: ${normalizedVolume.toFixed(2)}, Running Average: ${runningAverageVolume.toFixed(2)}`);\n\n var shouldMute = runningAverageVolume > 0.1;\n\n if (shouldMute !== mutedViaHighVolume) {\n mutedViaHighVolume = shouldMute;\n if (simpleTeleconferenceService) {\n simpleTeleconferenceService.invokeMethod('JS_onAudioLevelRefresh', shouldMute);\n } else {\n console.error('simpleTeleconferenceService is null or undefined.');\n }\n }\n\n requestId = requestAnimationFrame(() => monitorAudio(videoElement, analyserNode, dataArray, volumeHistory, volumeSum));\n }\n\n pixelStreaming.addEventListener(\"videoInitialized\", () => {\n cleanupAudioResources(); // Clean up previous audio context if exists\n\n var videoElements = parent.getElementsByTagName('video');\n if (activePixelStreams.indexOf(pixelStreaming) < 0) {\n return;\n }\n\n if (videoElements && videoElements.length > 0) {\n const videoElement = videoElements[0];\n // Enable PIP mode for all browsers.\n if (videoElement && document.pictureInPictureEnabled) {\n videoElement.disablePictureInPicture = false;\n }\n\n currentAudioContext = new AudioContext();\n\n // A hack fix for the audiocontext to work on Chrome and Firefox\n const audioTracks = videoElement.srcObject.getAudioTracks();\n const audioStream = new MediaStream(audioTracks);\n const sourceNode = currentAudioContext.createMediaStreamSource(audioStream);\n\n const analyserNode = currentAudioContext.createAnalyser();\n\n sourceNode.connect(analyserNode);\n\n analyserNode.fftSize = 256;\n const bufferLength = analyserNode.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n\n let volumeHistory = [];\n let volumeSum = 0;\n\n // Start monitoring audio with the new check for the video element's existence\n monitorAudio(videoElement, analyserNode, dataArray, volumeHistory, volumeSum);\n }\n })\n\n pixelStreaming.addEventListener('webRtcConnected', () => {\n if (activePixelStreams.indexOf(pixelStreaming) < 0)\n return;\n dotNetObjectReference.invokeMethodAsync('PixelStreamingConnected');\n })\n\n pixelStreaming.addEventListener('webRtcDisconnected', (eventString, allowClickToReconnect) => {\n if (activePixelStreams.indexOf(pixelStreaming) < 0)\n return;\n dotNetObjectReference.invokeMethodAsync('PixelStreamingDisconnected');\n })\n\n return config;\n}\n\nfunction cleanupAudioResources() {\n console.log(\"Cleaning up audio resources\");\n if (currentAudioContext) {\n currentAudioContext.close(); // Close the audio context if it's open\n currentAudioContext = null;\n }\n cancelMonitorAudio();\n}\n\nfunction cancelMonitorAudio() {\n if (requestId) {\n cancelAnimationFrame(requestId);\n requestId = null;\n }\n}\n\nexport function RTS_PS_AllowInput(config, enableInput) {\n config.setFlagEnabled(Flags.MouseInput, enableInput);\n config.setFlagEnabled(Flags.KeyboardInput, enableInput);\n config.setFlagEnabled(Flags.TouchInput, false);\n config.setFlagEnabled(Flags.GamepadInput, false);\n config.setFlagEnabled(Flags.XRControllerInput, false);\n config.setFlagEnabled(Flags.HoveringMouseMode, false);\n}\n\nexport function RTS_PS_ClearAll() {\n activePixelStreams.forEach(pixelStreaming => {\n pixelStreaming.disconnect();\n });\n activePixelStreams = [];\n cleanupAudioResources(); // Clean up any remaining audio contexts\n}\n\nwindow.RTS_PS_Connect = RTS_PS_Connect;\nwindow.RTS_PS_AllowInput = RTS_PS_AllowInput;\nwindow.RTS_PS_ClearAll = RTS_PS_ClearAll;"],"names":[],"sourceRoot":""}