@yang__yj/pixelstreaming-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/library/dist/lib-pixelstreamingfrontend.esm.js +1 -0
  2. package/library/dist/lib-pixelstreamingfrontend.js +1 -0
  3. package/library/types/AFK/AFKController.d.ts +39 -0
  4. package/library/types/Config/Config.d.ts +217 -0
  5. package/library/types/Config/SettingBase.d.ts +30 -0
  6. package/library/types/Config/SettingFlag.d.ts +33 -0
  7. package/library/types/Config/SettingNumber.d.ts +45 -0
  8. package/library/types/Config/SettingOption.d.ts +43 -0
  9. package/library/types/Config/SettingText.d.ts +29 -0
  10. package/library/types/DataChannel/DataChannelController.d.ts +59 -0
  11. package/library/types/DataChannel/DataChannelSender.d.ts +21 -0
  12. package/library/types/DataChannel/InitialSettings.d.ts +44 -0
  13. package/library/types/DataChannel/LatencyTestResults.d.ts +31 -0
  14. package/library/types/FreezeFrame/FreezeFrame.d.ts +36 -0
  15. package/library/types/FreezeFrame/FreezeFrameController.d.ts +37 -0
  16. package/library/types/Inputs/FakeTouchController.d.ts +61 -0
  17. package/library/types/Inputs/GamepadController.d.ts +84 -0
  18. package/library/types/Inputs/GamepadTypes.d.ts +8 -0
  19. package/library/types/Inputs/HoveringMouseEvents.d.ts +56 -0
  20. package/library/types/Inputs/IMouseEvents.d.ts +53 -0
  21. package/library/types/Inputs/ITouchController.d.ts +24 -0
  22. package/library/types/Inputs/InputClassesFactory.d.ts +54 -0
  23. package/library/types/Inputs/KeyboardController.d.ts +57 -0
  24. package/library/types/Inputs/LockedMouseEvents.d.ts +80 -0
  25. package/library/types/Inputs/MouseButtons.d.ts +22 -0
  26. package/library/types/Inputs/MouseController.d.ts +75 -0
  27. package/library/types/Inputs/SpecialKeyCodes.d.ts +14 -0
  28. package/library/types/Inputs/TouchController.d.ts +53 -0
  29. package/library/types/Inputs/XRGamepadController.d.ts +15 -0
  30. package/library/types/Logger/Logger.d.ts +38 -0
  31. package/library/types/PeerConnectionController/AggregatedStats.d.ts +77 -0
  32. package/library/types/PeerConnectionController/CandidatePairStats.d.ts +15 -0
  33. package/library/types/PeerConnectionController/CandidateStat.d.ts +11 -0
  34. package/library/types/PeerConnectionController/CodecStats.d.ts +14 -0
  35. package/library/types/PeerConnectionController/DataChannelStats.d.ts +15 -0
  36. package/library/types/PeerConnectionController/InboundRTPStats.d.ts +141 -0
  37. package/library/types/PeerConnectionController/InboundTrackStats.d.ts +32 -0
  38. package/library/types/PeerConnectionController/OutBoundRTPStats.d.ts +23 -0
  39. package/library/types/PeerConnectionController/PeerConnectionController.d.ts +132 -0
  40. package/library/types/PeerConnectionController/SessionStats.d.ts +8 -0
  41. package/library/types/PeerConnectionController/StreamStats.d.ts +9 -0
  42. package/library/types/PixelStreaming/PixelStreaming.d.ts +234 -0
  43. package/library/types/UI/OnScreenKeyboard.d.ts +31 -0
  44. package/library/types/UeInstanceMessage/ResponseController.d.ts +19 -0
  45. package/library/types/UeInstanceMessage/SendDescriptorController.d.ts +28 -0
  46. package/library/types/UeInstanceMessage/SendMessageController.d.ts +18 -0
  47. package/library/types/UeInstanceMessage/StreamMessageController.d.ts +31 -0
  48. package/library/types/UeInstanceMessage/ToStreamerMessagesController.d.ts +32 -0
  49. package/library/types/UeInstanceMessage/TwoWayMap.d.ts +32 -0
  50. package/library/types/Util/CoordinateConverter.d.ts +100 -0
  51. package/library/types/Util/EventEmitter.d.ts +374 -0
  52. package/library/types/Util/EventListenerTracker.d.ts +14 -0
  53. package/library/types/Util/FileUtil.d.ts +32 -0
  54. package/library/types/Util/WebGLUtils.d.ts +4 -0
  55. package/library/types/Util/WebXRUtils.d.ts +9 -0
  56. package/library/types/VideoPlayer/StreamController.d.ts +24 -0
  57. package/library/types/VideoPlayer/VideoPlayer.d.ts +76 -0
  58. package/library/types/WebRtcPlayer/WebRtcPlayerController.d.ts +374 -0
  59. package/library/types/WebSockets/MessageReceive.d.ts +78 -0
  60. package/library/types/WebSockets/MessageSend.d.ts +98 -0
  61. package/library/types/WebSockets/SignallingProtocol.d.ts +15 -0
  62. package/library/types/WebSockets/WebSocketController.d.ts +96 -0
  63. package/library/types/WebXR/WebXRController.d.ts +26 -0
  64. package/library/types/pixelstreamingfrontend.d.ts +25 -0
  65. package/package.json +18 -0
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("sdp")):"function"==typeof define&&define.amd?define(["sdp"],t):"object"==typeof exports?exports["lib-pixelstreamingfrontend"]=t(require("sdp")):e["lib-pixelstreamingfrontend"]=t(e.sdp)}(this,(e=>(()=>{"use strict";var t={366:t=>{t.exports=e}},s={};function n(e){var r=s[e];if(void 0!==r)return r.exports;var i=s[e]={exports:{}};return t[e](i,i.exports,n),i.exports}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]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{n.r(r),n.d(r,{AfkLogic:()=>Se,AfkTimedOutEvent:()=>x,AfkWarningActivateEvent:()=>R,AfkWarningDeactivateEvent:()=>L,AfkWarningUpdateEvent:()=>k,AggregatedStats:()=>Pe,CandidatePairStats:()=>ye,CandidateStat:()=>Ee,Config:()=>me,ControlSchemeType:()=>pe,DataChannelCloseEvent:()=>B,DataChannelErrorEvent:()=>_,DataChannelOpenEvent:()=>z,DataChannelStats:()=>Te,EncoderSettings:()=>Oe,EventEmitter:()=>ie,Flags:()=>oe,HideFreezeFrameEvent:()=>j,InboundAudioStats:()=>Ce,InboundVideoStats:()=>fe,InitialSettings:()=>Fe,InitialSettingsEvent:()=>ee,LatencyTestResultEvent:()=>Z,LatencyTestResults:()=>Ge,LoadFreezeFrameEvent:()=>X,Logger:()=>e,MessageRecv:()=>p,MessageSend:()=>i,MessageStreamerList:()=>S,NumericParameters:()=>de,OptionParameters:()=>ge,OutBoundVideoStats:()=>be,PixelStreaming:()=>vt,PlayStreamErrorEvent:()=>Q,PlayStreamEvent:()=>$,PlayStreamRejectedEvent:()=>q,SettingBase:()=>y,SettingFlag:()=>b,SettingNumber:()=>M,SettingOption:()=>P,SettingText:()=>w,SettingsChangedEvent:()=>te,SignallingProtocol:()=>v,StatsReceivedEvent:()=>J,StreamLoadingEvent:()=>H,StreamPreConnectEvent:()=>V,StreamPreDisconnectEvent:()=>N,StreamReconnectEvent:()=>K,StreamerListMessageEvent:()=>Y,TextParameters:()=>ce,UnquantizedAndDenormalizeUnsigned:()=>lt,VideoEncoderAvgQPEvent:()=>A,VideoInitializedEvent:()=>W,WebRTCSettings:()=>Ue,WebRtcAutoConnectEvent:()=>D,WebRtcConnectedEvent:()=>U,WebRtcConnectingEvent:()=>O,WebRtcDisconnectedEvent:()=>I,WebRtcFailedEvent:()=>G,WebRtcPlayerController:()=>ht,WebRtcSdpEvent:()=>F,WebSocketController:()=>C,WebXRController:()=>pt,XrFrameEvent:()=>re,XrSessionEndedEvent:()=>ne,XrSessionStartedEvent:()=>se});class e{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)}}var t,s;e.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 i{payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}class o extends i{constructor(){super(),this.type=t.LIST_STREAMERS}}class a extends i{constructor(e){super(),this.type=t.SUBSCRIBE,this.streamerId=e}}class d extends i{constructor(){super(),this.type=t.UNSUBSCRIBE}}class l extends i{constructor(e){super(),this.type=t.PONG,this.time=e}}class c extends i{constructor(e){super(),this.type=t.OFFER,e&&(this.type=e.type,this.sdp=e.sdp)}}class h extends i{constructor(e){super(),this.type=t.ANSWER,e&&(this.type=e.type,this.sdp=e.sdp)}}class g extends i{constructor(){super(),this.type=t.DATACHANNELREQUEST}}class u extends i{constructor(){super(),this.type=t.SFURECVDATACHANNELREADY}}class m{constructor(e){this.type=t.ICE_CANDIDATE,this.candidate=e}payload(){return e.Log(e.GetStackTrace(),"Sending => \n"+JSON.stringify(this,void 0,4),6),JSON.stringify(this)}}!function(e){e.CONFIG="config",e.STREAMER_LIST="streamerList",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 p{}class S extends p{}class v{constructor(){this.FromUEMessageHandlers=new Map}addMessageHandler(e,t){this.FromUEMessageHandlers.set(e,t)}handleMessage(t,s){this.FromUEMessageHandlers.has(t)?this.FromUEMessageHandlers.get(t)(s):e.Error(e.GetStackTrace(),`Message type of ${t} does not have a message handler registered on the frontend - ignoring message.`)}static setupDefaultHandlers(t){t.signallingProtocol.addMessageHandler(s.PING,(n=>{const r=new l((new Date).getTime()).payload();e.Log(e.GetStackTrace(),s.PING+": "+n,6),t.webSocket.send(r)})),t.signallingProtocol.addMessageHandler(s.CONFIG,(n=>{e.Log(e.GetStackTrace(),s.CONFIG,6);const r=JSON.parse(n);t.onConfig(r)})),t.signallingProtocol.addMessageHandler(s.STREAMER_LIST,(n=>{e.Log(e.GetStackTrace(),s.STREAMER_LIST,6);const r=JSON.parse(n);t.onStreamerList(r)})),t.signallingProtocol.addMessageHandler(s.PLAYER_COUNT,(t=>{e.Log(e.GetStackTrace(),s.PLAYER_COUNT,6);const n=JSON.parse(t);e.Log(e.GetStackTrace(),"Player Count: "+n.count,6)})),t.signallingProtocol.addMessageHandler(s.ANSWER,(n=>{e.Log(e.GetStackTrace(),s.ANSWER,6);const r=JSON.parse(n);t.onWebRtcAnswer(r)})),t.signallingProtocol.addMessageHandler(s.OFFER,(n=>{e.Log(e.GetStackTrace(),s.OFFER,6);const r=JSON.parse(n);t.onWebRtcOffer(r)})),t.signallingProtocol.addMessageHandler(s.ICE_CANDIDATE,(n=>{e.Log(e.GetStackTrace(),s.ICE_CANDIDATE,6);const r=JSON.parse(n);t.onIceCandidate(r.candidate)})),t.signallingProtocol.addMessageHandler(s.WARNING,(t=>{e.Warning(e.GetStackTrace(),`Warning received: ${t}`)})),t.signallingProtocol.addMessageHandler(s.PEER_DATA_CHANNELS,(n=>{e.Log(e.GetStackTrace(),s.PEER_DATA_CHANNELS,6);const r=JSON.parse(n);t.onWebRtcPeerDataChannels(r)}))}}class C{constructor(){this.WS_OPEN_STATE=1,this.onOpen=new EventTarget,this.onClose=new EventTarget,this.signallingProtocol=new v,v.setupDefaultHandlers(this)}connect(t){e.Log(e.GetStackTrace(),t,6);try{return this.webSocket=new WebSocket(t),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(t){return e.Error(t,t),!1}}handleOnMessageBinary(t){t&&t.data&&t.data.text().then((e=>{const t=new MessageEvent("messageFromBinary",{data:e});this.handleOnMessage(t)})).catch((t=>{e.Error(e.GetStackTrace(),`Failed to parse binary blob from websocket, reason: ${t}`)}))}handleOnMessage(t){if(t.data&&t.data instanceof Blob)return void this.handleOnMessageBinary(t);const s=JSON.parse(t.data);e.Log(e.GetStackTrace(),"received => \n"+JSON.stringify(JSON.parse(t.data),void 0,4),6),this.signallingProtocol.handleMessage(s.type,t.data)}handleOnOpen(t){e.Log(e.GetStackTrace(),"Connected to the signalling server via WebSocket",6),this.onOpen.dispatchEvent(new Event("open"))}handleOnError(){e.Error(e.GetStackTrace(),"WebSocket error")}handleOnClose(t){this.onWebSocketOncloseOverlayMessage(t),e.Log(e.GetStackTrace(),"Disconnected to the signalling server via WebSocket: "+JSON.stringify(t.code)+" - "+t.reason),this.onClose.dispatchEvent(new CustomEvent("close",{detail:t}))}requestStreamerList(){const e=new o;this.webSocket.send(e.payload())}sendSubscribe(e){const t=new a(e);this.webSocket.send(t.payload())}sendUnsubscribe(){const e=new d;this.webSocket.send(e.payload())}sendWebRtcOffer(e){const t=new c(e);this.webSocket.send(t.payload())}sendWebRtcAnswer(e){const t=new h(e);this.webSocket.send(t.payload())}sendWebRtcDatachannelRequest(){const e=new g;this.webSocket.send(e.payload())}sendSFURecvDataChannelReady(){const e=new u;this.webSocket.send(e.payload())}sendIceCandidate(t){if(e.Log(e.GetStackTrace(),"Sending Ice Candidate"),this.webSocket&&this.webSocket.readyState===this.WS_OPEN_STATE){const e=new m(t);this.webSocket.send(e.payload())}}close(){var e;null===(e=this.webSocket)||void 0===e||e.close()}onWebSocketOncloseOverlayMessage(e){}onConfig(e){}onStreamerList(e){}onIceCandidate(e){}onWebRtcAnswer(e){}onWebRtcOffer(e){}onWebRtcPeerDataChannels(e){}}class f{constructor(e){this.videoElementProvider=e,this.audioElement=document.createElement("Audio")}handleOnTrack(t){e.Log(e.GetStackTrace(),"handleOnTrack "+JSON.stringify(t.streams),6);const s=this.videoElementProvider.getVideoElement();if(t.track&&e.Log(e.GetStackTrace(),"Got track - "+t.track.kind+" id="+t.track.id+" readyState="+t.track.readyState,6),"audio"!=t.track.kind)return"video"==t.track.kind&&s.srcObject!==t.streams[0]?(s.srcObject=t.streams[0],void e.Log(e.GetStackTrace(),"Set video source from video track ontrack.")):void 0;this.CreateAudioTrack(t.streams[0])}CreateAudioTrack(t){const s=this.videoElementProvider.getVideoElement();s.srcObject!=t&&s.srcObject&&s.srcObject!==t&&(this.audioElement.srcObject=t,e.Log(e.GetStackTrace(),"Created new audio element to play separate audio stream."))}}class T{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<i?(e=this.rootDiv.clientWidth,t=Math.floor(this.rootDiv.clientWidth/i),s=Math.floor(.5*(this.rootDiv.clientHeight-t)),n=0):(e=Math.floor(this.rootDiv.clientHeight*i),t=this.rootDiv.clientHeight,s=0,n=Math.floor(.5*(this.rootDiv.clientWidth-e))),this.rootElement.style.width=this.rootDiv.offsetWidth+"px",this.rootElement.style.height=this.rootDiv.offsetHeight+"px",this.rootElement.style.left="0px",this.rootElement.style.top="0px",this.imageElement.style.width=e+"px",this.imageElement.style.height=t+"px",this.imageElement.style.left=n+"px",this.imageElement.style.top=s+"px"}}}class E{constructor(e){this.receiving=!1,this.size=0,this.jpeg=void 0,this.valid=!1,this.freezeFrameDelay=50,this.freezeFrame=new T(e)}showFreezeFrame(){this.valid&&this.freezeFrame.setElementForShow()}hideFreezeFrame(){this.valid=!1,this.freezeFrame.setElementForHide()}updateFreezeFrameAndShow(e,t){this.freezeFrame.updateImageElementSource(e),this.freezeFrame.imageElement.onload=()=>{this.freezeFrame.setDimensionsFromElementAndResize(),t()}}processFreezeFrameMessage(t,s){this.receiving||(this.receiving=!0,this.valid=!1,this.size=0,this.jpeg=void 0),this.size=new DataView(t.slice(1,5).buffer).getInt32(0,!0);const n=t.slice(5);if(this.jpeg){const e=new Uint8Array(this.jpeg.length+n.length);e.set(this.jpeg,0),e.set(n,this.jpeg.length),this.jpeg=e}else this.jpeg=n,this.receiving=!0,e.Log(e.GetStackTrace(),`received first chunk of freeze frame: ${this.jpeg.length}/${this.size}`,6);this.jpeg.length===this.size?(this.receiving=!1,this.valid=!0,e.Log(e.GetStackTrace(),`received complete freeze frame ${this.size}`,6),this.updateFreezeFrameAndShow(this.jpeg,s)):this.jpeg.length>this.size&&(e.Error(e.GetStackTrace(),`received bigger freeze frame than advertised: ${this.jpeg.length}/${this.size}`),this.jpeg=void 0,this.receiving=!1)}}class y{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 b extends y{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.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 M extends y{constructor(e,t,s,n,r,i,o,a=(()=>{})){super(e,t,s,i,a),this._min=n,this._max=r;const d=new URLSearchParams(window.location.search);if(o&&d.has(this.id)){const e=Number.parseInt(d.get(this.id));this.number=Number.isNaN(e)?i:e}else this.number=i;this.useUrlParams=o}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 w extends y{constructor(e,t,s,n,r,i=(()=>{})){super(e,t,s,n,i);const o=new URLSearchParams(window.location.search);if(r&&o.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 y{constructor(e,t,s,n,r,i,o=(()=>{})){super(e,t,s,[n,n],o),this.options=r;const a=new URLSearchParams(window.location.search),d=i&&a.has(this.id)?this.getUrlParamText():n;this.selected=d,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){const t=this.options.filter((t=>-1!==t.indexOf(e)));t.length&&(this.value=t[0])}}class R extends Event{constructor(e){super("afkWarningActivate"),this.data=e}}class k extends Event{constructor(e){super("afkWarningUpdate"),this.data=e}}class L extends Event{constructor(){super("afkWarningDeactivate")}}class x extends Event{constructor(){super("afkTimedOut")}}class A extends Event{constructor(e){super("videoEncoderAvgQP"),this.data=e}}class F extends Event{constructor(){super("webRtcSdp")}}class D extends Event{constructor(){super("webRtcAutoConnect")}}class O extends Event{constructor(){super("webRtcConnecting")}}class U extends Event{constructor(){super("webRtcConnected")}}class G extends Event{constructor(){super("webRtcFailed")}}class I extends Event{constructor(e){super("webRtcDisconnected"),this.data=e}}class z extends Event{constructor(e){super("dataChannelOpen"),this.data=e}}class B extends Event{constructor(e){super("dataChannelClose"),this.data=e}}class _ extends Event{constructor(e){super("dataChannelError"),this.data=e}}class W extends Event{constructor(){super("videoInitialized")}}class H extends Event{constructor(){super("streamLoading")}}class V extends Event{constructor(){super("streamConnect")}}class N extends Event{constructor(){super("streamDisconnect")}}class K extends Event{constructor(){super("streamReconnect")}}class Q extends Event{constructor(e){super("playStreamError"),this.data=e}}class $ extends Event{constructor(){super("playStream")}}class q extends Event{constructor(e){super("playStreamRejected"),this.data=e}}class X extends Event{constructor(e){super("loadFreezeFrame"),this.data=e}}class j extends Event{constructor(){super("hideFreezeFrame")}}class J extends Event{constructor(e){super("statsReceived"),this.data=e}}class Y extends Event{constructor(e){super("streamerListMessage"),this.data=e}}class Z extends Event{constructor(e){super("latencyTestResult"),this.data=e}}class ee extends Event{constructor(e){super("initialSettings"),this.data=e}}class te extends Event{constructor(e){super("settingsChanged"),this.data=e}}class se extends Event{constructor(){super("xrSessionStarted")}}class ne extends Event{constructor(){super("xrSessionEnded")}}class re extends Event{constructor(e){super("xrFrame"),this.data=e}}class ie extends EventTarget{dispatchEvent(e){return super.dispatchEvent(e)}addEventListener(e,t){super.addEventListener(e,t)}removeEventListener(e,t){super.removeEventListener(e,t)}}class oe{}oe.AutoConnect="AutoConnect",oe.AutoPlayVideo="AutoPlayVideo",oe.AFKDetection="TimeoutIfIdle",oe.BrowserSendOffer="OfferToReceive",oe.HoveringMouseMode="HoveringMouse",oe.ForceMonoAudio="ForceMonoAudio",oe.ForceTURN="ForceTURN",oe.FakeMouseWithTouches="FakeMouseWithTouches",oe.IsQualityController="ControlsQuality",oe.MatchViewportResolution="MatchViewportRes",oe.PreferSFU="preferSFU",oe.StartVideoMuted="StartVideoMuted",oe.SuppressBrowserKeys="SuppressBrowserKeys",oe.UseMic="UseMic",oe.KeyboardInput="KeyboardInput",oe.MouseInput="MouseInput",oe.TouchInput="TouchInput",oe.GamepadInput="GamepadInput",oe.XRControllerInput="XRControllerInput";const ae=e=>Object.getOwnPropertyNames(oe).some((t=>oe[t]===e));class de{}de.AFKTimeoutSecs="AFKTimeout",de.MinQP="MinQP",de.MaxQP="MaxQP",de.WebRTCFPS="WebRTCFPS",de.WebRTCMinBitrate="WebRTCMinBitrate",de.WebRTCMaxBitrate="WebRTCMaxBitrate",de.MaxReconnectAttempts="MaxReconnectAttempts";const le=e=>Object.getOwnPropertyNames(de).some((t=>de[t]===e));class ce{}ce.SignallingServerUrl="ss";const he=e=>Object.getOwnPropertyNames(ce).some((t=>ce[t]===e));class ge{}ge.PreferredCodec="PreferredCodec",ge.StreamerId="StreamerId";const ue=e=>Object.getOwnPropertyNames(ge).some((t=>ge[t]===e));class me{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&&this.setSettings(t)}get useUrlParams(){return this._useUrlParams}populateDefaultSettings(e){this.textParameters.set(ce.SignallingServerUrl,new w(ce.SignallingServerUrl,"Signalling url","Url of the signalling server",("https:"===location.protocol?"wss://":"ws://")+window.location.hostname+("80"===window.location.port||""===window.location.port?"":`:${window.location.port}`),e)),this.optionParameters.set(ge.StreamerId,new P(ge.StreamerId,"Streamer ID","The ID of the streamer to stream.","",[],e)),this.optionParameters.set(ge.PreferredCodec,new P(ge.PreferredCodec,"Preferred Codec","The preferred codec to be used during codec negotiation","H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f",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(oe.AutoConnect,new b(oe.AutoConnect,"Auto connect to stream","Whether we should attempt to auto connect to the signalling server or show a click to start prompt.",!1,e)),this.flags.set(oe.AutoPlayVideo,new b(oe.AutoPlayVideo,"Auto play video","When video is ready automatically start playing it as opposed to showing a play button.",!0,e)),this.flags.set(oe.BrowserSendOffer,new b(oe.BrowserSendOffer,"Browser send offer","Browser will initiate the WebRTC handshake by sending the offer to the streamer",!1,e)),this.flags.set(oe.UseMic,new b(oe.UseMic,"Use microphone","Make browser request microphone access and open an input audio track.",!1,e)),this.flags.set(oe.StartVideoMuted,new b(oe.StartVideoMuted,"Start video muted","Video will start muted if true.",!1,e)),this.flags.set(oe.SuppressBrowserKeys,new b(oe.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.",!0,e)),this.flags.set(oe.PreferSFU,new b(oe.PreferSFU,"Prefer SFU","Try to connect to the SFU instead of P2P.",!1,e)),this.flags.set(oe.IsQualityController,new b(oe.IsQualityController,"Is quality controller?","True if this peer controls stream quality",!0,e)),this.flags.set(oe.ForceMonoAudio,new b(oe.ForceMonoAudio,"Force mono audio","Force browser to request mono audio in the SDP",!1,e)),this.flags.set(oe.ForceTURN,new b(oe.ForceTURN,"Force TURN","Only generate TURN/Relayed ICE candidates.",!1,e)),this.flags.set(oe.AFKDetection,new b(oe.AFKDetection,"AFK if idle","Timeout the experience if user is AFK for a period.",!1,e)),this.flags.set(oe.MatchViewportResolution,new b(oe.MatchViewportResolution,"Match viewport resolution","Pixel Streaming will be instructed to dynamically resize the video stream to match the size of the video element.",!1,e)),this.flags.set(oe.HoveringMouseMode,new b(oe.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.",!1,e,((e,t)=>{t.label=`Control Scheme: ${e?"Hovering":"Locked"} Mouse`}))),this.flags.set(oe.FakeMouseWithTouches,new b(oe.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.",!1,e)),this.flags.set(oe.KeyboardInput,new b(oe.KeyboardInput,"Keyboard input","If enabled, send keyboard events to streamer",!0,e)),this.flags.set(oe.MouseInput,new b(oe.MouseInput,"Mouse input","If enabled, send mouse events to streamer",!0,e)),this.flags.set(oe.TouchInput,new b(oe.TouchInput,"Touch input","If enabled, send touch events to streamer",!0,e)),this.flags.set(oe.GamepadInput,new b(oe.GamepadInput,"Gamepad input","If enabled, send gamepad events to streamer",!0,e)),this.flags.set(oe.XRControllerInput,new b(oe.XRControllerInput,"XR controller input","If enabled, send XR controller events to streamer",!0,e)),this.numericParameters.set(de.AFKTimeoutSecs,new M(de.AFKTimeoutSecs,"AFK timeout","The time (in seconds) it takes for the application to time out if AFK timeout is enabled.",0,600,120,e)),this.numericParameters.set(de.MaxReconnectAttempts,new M(de.MaxReconnectAttempts,"Max Reconnects","Maximum number of reconnects the application will attempt when a streamer disconnects.",0,999,3,e)),this.numericParameters.set(de.MinQP,new M(de.MinQP,"Min QP","The lower bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,0,e)),this.numericParameters.set(de.MaxQP,new M(de.MaxQP,"Max QP","The upper bound for the quantization parameter (QP) of the encoder. 0 = Best quality, 51 = worst quality.",0,51,51,e)),this.numericParameters.set(de.WebRTCFPS,new M(de.WebRTCFPS,"Max FPS","The maximum FPS that WebRTC will try to transmit frames at.",1,999,60,e)),this.numericParameters.set(de.WebRTCMinBitrate,new M(de.WebRTCMinBitrate,"Min Bitrate (kbps)","The minimum bitrate that WebRTC should use.",0,5e5,0,e)),this.numericParameters.set(de.WebRTCMaxBitrate,new M(de.WebRTCMaxBitrate,"Max Bitrate (kbps)","The maximum bitrate that WebRTC should use.",0,5e5,0,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(t,s){this.flags.has(t)?this.flags.get(t).flag=s:e.Warning(e.GetStackTrace(),`Cannot toggle flag called ${t} - it does not exist in the Config.flags map.`)}setTextSetting(t,s){this.textParameters.has(t)?this.textParameters.get(t).text=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.textParameters map.`)}setOptionSettingOptions(t,s){this.optionParameters.has(t)?this.optionParameters.get(t).options=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.optionParameters map.`)}setOptionSettingValue(t,s){this.optionParameters.has(t)?this.optionParameters.get(t).selected=s:e.Warning(e.GetStackTrace(),`Cannot set text setting called ${t} - it does not exist in the Config.enumParameters map.`)}setFlagLabel(t,s){this.flags.has(t)?this.flags.get(t).label=s:e.Warning(e.GetStackTrace(),`Cannot set label for flag called ${t} - it does not exist in the Config.flags map.`)}setSettings(e){for(const t of Object.keys(e))ae(t)?this.setFlagEnabled(t,e[t]):le(t)?this.setNumericSetting(t,e[t]):he(t)?this.setTextSetting(t,e[t]):ue(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 te({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 te({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 te({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 te({id:s.id,type:"option",value:t,target:s})))}}}var pe;!function(e){e[e.LockedMouse=0]="LockedMouse",e[e.HoveringMouse=1]="HoveringMouse"}(pe||(pe={}));class Se{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 L))}startAfkWarningTimer(){this.config.getNumericSettingValue(de.AFKTimeoutSecs)>0&&this.config.isFlagEnabled(oe.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(oe.AFKDetection)&&(clearTimeout(this.warnTimer),this.warnTimer=setTimeout((()=>this.activateAfkEvent()),1e3*this.config.getNumericSettingValue(de.AFKTimeoutSecs)))}activateAfkEvent(){this.pauseAfkWarningTimer(),this.pixelStreaming.dispatchEvent(new R({countDown:this.countDown,dismissAfk:this.onDismissAfk})),this.countDown=this.closeTimeout,this.countdownActive=!0,this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown})),this.config.isFlagEnabled(oe.HoveringMouseMode)||document.exitPointerLock&&document.exitPointerLock(),this.countDownTimer=setInterval((()=>{this.countDown--,0==this.countDown?(this.pixelStreaming.dispatchEvent(new x),this.onAFKTimedOutCallback(),e.Log(e.GetStackTrace(),"You have been disconnected due to inactivity"),this.stopAfkWarningTimer()):this.pixelStreaming.dispatchEvent(new k({countDown:this.countDown}))}),1e3)}}class ve{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(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) opened.`,7),this.onOpen(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnClose(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) closed.`,7),this.onClose(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}handleOnMessage(t){e.Log(e.GetStackTrace(),`Data Channel (${this.label}) message: ${t}`,8)}handleOnError(t){var s;e.Log(e.GetStackTrace(),`Data Channel (${this.label}) error: ${t}`,7),this.onError(null===(s=this.dataChannel)||void 0===s?void 0:s.label,t)}onOpen(e,t){}onClose(e,t){}onError(e,t){}}class Ce{}class fe{}class Te{}class Ee{}class ye{}class be{}class Me{}class we{}class Pe{constructor(){this.inboundVideoStats=new fe,this.inboundAudioStats=new Ce,this.candidatePair=new ye,this.DataChannelStats=new Te,this.outBoundVideoStats=new be,this.sessionStats=new Me,this.streamStats=new we,this.codecs=new Map}processStats(t){this.localCandidates=new Array,this.remoteCandidates=new Array,t.forEach((t=>{switch(t.type){case"candidate-pair":this.handleCandidatePair(t);break;case"certificate":case"media-source":case"media-playout":case"outbound-rtp":case"peer-connection":case"remote-inbound-rtp":case"transport":break;case"codec":this.handleCodec(t);break;case"data-channel":this.handleDataChannel(t);break;case"inbound-rtp":this.handleInBoundRTP(t);break;case"local-candidate":this.handleLocalCandidate(t);break;case"remote-candidate":this.handleRemoteCandidate(t);break;case"remote-outbound-rtp":this.handleRemoteOutBound(t);break;case"track":this.handleTrack(t);break;case"stream":this.handleStream(t);break;default:e.Error(e.GetStackTrace(),"unhandled Stat Type"),e.Log(e.GetStackTrace(),t)}}))}handleStream(e){this.streamStats=e}handleCandidatePair(e){this.candidatePair.bytesReceived=e.bytesReceived,this.candidatePair.bytesSent=e.bytesSent,this.candidatePair.localCandidateId=e.localCandidateId,this.candidatePair.remoteCandidateId=e.remoteCandidateId,this.candidatePair.nominated=e.nominated,this.candidatePair.readable=e.readable,this.candidatePair.selected=e.selected,this.candidatePair.writable=e.writable,this.candidatePair.state=e.state,this.candidatePair.currentRoundTripTime=e.currentRoundTripTime}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 Ee;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.candidateType=e.candidateType,t.id=e.id,this.localCandidates.push(t)}handleRemoteCandidate(e){const t=new Ee;t.label="local-candidate",t.address=e.address,t.port=e.port,t.protocol=e.protocol,t.id=e.id,t.candidateType=e.candidateType,this.remoteCandidates.push(t)}handleInBoundRTP(t){switch(t.kind){case"video":this.inboundVideoStats=t,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=t,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:e.Log(e.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)}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)}}var Re,ke,Le=n(366),xe=function(e,t,s,n){return new(s||(s=Promise))((function(r,i){function o(e){try{d(n.next(e))}catch(e){i(e)}}function a(e){try{d(n.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?r(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}d((n=n.apply(e,t||[])).next())}))};class Ae{constructor(e,t,s){this.config=t,this.createPeerConnection(e,s)}createPeerConnection(t,s){this.config.isFlagEnabled(oe.ForceTURN)&&(t.iceTransportPolicy="relay",e.Log(e.GetStackTrace(),"Forcing TURN usage by setting ICE Transport Policy in peer connection config.")),this.peerConnection=new RTCPeerConnection(t),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 Pe,this.preferredCodec=s,this.updateCodecSelection=!0}createOffer(t,s){return xe(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Create Offer",6);const n="localhost"===location.hostname||"127.0.0.1"===location.hostname,r="https:"===location.protocol;let i=s.isFlagEnabled(oe.UseMic);!i||n||r||(i=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.GetStackTrace(),"For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'")),this.setupTransceiversAsync(i).finally((()=>{var e;null===(e=this.peerConnection)||void 0===e||e.createOffer(t).then((e=>{var t;this.showTextOverlayConnecting(),e.sdp=this.mungeSDP(e.sdp,i),null===(t=this.peerConnection)||void 0===t||t.setLocalDescription(e),this.onSendWebRTCOffer(e)})).catch((()=>{this.showTextOverlaySetupFailure()}))}))}))}receiveOffer(t,s){var n;return xe(this,void 0,void 0,(function*(){e.Log(e.GetStackTrace(),"Receive Offer",6),null===(n=this.peerConnection)||void 0===n||n.setRemoteDescription(t).then((()=>{const t="localhost"===location.hostname||"127.0.0.1"===location.hostname,n="https:"===location.protocol;let r=s.isFlagEnabled(oe.UseMic);!r||t||n||(r=!1,e.Error(e.GetStackTrace(),"Microphone access in the browser will not work if you are not on HTTPS or localhost. Disabling mic access."),e.Error(e.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.createAnswer().then((e=>{var t;return e.sdp=this.mungeSDP(e.sdp,r),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((()=>{e.Error(e.GetStackTrace(),"createAnswer() failed")}))}))})),this.config.setOptionSettingOptions(ge.PreferredCodec,this.parseAvailableCodecs(t).filter((e=>this.config.getSettingOption(ge.PreferredCodec).options.includes(e))))}))}receiveAnswer(e){var t;null===(t=this.peerConnection)||void 0===t||t.setRemoteDescription(e),this.config.setOptionSettingOptions(ge.PreferredCodec,this.parseAvailableCodecs(e).filter((e=>this.config.getSettingOption(ge.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.config.setOptionSettingValue(ge.PreferredCodec,this.aggregatedStats.codecs.get(this.aggregatedStats.inboundVideoStats.codecId))}))}close(){this.peerConnection&&(this.peerConnection.close(),this.peerConnection=null)}mungeSDP(e,t){const s=e;s.replace(/(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n/gm,"$1;x-google-start-bitrate=10000;x-google-max-bitrate=100000\r\n");let n="";return n+="maxaveragebitrate=510000;",t&&(n+="sprop-maxcapturerate=48000;"),n+=this.config.isFlagEnabled(oe.ForceMonoAudio)?"stereo=0;":"stereo=1;",n+="useinbandfec=1",s.replace("useinbandfec=1",n),s}handleOnIce(t){var s;e.Log(e.GetStackTrace(),"peerconnection handleOnIce",6),this.config.isFlagEnabled(oe.ForceTURN)&&t.candidate.indexOf("relay")<0?e.Info(e.GetStackTrace(),`Dropping candidate because it was not TURN relay. | Type= ${t.type} | Protocol= ${t.protocol} | Address=${t.address} | Port=${t.port} |`,6):null===(s=this.peerConnection)||void 0===s||s.addIceCandidate(t)}handleSignalStateChange(t){e.Log(e.GetStackTrace(),"signaling state change: "+t,6)}handleIceConnectionStateChange(t){e.Log(e.GetStackTrace(),"ice connection state change: "+t,6),this.onIceConnectionStateChange(t)}handleIceGatheringStateChange(t){e.Log(e.GetStackTrace(),"ice gathering state change: "+JSON.stringify(t),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,o,a,d,l;return xe(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){const t=this.preferredCodec.split(" "),s=[{mimeType:"video/"+t[0],clockRate:9e4,sdpFmtpLine:t[1]?t[1]:""}];this.config.getSettingOption(ge.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 t={video:!1,audio:!!e&&{autoGainControl:!1,channelCount:1,echoCancellation:!1,latency:0,noiseSuppression:!1,sampleRate:48e3,sampleSize:16,volume:1}},s=yield navigator.mediaDevices.getUserMedia(t);if(s)if(c){for(const e of null!==(a=null===(o=this.peerConnection)||void 0===o?void 0:o.getTransceivers())&&void 0!==a?a:[])if(e&&e.receiver&&e.receiver.track&&"audio"===e.receiver.track.kind)for(const t of s.getTracks())t.kind&&"audio"==t.kind&&(e.sender.replaceTrack(t),e.direction="sendrecv")}else for(const e of s.getTracks())e.kind&&"audio"==e.kind&&(null===(d=this.peerConnection)||void 0===d||d.addTransceiver(e,{direction:"sendrecv"}));else null===(l=this.peerConnection)||void 0===l||l.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,Le.splitSections)(e.sdp);return s.shift(),s.forEach((e=>{const{codecs:s}=(0,Le.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 Fe{constructor(){this.PixelStreamingSettings=new De,this.EncoderSettings=new Oe,this.WebRTCSettings=new Ue}ueCompatible(){null!=this.WebRTCSettings.MaxFPS&&(this.WebRTCSettings.FPS=this.WebRTCSettings.MaxFPS)}}class De{}class Oe{}class Ue{}class Ge{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||(e.Log(e.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||(e.Log(e.GetStackTrace(),`Setting CaptureToSendMs Ms \n ${this.PostCaptureTimeMs} \n ${this.PreCaptureTimeMs}`,6),this.CaptureToSendMs=this.PostCaptureTimeMs-this.PreCaptureTimeMs)}}class Ie{static setExtensionFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.extension=n}static setMimeTypeFromBytes(t,s){s.receiving||(s.mimetype="",s.extension="",s.receiving=!0,s.valid=!1,s.size=0,s.data=[],s.timestampStart=(new Date).getTime(),e.Log(e.GetStackTrace(),"Received first chunk of file",6));const n=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),n,6),s.mimetype=n}static setContentsFromBytes(t,s){if(!s.receiving)return;s.size=Math.ceil(new DataView(t.slice(1,5).buffer).getInt32(0,!0)/16379);const n=t.slice(5);if(s.data.push(n),e.Log(e.GetStackTrace(),`Received file chunk: ${s.data.length}/${s.size}`,6),s.data.length===s.size){s.receiving=!1,s.valid=!0,e.Log(e.GetStackTrace(),"Received complete file",6);const t=(new Date).getTime()-s.timestampStart,n=Math.round(16*s.size*1024/t);e.Log(e.GetStackTrace(),`Average transfer bitrate: ${n}kb/s over ${t/1e3} seconds`,6);const r=new Blob(s.data,{type:s.mimetype}),i=document.createElement("a");i.setAttribute("href",URL.createObjectURL(r)),i.setAttribute("download",`transfer.${s.extension}`),document.body.append(i),i.remove()}else s.data.length>s.size&&(s.receiving=!1,e.Error(e.GetStackTrace(),`Received bigger file than advertised: ${s.data.length}/${s.size}`))}}class ze{constructor(){this.mimetype="",this.extension="",this.receiving=!1,this.size=0,this.data=[],this.valid=!1}}class Be{}Be.mainButton=0,Be.auxiliaryButton=1,Be.secondaryButton=2,Be.fourthButton=3,Be.fifthButton=4;class _e{}_e.primaryButton=1,_e.secondaryButton=2,_e.auxiliaryButton=4,_e.fourthButton=8,_e.fifthButton=16;class We{constructor(){this.unregisterCallbacks=[]}addUnregisterCallback(e){this.unregisterCallbacks.push(e)}unregisterAll(){for(const e of this.unregisterCallbacks)e();this.unregisterCallbacks=[]}}class He{constructor(e,t,s){this.touchEventListenerTracker=new We,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()){if(null==this.fakeTouchFinger){const t=e.changedTouches[0];this.fakeTouchFinger=new Ve(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")([Be.mainButton,r.x,r.y])}e.preventDefault()}}onTouchEnd(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.videoElementProvider.getVideoParentElement(),s=this.toStreamerMessagesProvider.toStreamerHandlers;for(let n=0;n<e.changedTouches.length;n++){const r=e.changedTouches[n];if(r.identifier===this.fakeTouchFinger.id){const e=r.clientX-this.videoElementParentClientRect.left,n=r.clientY-this.videoElementParentClientRect.top,i=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,n);s.get("MouseUp")([Be.mainButton,i.x,i.y]);const o=new MouseEvent("mouseleave",r);t.dispatchEvent(o),this.fakeTouchFinger=null;break}}e.preventDefault()}onTouchMove(e){if(!this.videoElementProvider.isVideoReady())return;const t=this.toStreamerMessagesProvider.toStreamerHandlers;for(let s=0;s<e.touches.length;s++){const n=e.touches[s];if(n.identifier===this.fakeTouchFinger.id){const e=n.clientX-this.videoElementParentClientRect.left,s=n.clientY-this.videoElementParentClientRect.top,r=this.coordinateConverter.normalizeAndQuantizeUnsigned(e,s),i=this.coordinateConverter.normalizeAndQuantizeSigned(e-this.fakeTouchFinger.x,s-this.fakeTouchFinger.y);t.get("MouseMove")([r.x,r.y,i.x,i.y]),this.fakeTouchFinger.x=e,this.fakeTouchFinger.y=s;break}}e.preventDefault()}}class Ve{constructor(e,t,s){this.id=e,this.x=t,this.y=s}}class Ne{}Ne.backSpace=8,Ne.shift=16,Ne.control=17,Ne.alt=18,Ne.rightShift=253,Ne.rightControl=254,Ne.rightAlt=255;class Ke{constructor(e,t,s){this.keyboardEventListenerTracker=new We,this.CodeToKeyCode={Escape:27,Digit0:48,Digit1:49,Digit2:50,Digit3:51,Digit4:52,Digit5:53,Digit6:54,Digit7:55,Digit8:56,Digit9:57,Minus:173,Equal:187,Backspace:8,Tab:9,KeyQ:81,KeyW:87,KeyE:69,KeyR:82,KeyT:84,KeyY:89,KeyU:85,KeyI:73,KeyO:79,KeyP:80,BracketLeft:219,BracketRight:221,Enter:13,ControlLeft:17,KeyA:65,KeyS:83,KeyD:68,KeyF:70,KeyG:71,KeyH:72,KeyJ:74,KeyK:75,KeyL:76,Semicolon:186,Quote:222,Backquote:192,ShiftLeft:16,Backslash:220,KeyZ:90,KeyX:88,KeyC:67,KeyV:86,KeyB:66,KeyN:78,KeyM:77,Comma:188,Period:190,Slash:191,ShiftRight:253,AltLeft:18,Space:32,CapsLock:20,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,Pause:19,ScrollLock:145,NumpadDivide:111,NumpadMultiply:106,NumpadSubtract:109,NumpadAdd:107,NumpadDecimal:110,Numpad9:105,Numpad8:104,Numpad7:103,Numpad6:102,Numpad5:101,Numpad4:100,Numpad3:99,Numpad2:98,Numpad1:97,Numpad0:96,NumLock:144,ControlRight:254,AltRight:255,Home:36,End:35,ArrowUp:38,ArrowLeft:37,ArrowRight:39,ArrowDown:40,PageUp:33,PageDown:34,Insert:45,Delete:46,ContextMenu:93},this.toStreamerMessagesProvider=e,this.config=t,this.activeKeysProvider=s}registerKeyBoardEvents(){const e=e=>this.handleOnKeyDown(e),t=e=>this.handleOnKeyUp(e),s=e=>this.handleOnKeyPress(e);document.addEventListener("keydown",e),document.addEventListener("keyup",t),document.addEventListener("keypress",s),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keydown",e))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keyup",t))),this.keyboardEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("keypress",s)))}unregisterKeyBoardEvents(){this.keyboardEventListenerTracker.unregisterAll()}handleOnKeyDown(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key down ${s}, repeat = ${t.repeat}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyDown")([this.getKeycode(t),t.repeat?1:0]),this.activeKeysProvider.getActiveKeys().push(s),s===Ne.backSpace&&document.dispatchEvent(new KeyboardEvent("keypress",{charCode:Ne.backSpace})),this.config.isFlagEnabled(oe.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyUp(t){const s=this.getKeycode(t);s&&(e.Log(e.GetStackTrace(),`key up ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyUp")([s,t.repeat?1:0]),this.config.isFlagEnabled(oe.SuppressBrowserKeys)&&this.isKeyCodeBrowserKey(s)&&t.preventDefault())}handleOnKeyPress(t){if(!("charCode"in t))return void e.Warning(e.GetStackTrace(),"KeyboardEvent.charCode is deprecated in this browser, cannot send key press.");const s=t.charCode;e.Log(e.GetStackTrace(),`key press ${s}`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("KeyPress")([s])}getKeycode(t){if(!("keyCode"in t)){const s=t;return s.code in this.CodeToKeyCode?this.CodeToKeyCode[s.code]:(e.Warning(e.GetStackTrace(),`Keyboard code of ${s.code} is not supported in our mapping, ignoring this key.`),null)}return t.keyCode===Ne.shift&&"ShiftRight"===t.code?Ne.rightShift:t.keyCode===Ne.control&&"ControlRight"===t.code?Ne.rightControl:t.keyCode===Ne.alt&&"AltRight"===t.code?Ne.rightAlt:t.keyCode}isKeyCodeBrowserKey(e){return e>=112&&e<=123||9===e}}class Qe{constructor(e,t,s){this.x=0,this.y=0,this.updateMouseMovePositionEvent=e=>{this.updateMouseMovePosition(e)},this.mouseEventListenerTracker=new We,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 t=this.videoElementProvider.getVideoParentElement(),s=this.mouseController.toStreamerMessagesProvider.toStreamerHandlers;if(document.pointerLockElement===t||document.mozPointerLockElement===t)e.Log(e.GetStackTrace(),"Pointer locked",6),document.addEventListener("mousemove",this.updateMouseMovePositionEvent,!1),this.mouseEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1)));else{e.Log(e.GetStackTrace(),"The pointer lock status is now unlocked",6),document.removeEventListener("mousemove",this.updateMouseMovePositionEvent,!1);let t=this.activeKeysProvider.getActiveKeys();const n=new Set(t),r=[];n.forEach((e=>{r[e]})),r.forEach((e=>{s.get("KeyUp")([e])})),t=[]}}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 $e{constructor(e){this.mouseController=e}unregisterMouseEvents(){}updateMouseMovePosition(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"MouseMove",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY),n=this.mouseController.coordinateConverter.normalizeAndQuantizeSigned(t.movementX,t.movementY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseMove")([s.x,s.y,n.x,n.y]),t.preventDefault()}handleMouseDown(t){if(!this.mouseController.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),"onMouse Down",6);const s=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(t.offsetX,t.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t.button,s.x,s.y]),t.preventDefault()}handleMouseUp(e){if(!this.mouseController.videoElementProvider.isVideoReady())return;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){if(!this.mouseController.videoElementProvider.isVideoReady())return;const t=this.mouseController.coordinateConverter.normalizeAndQuantizeUnsigned(e.offsetX,e.offsetY);this.mouseController.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([e.button,t.x,t.y]),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()&&this.mouseController.pressMouseButtons(e.buttons,e.offsetX,e.offsetY)}handleReleaseMouseButtons(e){this.mouseController.videoElementProvider.isVideoReady()&&this.mouseController.releaseMouseButtons(e.buttons,e.offsetX,e.offsetY)}}class qe{constructor(e,t,s,n){this.mouseEventListenerTracker=new We,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 Qe(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),o=e=>s.handleMouseWheel(e),a=e=>s.handleMouseDouble(e);t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("wheel",o),t.addEventListener("dblclick",a),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mousedown",r))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseup",i))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",a))),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 $e(e),n=e=>s.updateMouseMovePosition(e),r=e=>s.handleMouseDown(e),i=e=>s.handleMouseUp(e),o=e=>s.handleContextMenu(e),a=e=>s.handleMouseWheel(e),d=e=>s.handleMouseDouble(e);t.addEventListener("mousemove",n),t.addEventListener("mousedown",r),t.addEventListener("mouseup",i),t.addEventListener("contextmenu",o),t.addEventListener("wheel",a),t.addEventListener("dblclick",d),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",o))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("wheel",a))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("dblclick",d))),this.mouseEventListenerTracker.addUnregisterCallback((()=>s.unregisterMouseEvents()))}registerMouseEnterAndLeaveEvents(){const t=this.videoElementProvider.getVideoParentElement(),s=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Entered",6),this.sendMouseEnter(),this.pressMouseButtons(t.buttons,t.x,t.y))},n=t=>{this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"Mouse Left",6),this.sendMouseLeave(),this.releaseMouseButtons(t.buttons,t.x,t.y))};t.addEventListener("mouseenter",s),t.addEventListener("mouseleave",n),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseenter",s))),this.mouseEventListenerTracker.addUnregisterCallback((()=>t.removeEventListener("mouseleave",n)))}releaseMouseButtons(e,t,s){const n=this.coordinateConverter.normalizeAndQuantizeUnsigned(t,s);e&_e.primaryButton&&this.sendMouseUp(Be.mainButton,n.x,n.y),e&_e.secondaryButton&&this.sendMouseUp(Be.secondaryButton,n.x,n.y),e&_e.auxiliaryButton&&this.sendMouseUp(Be.auxiliaryButton,n.x,n.y),e&_e.fourthButton&&this.sendMouseUp(Be.fourthButton,n.x,n.y),e&_e.fifthButton&&this.sendMouseUp(Be.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(Be.mainButton,n.x,n.y),e&_e.secondaryButton&&this.sendMouseDown(Be.secondaryButton,n.x,n.y),e&_e.auxiliaryButton&&this.sendMouseDown(Be.auxiliaryButton,n.x,n.y),e&_e.fourthButton&&this.sendMouseDown(Be.fourthButton,n.x,n.y),e&_e.fifthButton&&this.sendMouseDown(Be.fifthButton,n.x,n.y)}sendMouseEnter(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseEnter")()}sendMouseLeave(){this.videoElementProvider.isVideoReady()&&this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseLeave")()}sendMouseDown(t,s,n){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),`mouse button ${t} down at (${s}, ${n})`,6),this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseDown")([t,s,n]))}sendMouseUp(t,s,n){if(!this.videoElementProvider.isVideoReady())return;e.Log(e.GetStackTrace(),`mouse button ${t} up at (${s}, ${n})`,6);const r=this.coordinateConverter.normalizeAndQuantizeUnsigned(s,n);this.toStreamerMessagesProvider.toStreamerHandlers.get("MouseUp")([t,r.x,r.y])}}class Xe{constructor(t,s,n){this.fingers=[9,8,7,6,5,4,3,2,1,0],this.fingerIds=new Map,this.maxByteValue=255,this.touchEventListenerTracker=new We,this.toStreamerMessagesProvider=t,this.videoElementProvider=s,this.coordinateConverter=n,this.videoElementParent=s.getVideoElement();const r=e=>this.onTouchStart(e),i=e=>this.onTouchEnd(e),o=e=>this.onTouchMove(e);this.videoElementParent.addEventListener("touchstart",r),this.videoElementParent.addEventListener("touchend",i),this.videoElementParent.addEventListener("touchmove",o),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchstart",r))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchend",i))),this.touchEventListenerTracker.addUnregisterCallback((()=>this.videoElementParent.removeEventListener("touchmove",o))),e.Log(e.GetStackTrace(),"Touch Events Registered",6);const a=e=>{e.preventDefault()};document.addEventListener("touchmove",a),this.touchEventListenerTracker.addUnregisterCallback((()=>document.removeEventListener("touchmove",a)))}unregisterTouchEvents(){this.touchEventListenerTracker.unregisterAll()}rememberTouch(t){const s=this.fingers.pop();void 0===s&&e.Log(e.GetStackTrace(),"exhausted touch identifiers",6),this.fingerIds.set(t.identifier,s)}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(t){if(this.videoElementProvider.isVideoReady()){for(let e=0;e<t.changedTouches.length;e++)this.rememberTouch(t.changedTouches[e]);e.Log(e.GetStackTrace(),"touch start",6),this.emitTouchData("TouchStart",t.changedTouches),t.preventDefault()}}onTouchEnd(t){if(this.videoElementProvider.isVideoReady()){e.Log(e.GetStackTrace(),"touch end",6),this.emitTouchData("TouchEnd",t.changedTouches);for(let e=0;e<t.changedTouches.length;e++)this.forgetTouch(t.changedTouches[e]);t.preventDefault()}}onTouchMove(t){this.videoElementProvider.isVideoReady()&&(e.Log(e.GetStackTrace(),"touch move",6),this.emitTouchData("TouchMove",t.touches),t.preventDefault())}emitTouchData(t,s){if(!this.videoElementProvider.isVideoReady())return;const n=this.videoElementProvider.getVideoParentElement(),r=this.toStreamerMessagesProvider.toStreamerHandlers;for(let i=0;i<s.length;i++){const o=1,a=s[i],d=a.clientX-n.offsetLeft,l=a.clientY-n.offsetTop;e.Log(e.GetStackTrace(),`F${this.fingerIds.get(a.identifier)}=(${d}, ${l})`,6);const c=this.coordinateConverter.normalizeAndQuantizeUnsigned(d,l);switch(t){case"TouchStart":r.get("TouchStart")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchEnd":r.get("TouchEnd")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0]);break;case"TouchMove":r.get("TouchMove")([o,c.x,c.y,this.fingerIds.get(a.identifier),this.maxByteValue*a.force,c.inRange?1:0])}}}}class je{constructor(e){this.gamePadEventListenerTracker=new We,this.toStreamerMessagesProvider=e,this.requestAnimationFrame=(window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.requestAnimationFrame).bind(window);const t=window;if("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(t){e.Log(e.GetStackTrace(),"Gamepad connect handler",6);const s=t.gamepad,n={currentState:s,prevState:s,id:void 0};this.controllers.push(n),this.controllers[s.index].currentState=s,this.controllers[s.index].prevState=s,e.Log(e.GetStackTrace(),"gamepad: "+s.id+" connected",6),window.requestAnimationFrame((()=>this.updateStatus())),this.onGamepadConnected()}gamePadDisconnectHandler(t){e.Log(e.GetStackTrace(),"Gamepad disconnect handler",6),e.Log(e.GetStackTrace(),"gamepad: "+t.gamepad.id+" disconnected",6);const s=this.controllers[t.gamepad.index];delete this.controllers[t.gamepad.index],this.controllers=this.controllers.filter((e=>void 0!==e)),this.onGamepadDisconnected(s.id)}scanGamePads(){const e=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():[];for(let t=0;t<e.length;t++)e[t]&&e[t].index in this.controllers&&(this.controllers[e[t].index].currentState=e[t])}updateStatus(){this.scanGamePads();const e=this.toStreamerMessagesProvider.toStreamerHandlers;for(const t of this.controllers){const s=void 0===t.id?this.controllers.indexOf(t):t.id,n=t.currentState;for(let n=0;n<t.currentState.buttons.length;n++){const r=t.currentState.buttons[n],i=t.prevState.buttons[n];r.pressed?n==Re.LeftTrigger?e.get("GamepadAnalog")([s,5,r.value]):n==Re.RightTrigger?e.get("GamepadAnalog")([s,6,r.value]):e.get("GamepadButtonPressed")([s,n,i.pressed?1:0]):!r.pressed&&i.pressed&&(n==Re.LeftTrigger?e.get("GamepadAnalog")([s,5,0]):n==Re.RightTrigger?e.get("GamepadAnalog")([s,6,0]):e.get("GamepadButtonReleased")([s,n]))}for(let t=0;t<n.axes.length;t+=2){const r=parseFloat(n.axes[t].toFixed(4)),i=-parseFloat(n.axes[t+1].toFixed(4));e.get("GamepadAnalog")([s,t+1,r]),e.get("GamepadAnalog")([s,t+2,i])}this.controllers[s].prevState=n}this.controllers.length>0&&this.requestAnimationFrame((()=>this.updateStatus()))}onGamepadResponseReceived(e){for(const t of this.controllers)if(void 0===t.id){t.id=e;break}}onGamepadConnected(){}onGamepadDisconnected(e){}}!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"}(Re||(Re={}));class Je{constructor(e,t,s){this.activeKeys=new Ye,this.toStreamerMessagesProvider=e,this.videoElementProvider=t,this.coordinateConverter=s}registerKeyBoard(t){e.Log(e.GetStackTrace(),"Register Keyboard Events",7);const s=new Ke(this.toStreamerMessagesProvider,t,this.activeKeys);return s.registerKeyBoardEvents(),s}registerMouse(t){e.Log(e.GetStackTrace(),"Register Mouse Events",7);const s=new qe(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter,this.activeKeys);switch(t){case pe.LockedMouse:s.registerLockedMouseEvents(s);break;case pe.HoveringMouse:s.registerHoveringMouseEvents(s);break;default:e.Info(e.GetStackTrace(),"unknown Control Scheme Type Defaulting to Locked Mouse Events"),s.registerLockedMouseEvents(s)}return s}registerTouch(t,s){if(e.Log(e.GetStackTrace(),"Registering Touch",6),t){const e=new He(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter);return e.setVideoElementParentClientRect(s),e}return new Xe(this.toStreamerMessagesProvider,this.videoElementProvider,this.coordinateConverter)}registerGamePad(){return e.Log(e.GetStackTrace(),"Register Game Pad",7),new je(this.toStreamerMessagesProvider)}}class Ye{constructor(){this.activeKeys=[],this.activeKeys=[]}getActiveKeys(){return this.activeKeys}}class Ze{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=()=>{this.videoElement.paused&&this.videoElement.play()},this.videoElement.onloadedmetadata=()=>{this.onVideoInitialized()},window.addEventListener("resize",(()=>this.resizePlayerStyle()),!0),window.addEventListener("orientationchange",(()=>this.onOrientationChange()))}play(){return this.videoElement.muted=this.config.isFlagEnabled(oe.StartVideoMuted),this.videoElement.autoplay=this.config.isFlagEnabled(oe.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(oe.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 e.Log(e.GetStackTrace(),"Resizing too often - skipping",6),clearTimeout(this.resizeTimeoutHandle),this.resizeTimeoutHandle=window.setTimeout((()=>this.updateVideoStreamSize()),100)}}class et{constructor(){this.map=new Map,this.reverseMap=new Map}getFromKey(e){return this.map.get(e)}getFromValue(e){return this.reverseMap.get(e)}add(e,t){this.map.set(e,t),this.reverseMap.set(t,e)}remove(e,t){this.map.delete(e),this.reverseMap.delete(t)}}class tt{constructor(){this.toStreamerHandlers=new Map,this.fromStreamerHandlers=new Map,this.toStreamerMessages=new et,this.fromStreamerMessages=new et}populateDefaultProtocol(){this.toStreamerMessages.add("IFrameRequest",{id:0,byteLength:0,structure:[]}),this.toStreamerMessages.add("RequestQualityControl",{id:1,byteLength:0,structure:[]}),this.toStreamerMessages.add("FpsRequest",{id:2,byteLength:0,structure:[]}),this.toStreamerMessages.add("AverageBitrateRequest",{id:3,byteLength:0,structure:[]}),this.toStreamerMessages.add("StartStreaming",{id:4,byteLength:0,structure:[]}),this.toStreamerMessages.add("StopStreaming",{id:5,byteLength:0,structure:[]}),this.toStreamerMessages.add("LatencyTest",{id:6,byteLength:0,structure:[]}),this.toStreamerMessages.add("RequestInitialSettings",{id:7,byteLength:0,structure:[]}),this.toStreamerMessages.add("TestEcho",{id:8,byteLength:0,structure:[]}),this.toStreamerMessages.add("UIInteraction",{id:50,byteLength:0,structure:[]}),this.toStreamerMessages.add("Command",{id:51,byteLength:0,structure:[]}),this.toStreamerMessages.add("KeyDown",{id:60,byteLength:2,structure:["uint8","uint8"]}),this.toStreamerMessages.add("KeyUp",{id:61,byteLength:1,structure:["uint8"]}),this.toStreamerMessages.add("KeyPress",{id:62,byteLength:2,structure:["uint16"]}),this.toStreamerMessages.add("MouseEnter",{id:70,byteLength:0,structure:[]}),this.toStreamerMessages.add("MouseLeave",{id:71,byteLength:0,structure:[]}),this.toStreamerMessages.add("MouseDown",{id:72,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("MouseUp",{id:73,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("MouseMove",{id:74,byteLength:8,structure:["uint16","uint16","int16","int16"]}),this.toStreamerMessages.add("MouseWheel",{id:75,byteLength:6,structure:["int16","uint16","uint16"]}),this.toStreamerMessages.add("MouseDouble",{id:76,byteLength:5,structure:["uint8","uint16","uint16"]}),this.toStreamerMessages.add("TouchStart",{id:80,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("TouchEnd",{id:81,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("TouchMove",{id:82,byteLength:8,structure:["uint8","uint16","uint16","uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadConnected",{id:93,byteLength:0,structure:[]}),this.toStreamerMessages.add("GamepadButtonPressed",{id:90,byteLength:3,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadButtonReleased",{id:91,byteLength:3,structure:["uint8","uint8","uint8"]}),this.toStreamerMessages.add("GamepadAnalog",{id:92,byteLength:10,structure:["uint8","uint8","double"]}),this.toStreamerMessages.add("GamepadDisconnected",{id:94,byteLength:1,structure:["uint8"]}),this.fromStreamerMessages.add("QualityControlOwnership",0),this.fromStreamerMessages.add("Response",1),this.fromStreamerMessages.add("Command",2),this.fromStreamerMessages.add("FreezeFrame",3),this.fromStreamerMessages.add("UnfreezeFrame",4),this.fromStreamerMessages.add("VideoEncoderAvgQP",5),this.fromStreamerMessages.add("LatencyTest",6),this.fromStreamerMessages.add("InitialSettings",7),this.fromStreamerMessages.add("FileExtension",8),this.fromStreamerMessages.add("FileMimeType",9),this.fromStreamerMessages.add("FileContents",10),this.fromStreamerMessages.add("TestEcho",11),this.fromStreamerMessages.add("InputControlOwnership",12),this.fromStreamerMessages.add("GamepadResponse",13),this.fromStreamerMessages.add("Protocol",255)}registerMessageHandler(t,s,n){switch(t){case ke.ToStreamer:this.toStreamerHandlers.set(s,n);break;case ke.FromStreamer:this.fromStreamerHandlers.set(s,n);break;default:e.Log(e.GetStackTrace(),`Unknown message direction ${t}`)}}}!function(e){e[e.ToStreamer=0]="ToStreamer",e[e.FromStreamer=1]="FromStreamer"}(ke||(ke={}));class st{constructor(){this.responseEventListeners=new Map}addResponseEventListener(e,t){this.responseEventListeners.set(e,t)}removeResponseEventListener(e){this.responseEventListeners.delete(e)}onResponse(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Response",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),s,6),this.responseEventListeners.forEach((e=>{e(s)}))}}class nt{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendLatencyTest(e){this.sendDescriptor("LatencyTest",e)}emitCommand(e){this.sendDescriptor("Command",e)}emitUIInteraction(e){this.sendDescriptor("UIInteraction",e)}sendDescriptor(t,s){const n=JSON.stringify(s),r=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(t);void 0===r&&e.Error(e.GetStackTrace(),`Attempted to emit descriptor with message type: ${t}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`),e.Log(e.GetStackTrace(),"Sending: "+s,6);const i=new DataView(new ArrayBuffer(3+2*n.length));let o=0;i.setUint8(o,r.id),o++,i.setUint16(o,n.length,!0),o+=2;for(let e=0;e<n.length;e++)i.setUint16(o,n.charCodeAt(e),!0),o+=2;this.dataChannelSender.canSend()?this.dataChannelSender.sendData(i.buffer):e.Info(e.GetStackTrace(),`Data channel cannot send yet, skipping sending descriptor message: ${t} - ${n}`)}}class rt{constructor(e,t){this.dataChannelSender=e,this.toStreamerMessagesMapProvider=t}sendMessageToStreamer(t,s){void 0===s&&(s=[]);const n=this.toStreamerMessagesMapProvider.toStreamerMessages.getFromKey(t);if(void 0===n)return void e.Error(e.GetStackTrace(),`Attempted to send a message to the streamer with message type: ${t}, but the frontend hasn't been configured to send such a message. Check you've added the message type in your cpp`);const r=new DataView(new ArrayBuffer(n.byteLength+1));r.setUint8(0,n.id);let i=1;s.forEach(((e,t)=>{switch(n.structure[t]){case"uint8":r.setUint8(i,e),i+=1;break;case"uint16":r.setUint16(i,e,!0),i+=2;break;case"int16":r.setInt16(i,e,!0),i+=2;break;case"float":r.setFloat32(i,e,!0),i+=4;break;case"double":r.setFloat64(i,e,!0),i+=8}})),this.dataChannelSender.canSend()?this.dataChannelSender.sendData(r.buffer):e.Info(e.GetStackTrace(),`Data channel cannot send yet, skipping sending message: ${t} - ${new Uint8Array(r.buffer)}`)}}class it{constructor(e){this.sendMessageController=e}SendRequestQualityControl(){this.sendMessageController.sendMessageToStreamer("RequestQualityControl")}SendMaxFpsRequest(){this.sendMessageController.sendMessageToStreamer("FpsRequest")}SendAverageBitrateRequest(){this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest")}SendStartStreaming(){this.sendMessageController.sendMessageToStreamer("StartStreaming")}SendStopStreaming(){this.sendMessageController.sendMessageToStreamer("StopStreaming")}SendRequestInitialSettings(){this.sendMessageController.sendMessageToStreamer("RequestInitialSettings")}}class ot{constructor(e){this.dataChannelProvider=e}canSend(){return void 0!==this.dataChannelProvider.getDataChannelInstance().dataChannel&&"open"==this.dataChannelProvider.getDataChannelInstance().dataChannel.readyState}sendData(t){const s=this.dataChannelProvider.getDataChannelInstance();"open"==s.dataChannel.readyState?(s.dataChannel.send(t),e.Log(e.GetStackTrace(),`Message Sent: ${new Uint8Array(t)}`,6),this.resetAfkWarningTimerOnDataSend()):e.Error(e.GetStackTrace(),`Message Failed: ${new Uint8Array(t)}`)}resetAfkWarningTimerOnDataSend(){}}class at{constructor(e){this.videoElementProvider=e,this.normalizeAndQuantizeUnsignedFunc=()=>{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 t=this.videoElementParent.clientHeight/this.videoElementParent.clientWidth,s=this.videoElement.videoHeight/this.videoElement.videoWidth;t>s?(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio > videoAspectRatio",6),this.ratio=t/s,this.normalizeAndQuantizeUnsignedFunc=(e,t)=>this.normalizeAndQuantizeUnsignedPlayerBigger(e,t),this.normalizeAndQuantizeSignedFunc=(e,t)=>this.normalizeAndQuantizeSignedPlayerBigger(e,t),this.denormalizeAndUnquantizeUnsignedFunc=(e,t)=>this.denormalizeAndUnquantizeUnsignedPlayerBigger(e,t)):(e.Log(e.GetStackTrace(),"Setup Normalize and Quantize for playerAspectRatio <= videoAspectRatio",6),this.ratio=s/t,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 dt(!1,65535,65535):new dt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerBigger(e,t){const s=e/65536,n=(t/65536-.5)/this.ratio+.5;return new lt(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 ct(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 dt(!1,65535,65535):new dt(!0,65536*s,65536*n)}denormalizeAndUnquantizeUnsignedPlayerSmaller(e,t){const s=(e/65536-.5)/this.ratio+.5,n=t/65536;return new lt(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 ct(32767*s,32767*n)}}class dt{constructor(e,t,s){this.inRange=e,this.x=t,this.y=s}}class lt{constructor(e,t){this.x=e,this.y=t}}class ct{constructor(e,t){this.x=e,this.y=t}}class ht{constructor(e,t){this.shouldShowPlayOverlay=!0,this.config=e,this.pixelStreaming=t,this.responseController=new st,this.file=new ze,this.sdpConstraints={offerToReceiveAudio:!0,offerToReceiveVideo:!0},this.afkController=new Se(this.config,this.pixelStreaming,this.onAfkTriggered.bind(this)),this.afkController.onAFKTimedOutCallback=()=>{this.setDisconnectMessageOverride("You have been disconnected due to inactivity"),this.closeSignalingServer()},this.freezeFrameController=new E(this.pixelStreaming.videoElementParent),this.videoPlayer=new Ze(this.pixelStreaming.videoElementParent,this.config),this.videoPlayer.onVideoInitialized=()=>this.handleVideoInitialized(),this.videoPlayer.onMatchViewportResolutionCallback=(e,t)=>{const s={"Resolution.Width":e,"Resolution.Height":t};this.sendDescriptorController.emitCommand(s)},this.videoPlayer.onResizePlayerCallback=()=>{this.setUpMouseAndFreezeFrame()},this.streamController=new f(this.videoPlayer),this.coordinateConverter=new at(this.videoPlayer),this.sendrecvDataChannelController=new ve,this.recvDataChannelController=new ve,this.registerDataChannelEventEmitters(this.sendrecvDataChannelController),this.registerDataChannelEventEmitters(this.recvDataChannelController),this.dataChannelSender=new ot(this.sendrecvDataChannelController),this.dataChannelSender.resetAfkWarningTimerOnDataSend=()=>this.afkController.resetAfkWarningTimer(),this.streamMessageController=new tt,this.webSocketController=new C,this.webSocketController.onConfig=e=>this.handleOnConfigMessage(e),this.webSocketController.onStreamerList=e=>this.handleStreamerListMessage(e),this.webSocketController.onWebSocketOncloseOverlayMessage=e=>{this.pixelStreaming._onDisconnect(`Websocket disconnect (${e.code}) ${""!=e.reason?"- "+e.reason:""}`),this.setVideoEncoderAvgQP(0)},this.webSocketController.onOpen.addEventListener("open",(()=>{this.config.isFlagEnabled(oe.BrowserSendOffer)||this.webSocketController.requestStreamerList()})),this.webSocketController.onClose.addEventListener("close",(e=>{this.afkController.stopAfkWarningTimer(),this.statsTimerHandle&&void 0!==this.statsTimerHandle&&window.clearInterval(this.statsTimerHandle),this.setTouchInputEnabled(!1),this.setMouseInputEnabled(!1),this.setKeyboardInputEnabled(!1),this.setGamePadInputEnabled(!1),this.shouldReconnect&&1001!=e.detail.code&&this.config.getNumericSettingValue(de.MaxReconnectAttempts)>0&&(this.isReconnecting=!0,this.reconnectAttempt++,this.restartStreamAutomatically())})),this.sendDescriptorController=new nt(this.dataChannelSender,this.streamMessageController),this.sendMessageController=new rt(this.dataChannelSender,this.streamMessageController),this.toStreamerMessagesController=new it(this.sendMessageController),this.registerMessageHandlers(),this.streamMessageController.populateDefaultProtocol(),this.inputClassesFactory=new Je(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(ge.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(ce.SignallingServerUrl);return this.config.isFlagEnabled(oe.BrowserSendOffer)&&(e+="?"+oe.BrowserSendOffer+"=true"),e}}requestUnquantizedAndDenormalizeUnsigned(e,t){return this.coordinateConverter.unquantizeAndDenormalizeUnsigned(e,t)}handleOnMessage(t){const s=new Uint8Array(t.data);e.Log(e.GetStackTrace(),"Message incoming:"+s,6);const n=this.streamMessageController.fromStreamerMessages.getFromValue(s[0]);this.streamMessageController.fromStreamerHandlers.get(n)(t.data)}registerMessageHandlers(){this.streamMessageController.registerMessageHandler(ke.FromStreamer,"QualityControlOwnership",(e=>this.onQualityControlOwnership(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Response",(e=>this.responseController.onResponse(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Command",(e=>{this.onCommand(e)})),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FreezeFrame",(e=>this.onFreezeFrameMessage(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"UnfreezeFrame",(()=>this.invalidateFreezeFrameAndEnableVideo())),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"VideoEncoderAvgQP",(e=>this.handleVideoEncoderAvgQP(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"LatencyTest",(e=>this.handleLatencyTestResult(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"InitialSettings",(e=>this.handleInitialSettings(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileExtension",(e=>this.onFileExtension(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileMimeType",(e=>this.onFileMimeType(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"FileContents",(e=>this.onFileContents(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"InputControlOwnership",(e=>this.onInputControlOwnership(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"GamepadResponse",(e=>this.onGamepadResponse(e))),this.streamMessageController.registerMessageHandler(ke.FromStreamer,"Protocol",(e=>this.onProtocolMessage(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"IFrameRequest",(()=>this.sendMessageController.sendMessageToStreamer("IFrameRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"RequestQualityControl",(()=>this.sendMessageController.sendMessageToStreamer("RequestQualityControl"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"FpsRequest",(()=>this.sendMessageController.sendMessageToStreamer("FpsRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"AverageBitrateRequest",(()=>this.sendMessageController.sendMessageToStreamer("AverageBitrateRequest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"StartStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StartStreaming"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"StopStreaming",(()=>this.sendMessageController.sendMessageToStreamer("StopStreaming"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"LatencyTest",(()=>this.sendMessageController.sendMessageToStreamer("LatencyTest"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"RequestInitialSettings",(()=>this.sendMessageController.sendMessageToStreamer("RequestInitialSettings"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TestEcho",(()=>{})),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"UIInteraction",(e=>this.sendDescriptorController.emitUIInteraction(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"Command",(e=>this.sendDescriptorController.emitCommand(e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyDown",(e=>this.sendMessageController.sendMessageToStreamer("KeyDown",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyUp",(e=>this.sendMessageController.sendMessageToStreamer("KeyUp",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"KeyPress",(e=>this.sendMessageController.sendMessageToStreamer("KeyPress",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseEnter",(e=>this.sendMessageController.sendMessageToStreamer("MouseEnter",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseLeave",(e=>this.sendMessageController.sendMessageToStreamer("MouseLeave",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseDown",(e=>this.sendMessageController.sendMessageToStreamer("MouseDown",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseUp",(e=>this.sendMessageController.sendMessageToStreamer("MouseUp",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseMove",(e=>this.sendMessageController.sendMessageToStreamer("MouseMove",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseWheel",(e=>this.sendMessageController.sendMessageToStreamer("MouseWheel",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"MouseDouble",(e=>this.sendMessageController.sendMessageToStreamer("MouseDouble",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchStart",(e=>this.sendMessageController.sendMessageToStreamer("TouchStart",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchEnd",(e=>this.sendMessageController.sendMessageToStreamer("TouchEnd",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"TouchMove",(e=>this.sendMessageController.sendMessageToStreamer("TouchMove",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadConnected",(()=>this.sendMessageController.sendMessageToStreamer("GamepadConnected"))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonPressed",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("GamepadButtonReleased",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadAnalog",(e=>this.sendMessageController.sendMessageToStreamer("GamepadAnalog",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"GamepadDisconnected",(e=>this.sendMessageController.sendMessageToStreamer("GamepadDisconnected",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRHMDTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRHMDTransform",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRControllerTransform",(e=>this.sendMessageController.sendMessageToStreamer("XRControllerTransform",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRSystem",(e=>this.sendMessageController.sendMessageToStreamer("XRSystem",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonTouched",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonTouched",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonPressed",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonPressed",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRButtonReleased",(e=>this.sendMessageController.sendMessageToStreamer("XRButtonReleased",e))),this.streamMessageController.registerMessageHandler(ke.ToStreamer,"XRAnalog",(e=>this.sendMessageController.sendMessageToStreamer("XRAnalog",e)))}onCommand(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.Command",6);const s=new TextDecoder("utf-16").decode(t.slice(1));e.Log(e.GetStackTrace(),"Data Channel Command: "+s,6);const n=JSON.parse(s);"onScreenKeyboard"===n.command&&this.pixelStreaming._activateOnScreenKeyboard(n)}onProtocolMessage(t){try{const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s);Object.prototype.hasOwnProperty.call(n,"Direction")||e.Error(e.GetStackTrace(),"Malformed protocol received. Ensure the protocol message contains a direction");const r=n.Direction;delete n.Direction,e.Log(e.GetStackTrace(),`Received new ${r==ke.FromStreamer?"FromStreamer":"ToStreamer"} protocol. Updating existing protocol...`),Object.keys(n).forEach((t=>{const s=n[t];switch(r){case ke.ToStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id")||!Object.prototype.hasOwnProperty.call(s,"byteLength"))return void e.Error(e.GetStackTrace(),`ToStreamer->${t} protocol definition was malformed as it didn't contain at least an id and a byteLength\n\n Definition was: ${JSON.stringify(s,null,2)}`);if(s.byteLength>0&&!Object.prototype.hasOwnProperty.call(s,"structure"))return void e.Error(e.GetStackTrace(),`ToStreamer->${t} protocol definition was malformed as it specified a byteLength but no accompanying structure`);this.streamMessageController.toStreamerHandlers.get(t)?this.streamMessageController.toStreamerMessages.add(t,s):e.Error(e.GetStackTrace(),`There was no registered handler for "${t}" - try adding one using registerMessageHandler(MessageDirection.ToStreamer, "${t}", myHandler)`);break;case ke.FromStreamer:if(!Object.prototype.hasOwnProperty.call(s,"id"))return void e.Error(e.GetStackTrace(),`FromStreamer->${t} protocol definition was malformed as it didn't contain at least an id\n\n Definition was: ${JSON.stringify(s,null,2)}`);this.streamMessageController.fromStreamerHandlers.get(t)?this.streamMessageController.fromStreamerMessages.add(t,s.id):e.Error(e.GetStackTrace(),`There was no registered handler for "${s}" - try adding one using registerMessageHandler(MessageDirection.FromStreamer, "${t}", myHandler)`);break;default:e.Error(e.GetStackTrace(),`Unknown direction: ${r}`)}})),this.toStreamerMessagesController.SendRequestInitialSettings(),this.toStreamerMessagesController.SendRequestQualityControl()}catch(t){e.Log(e.GetStackTrace(),t)}}onInputControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InputControlOwnership",6);const n=new Boolean(s[1]).valueOf();e.Log(e.GetStackTrace(),`Received input controller message - will your input control the stream: ${n}`),this.pixelStreaming._onInputControlOwnership(n)}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()}restartStreamAutomatically(){if(this.webSocketController)if(this.webSocketController.webSocket&&this.webSocketController.webSocket.readyState!==WebSocket.CLOSED){this.pixelStreaming._showActionOrErrorOnDisconnect=!1,this.setDisconnectMessageOverride("Restarting stream..."),this.closeSignalingServer();const e=setTimeout((()=>{this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer(),clearTimeout(e)}),3e3)}else e.Log(e.GetStackTrace(),"A websocket connection has not been made yet so we will start the stream"),this.pixelStreaming._onWebRtcAutoConnect(),this.connectToSignallingServer();else e.Log(e.GetStackTrace(),"The Web Socket Controller does not exist so this will not work right now.")}loadFreezeFrameOrShowPlayOverlay(){this.pixelStreaming.dispatchEvent(new X({shouldShowPlayOverlay:this.shouldShowPlayOverlay,isValid:this.freezeFrameController.valid,jpegData:this.freezeFrameController.jpeg})),!0===this.shouldShowPlayOverlay?(e.Log(e.GetStackTrace(),"showing play overlay"),this.resizePlayerStyle()):(e.Log(e.GetStackTrace(),"showing freeze frame"),this.freezeFrameController.showFreezeFrame()),setTimeout((()=>{this.videoPlayer.setVideoEnabled(!1)}),this.freezeFrameController.freezeFrameDelay)}onFreezeFrameMessage(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.FreezeFrame",6);const s=new Uint8Array(t);this.freezeFrameController.processFreezeFrameMessage(s,(()=>this.loadFreezeFrameOrShowPlayOverlay()))}invalidateFreezeFrameAndEnableVideo(){e.Log(e.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);Ie.setExtensionFromBytes(t,this.file)}onFileMimeType(e){const t=new Uint8Array(e);Ie.setMimeTypeFromBytes(t,this.file)}onFileContents(e){const t=new Uint8Array(e);Ie.setContentsFromBytes(t,this.file)}playStream(){if(!this.videoPlayer.getVideoElement()){const t="Could not play video stream because the video player was not initialized correctly.";return this.pixelStreaming.dispatchEvent(new Q({message:t})),e.Error(e.GetStackTrace(),t),this.setDisconnectMessageOverride("Stream not initialized correctly"),void this.closeSignalingServer()}this.videoPlayer.hasVideoSource()?(this.setTouchInputEnabled(this.config.isFlagEnabled(oe.TouchInput)),this.pixelStreaming.dispatchEvent(new $),this.streamController.audioElement.srcObject?(this.streamController.audioElement.muted=this.config.isFlagEnabled(oe.StartVideoMuted),this.streamController.audioElement.play().then((()=>{this.playVideo()})).catch((t=>{e.Log(e.GetStackTrace(),t),e.Log(e.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 q({reason:t}))}))):this.playVideo(),this.shouldShowPlayOverlay=!1,this.freezeFrameController.showFreezeFrame()):e.Warning(e.GetStackTrace(),"Cannot play stream, the video element has no srcObject to play.")}playVideo(){this.videoPlayer.play().catch((t=>{this.streamController.audioElement.srcObject&&this.streamController.audioElement.pause(),e.Log(e.GetStackTrace(),t),e.Log(e.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 q({reason:t}))}))}autoPlayVideoOrSetUpPlayOverlay(){this.config.isFlagEnabled(oe.AutoPlayVideo)&&this.playStream(),this.resizePlayerStyle()}connectToSignallingServer(){const e=this.signallingUrlBuilder();this.webSocketController.connect(e)}startSession(t){if(this.peerConfig=t,this.config.isFlagEnabled(oe.ForceTURN)&&!this.checkTurnServerAvailability(t))return e.Info(e.GetStackTrace(),"No turn server was found in the Peer Connection Options. TURN cannot be forced, closing connection. Please use STUN instead"),this.setDisconnectMessageOverride("TURN cannot be forced, closing connection. Please use STUN instead."),void this.closeSignalingServer();this.peerConnectionController=new Ae(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 s=!1;this.peerConnectionController.onIceConnectionStateChange=()=>{!s&&["connected","completed"].includes(this.peerConnectionController.peerConnection.iceConnectionState)&&(this.pixelStreaming._onWebRtcConnected(),s=!0)},this.peerConnectionController.onTrack=e=>this.streamController.handleOnTrack(e),this.config.isFlagEnabled(oe.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(t){if(!t.iceServers)return e.Info(e.GetStackTrace(),"A turn sever was not found"),!1;for(const s of t.iceServers)for(const t of s.urls)if(t.includes("turn"))return e.Log(e.GetStackTrace(),`A turn sever was found at ${t}`),!0;return e.Info(e.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(t){if(e.Log(e.GetStackTrace(),`Got streamer list ${t.ids}`,6),this.isReconnecting)t.ids.includes(this.subscribedStream)?(this.isReconnecting=!1,this.reconnectAttempt=0,this.webSocketController.sendSubscribe(this.subscribedStream)):this.reconnectAttempt<this.config.getNumericSettingValue(de.MaxReconnectAttempts)?(this.reconnectAttempt++,setTimeout((()=>{this.webSocketController.requestStreamerList()}),2e3)):(this.reconnectAttempt=0,this.isReconnecting=!1,this.shouldReconnect=!1,this.webSocketController.close(),this.config.setOptionSettingValue(ge.StreamerId,""),this.config.setOptionSettingOptions(ge.StreamerId,[]));else{const e=[...t.ids];e.unshift(""),this.config.setOptionSettingOptions(ge.StreamerId,e);const s=new URLSearchParams(window.location.search);let n=null;1==t.ids.length?n=t.ids[0]:this.config.isFlagEnabled(oe.PreferSFU)&&t.ids.includes("SFU")?n="SFU":s.has(ge.StreamerId)&&t.ids.includes(s.get(ge.StreamerId))&&(n=s.get(ge.StreamerId)),null!==n&&this.config.setOptionSettingValue(ge.StreamerId,n),this.pixelStreaming.dispatchEvent(new Y({messageStreamerList:t,autoSelectedStreamerId:n}))}}handleWebRtcAnswer(t){e.Log(e.GetStackTrace(),`Got answer sdp ${t.sdp}`,6);const s={sdp:t.sdp,type:"answer"};this.peerConnectionController.receiveAnswer(s),this.handlePostWebrtcNegotiation()}handleWebRtcOffer(t){e.Log(e.GetStackTrace(),`Got offer sdp ${t.sdp}`,6),this.isUsingSFU=!!t.sfu&&t.sfu,this.isUsingSFU&&(this.peerConnectionController.preferredCodec="");const s={sdp:t.sdp,type:"offer"};this.peerConnectionController.receiveOffer(s,this.config),this.handlePostWebrtcNegotiation()}handleWebRtcSFUPeerDatachannels(e){const t={ordered:!0,negotiated:!0,id:e.sendStreamId},s=e.sendStreamId!=e.recvStreamId;if(this.sendrecvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,s?"send-datachannel":"datachannel",t),s){const t={ordered:!0,negotiated:!0,id:e.recvStreamId};this.recvDataChannelController.createDataChannel(this.peerConnectionController.peerConnection,"recv-datachannel",t),this.recvDataChannelController.handleOnOpen=()=>this.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(oe.MouseInput)),this.setKeyboardInputEnabled(this.config.isFlagEnabled(oe.KeyboardInput)),this.setGamePadInputEnabled(this.config.isFlagEnabled(oe.GamepadInput))}handleIceCandidate(t){e.Log(e.GetStackTrace(),"Web RTC Controller: onWebRtcIce",6);const s=new RTCIceCandidate(t);this.peerConnectionController.handleOnIce(s)}handleSendIceCandidate(t){e.Log(e.GetStackTrace(),"OnIceCandidate",6),t.candidate&&t.candidate.candidate&&this.webSocketController.sendIceCandidate(t.candidate)}handleDataChannel(t){e.Log(e.GetStackTrace(),"Data channel created for us by browser as we are a receiving peer.",6),this.sendrecvDataChannelController.dataChannel=t.channel,this.sendrecvDataChannelController.setupDataChannel(),this.sendrecvDataChannelController.handleOnMessage=e=>this.handleOnMessage(e)}handleSendWebRTCOffer(t){e.Log(e.GetStackTrace(),"Sending the offer to the Server",6),this.webSocketController.sendWebRtcOffer(t)}handleSendWebRTCAnswer(t){e.Log(e.GetStackTrace(),"Sending the answer to the Server",6),this.webSocketController.sendWebRtcAnswer(t),this.isUsingSFU&&this.webSocketController.sendWebRtcDatachannelRequest()}setUpMouseAndFreezeFrame(){this.videoElementParentClientRect=this.videoPlayer.getVideoParentElement().getBoundingClientRect(),this.coordinateConverter.setupNormalizeAndQuantize(),this.freezeFrameController.freezeFrame.resize()}closeSignalingServer(){var e;this.shouldReconnect=!1,null===(e=this.webSocketController)||void 0===e||e.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.sendDescriptorController.sendLatencyTest({StartTime:this.latencyStartTime})}sendEncoderMinQP(t){e.Log(e.GetStackTrace(),`MinQP=${t}\n`,6),null!=t&&this.sendDescriptorController.emitCommand({"Encoder.MinQP":t})}sendEncoderMaxQP(t){e.Log(e.GetStackTrace(),`MaxQP=${t}\n`,6),null!=t&&this.sendDescriptorController.emitCommand({"Encoder.MaxQP":t})}sendWebRTCMinBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Min Bitrate=${t}`,6),null!=t&&this.sendDescriptorController.emitCommand({"WebRTC.MinBitrate":t})}sendWebRTCMaxBitrate(t){e.Log(e.GetStackTrace(),`WebRTC Max Bitrate=${t}`,6),null!=t&&this.sendDescriptorController.emitCommand({"WebRTC.MaxBitrate":t})}sendWebRTCFps(t){e.Log(e.GetStackTrace(),`WebRTC FPS=${t}`,6),null!=t&&(this.sendDescriptorController.emitCommand({"WebRTC.Fps":t}),this.sendDescriptorController.emitCommand({"WebRTC.MaxFps":t}))}sendShowFps(){e.Log(e.GetStackTrace(),"---- Sending show stat to UE ----",6),this.sendDescriptorController.emitCommand({"stat.fps":""})}sendIframeRequest(){e.Log(e.GetStackTrace(),"---- Sending Request for an IFrame ----",6),this.streamMessageController.toStreamerHandlers.get("IFrameRequest")()}emitUIInteraction(t){e.Log(e.GetStackTrace(),"---- Sending custom UIInteraction message ----",6),this.sendDescriptorController.emitUIInteraction(t)}emitCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command message ----",6),this.sendDescriptorController.emitCommand(t)}emitConsoleCommand(t){e.Log(e.GetStackTrace(),"---- Sending custom Command:ConsoleCommand message ----",6),this.sendDescriptorController.emitCommand({ConsoleCommand:t})}sendRequestQualityControlOwnership(){e.Log(e.GetStackTrace(),"---- Sending Request to Control Quality ----",6),this.toStreamerMessagesController.SendRequestQualityControl()}handleLatencyTestResult(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.latencyTest",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=new Ge;Object.assign(n,JSON.parse(s)),n.processFields(),n.testStartTimeMs=this.latencyStartTime,n.browserReceiptTimeMs=Date.now(),n.latencyExcludingDecode=~~(n.browserReceiptTimeMs-n.testStartTimeMs),n.testDuration=~~(n.TransmissionTimeMs-n.ReceiptTimeMs),n.networkLatency=~~(n.latencyExcludingDecode-n.testDuration),n.frameDisplayDeltaTimeMs&&n.browserReceiptTimeMs&&(n.endToEndLatency=(n.frameDisplayDeltaTimeMs,n.networkLatency,~~+n.CaptureToSendMs)),this.pixelStreaming._onLatencyTestResult(n)}handleInitialSettings(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.InitialSettings",6);const s=new TextDecoder("utf-16").decode(t.slice(1)),n=JSON.parse(s),r=new Fe;n.Encoder&&(r.EncoderSettings=n.Encoder),n.WebRTC&&(r.WebRTCSettings=n.WebRTC),n.PixelStreaming&&(r.PixelStreamingSettings=n.PixelStreaming),n.ConfigOptions&&void 0!==n.ConfigOptions.DefaultToHover&&this.config.setFlagEnabled(oe.HoveringMouseMode,!!n.ConfigOptions.DefaultToHover),r.ueCompatible(),e.Log(e.GetStackTrace(),s,6),this.pixelStreaming._onInitialSettings(r)}handleVideoEncoderAvgQP(t){e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.VideoEncoderAvgQP",6);const s=Number(new TextDecoder("utf-16").decode(t.slice(1)));this.setVideoEncoderAvgQP(s)}handleVideoInitialized(){this.pixelStreaming._onVideoInitialized(),this.autoPlayVideoOrSetUpPlayOverlay(),this.resizePlayerStyle(),this.videoPlayer.updateVideoStreamSize()}onQualityControlOwnership(t){const s=new Uint8Array(t);e.Log(e.GetStackTrace(),"DataChannelReceiveMessageType.QualityControlOwnership",6),this.isQualityController=new Boolean(s[1]).valueOf(),e.Log(e.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()}getDisconnectMessageOverride(){return this.disconnectMessageOverride}setDisconnectMessageOverride(e){this.disconnectMessageOverride=e}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(oe.HoveringMouseMode)?pe.HoveringMouse:pe.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(oe.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 B({label:e,event:t})),e.onError=(e,t)=>this.pixelStreaming.dispatchEvent(new _({label:e,event:t}))}}class gt{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 ut{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 mt{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 o=n.transform.matrix,a=[];for(let e=0;e<16;e++)a[e]=new Float32Array([o[e]])[0];this.toStreamerMessagesProvider.toStreamerHandlers.get("XRControllerTransform")([a[0],a[4],a[8],a[12],a[1],a[5],a[9],a[13],a[2],a[6],a[10],a[14],a[3],a[7],a[11],a[15],i]),void 0===this.controllers[i]&&(this.controllers[i]={prevState:void 0,currentState:void 0,id:void 0},this.controllers[i].prevState=ut.deepCopyGamepad(e.gamepad)),this.controllers[i].currentState=ut.deepCopyGamepad(e.gamepad);const d=this.controllers[i],l=d.currentState,c=d.prevState;for(let e=0;e<l.buttons.length;e++){const t=l.buttons[e],s=c.buttons[e];t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,e,s.pressed?1:0]):!t.pressed&&s.pressed&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,e,0]),t.touched&&!t.pressed?this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonPressed")([i,3,s.touched?1:0]):!t.touched&&s.touched&&this.toStreamerMessagesProvider.toStreamerHandlers.get("XRButtonReleased")([i,3,0])}for(let e=0;e<l.axes.length;e++)this.toStreamerMessagesProvider.toStreamerHandlers.get("XRAnalog")([i,e,l.axes[e]]);this.controllers[i].prevState=l}}}class pt{constructor(e){this.xrSession=null,this.webRtcController=e,this.xrControllers=[],this.xrGamepadController=new mt(this.webRtcController.streamMessageController),this.onSessionEnded=new EventTarget,this.onSessionStarted=new EventTarget,this.onFrame=new EventTarget}xrClicked(){this.xrSession?this.xrSession.end():navigator.xr.requestSession("immersive-vr").then((e=>{this.onXrSessionStarted(e)}))}onXrSessionEnded(){e.Log(e.GetStackTrace(),"XR Session ended"),this.xrSession=null,this.onSessionEnded.dispatchEvent(new Event("xrSessionEnded"))}onXrSessionStarted(t){e.Log(e.GetStackTrace(),"XR Session started"),this.xrSession=t,this.xrSession.addEventListener("end",(()=>{this.onXrSessionEnded()}));const s=document.createElement("canvas");this.gl=s.getContext("webgl2",{xrCompatible:!0}),this.xrSession.updateRenderState({baseLayer:new XRWebGLLayer(this.xrSession,this.gl)});const n=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(n,gt.vertexShader()),this.gl.compileShader(n);const r=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(r,gt.fragmentShader()),this.gl.compileShader(r);const i=this.gl.createProgram();this.gl.attachShader(i,n),this.gl.attachShader(i,r),this.gl.linkProgram(i),this.gl.useProgram(i),this.positionLocation=this.gl.getAttribLocation(i,"a_position"),this.texcoordLocation=this.gl.getAttribLocation(i,"a_texCoord"),this.positionBuffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionBuffer),this.gl.enableVertexAttribArray(this.positionLocation);const o=this.gl.createTexture();this.gl.bindTexture(this.gl.TEXTURE_2D,o),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(i,"u_resolution"),this.offsetLocation=this.gl.getUniformLocation(i,"u_offset"),t.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(oe.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 re({time:e,frame:t}))}render(e){if(!this.gl)return;const t=this.xrSession.renderState.baseLayer;let s,n,r,i,o;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,o=0,this.gl.vertexAttribPointer(this.positionLocation,s,n,r,i,o),this.gl.enableVertexAttribArray(this.texcoordLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.texcoordBuffer),s=2,n=this.gl.FLOAT,r=!1,i=0,o=0,this.gl.vertexAttribPointer(this.texcoordLocation,s,n,r,i,o),this.gl.uniform2f(this.resolutionLocation,e.videoWidth,e.videoHeight);const a=this.gl.TRIANGLES;o=0,this.gl.drawArrays(a,o,6)}static isSessionSupported(e){return navigator.xr?navigator.xr.isSessionSupported(e):new Promise((()=>!1))}}class St{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 vt{constructor(e,t){this._showActionOrErrorOnDisconnect=!0,this.allowConsoleCommands=!1,this.config=e,(null==t?void 0:t.videoElementParent)&&(this._videoElementParent=t.videoElementParent),this._eventEmitter=new ie,this.configureSettings(),this.setWebRtcPlayerController(new ht(this.config,this)),this.onScreenKeyboardHelper=new St(this.videoElementParent),this.onScreenKeyboardHelper.unquantizeAndDenormalizeUnsigned=(e,t)=>this._webRtcController.requestUnquantizedAndDenormalizeUnsigned(e,t),this._activateOnScreenKeyboard=e=>this.onScreenKeyboardHelper.showOnScreenKeyboard(e),this._webXrController=new pt(this._webRtcController)}get videoElementParent(){return this._videoElementParent||(this._videoElementParent=document.createElement("div"),this._videoElementParent.id="videoElementParent"),this._videoElementParent}configureSettings(){this.config._addOnSettingChangedListener(oe.IsQualityController,(e=>{!0!==e||this._webRtcController.isQualityController||this._webRtcController.sendRequestQualityControlOwnership()})),this.config._addOnSettingChangedListener(oe.AFKDetection,(e=>{this._webRtcController.setAfkEnabled(e)})),this.config._addOnSettingChangedListener(oe.MatchViewportResolution,(()=>{this._webRtcController.videoPlayer.updateVideoStreamSize()})),this.config._addOnSettingChangedListener(oe.HoveringMouseMode,(e=>{this.config.setFlagLabel(oe.HoveringMouseMode,`Control Scheme: ${e?"Hovering":"Locked"} Mouse`),this._webRtcController.setMouseInputEnabled(this.config.isFlagEnabled(oe.MouseInput))})),this.config._addOnSettingChangedListener(oe.KeyboardInput,(e=>{this._webRtcController.setKeyboardInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.MouseInput,(e=>{this._webRtcController.setMouseInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.TouchInput,(e=>{this._webRtcController.setTouchInputEnabled(e)})),this.config._addOnSettingChangedListener(oe.GamepadInput,(e=>{this._webRtcController.setGamePadInputEnabled(e)})),this.config._addOnNumericSettingChangedListener(de.MinQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending MinQP --------",7),this._webRtcController.sendEncoderMinQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.MaxQP,(t=>{e.Log(e.GetStackTrace(),"-------- Sending encoder settings --------",7),this._webRtcController.sendEncoderMaxQP(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMinBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMinBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCMaxBitrate,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCMaxBitrate(1e3*t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnNumericSettingChangedListener(de.WebRTCFPS,(t=>{e.Log(e.GetStackTrace(),"-------- Sending web rtc settings --------",7),this._webRtcController.sendWebRTCFps(t),e.Log(e.GetStackTrace(),"-------------------------------------------",7)})),this.config._addOnOptionSettingChangedListener(ge.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(ge.PreferredCodec).selected),this._webRtcController.resizePlayerStyle(),this.checkForAutoConnect()}connect(){this._eventEmitter.dispatchEvent(new V),this._webRtcController.connectToSignallingServer()}reconnect(){this._eventEmitter.dispatchEvent(new K),this._webRtcController.restartStreamAutomatically()}disconnect(){this._eventEmitter.dispatchEvent(new N),this._webRtcController.close()}play(){this._onStreamLoading(),this._webRtcController.playStream()}checkForAutoConnect(){this.config.isFlagEnabled(oe.AutoConnect)&&(this._onWebRtcAutoConnect(),this._webRtcController.connectToSignallingServer())}_onWebRtcAutoConnect(){this._eventEmitter.dispatchEvent(new D),this._showActionOrErrorOnDisconnect=!0}_onWebRtcSdp(){this._eventEmitter.dispatchEvent(new F)}_onStreamLoading(){this._eventEmitter.dispatchEvent(new H)}_onDisconnect(e){""!=this._webRtcController.getDisconnectMessageOverride()&&void 0!==this._webRtcController.getDisconnectMessageOverride()&&null!=this._webRtcController.getDisconnectMessageOverride()&&(e=this._webRtcController.getDisconnectMessageOverride(),this._webRtcController.setDisconnectMessageOverride("")),this._eventEmitter.dispatchEvent(new I({eventString:e,showActionOrErrorOnDisconnect:this._showActionOrErrorOnDisconnect})),0==this._showActionOrErrorOnDisconnect&&(this._showActionOrErrorOnDisconnect=!0)}_onWebRtcConnecting(){this._eventEmitter.dispatchEvent(new O)}_onWebRtcConnected(){this._eventEmitter.dispatchEvent(new U)}_onWebRtcFailed(){this._eventEmitter.dispatchEvent(new G)}_onVideoInitialized(){this._eventEmitter.dispatchEvent(new W),this._videoStartTime=Date.now()}_onLatencyTestResult(e){this._eventEmitter.dispatchEvent(new Z({latencyTimings: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 J({aggregatedStats:e}))}_onVideoEncoderAvgQP(e){this._eventEmitter.dispatchEvent(new A({avgQP:e}))}_onInitialSettings(t){var s;this._eventEmitter.dispatchEvent(new ee({settings:t})),t.PixelStreamingSettings&&(this.allowConsoleCommands=null!==(s=t.PixelStreamingSettings.AllowPixelStreamingCommands)&&void 0!==s&&s,!1===this.allowConsoleCommands&&e.Info(e.GetStackTrace(),"-AllowPixelStreamingCommands=false, sending arbitrary console commands from browser to UE is disabled."));const n=this.config.useUrlParams,r=new URLSearchParams(window.location.search);t.EncoderSettings&&(this.config.setNumericSetting(de.MinQP,n&&r.has(de.MinQP)?Number.parseInt(r.get(de.MinQP)):t.EncoderSettings.MinQP),this.config.setNumericSetting(de.MaxQP,n&&r.has(de.MaxQP)?Number.parseInt(r.get(de.MaxQP)):t.EncoderSettings.MaxQP)),t.WebRTCSettings&&(this.config.setNumericSetting(de.WebRTCMinBitrate,n&&r.has(de.WebRTCMinBitrate)?Number.parseInt(r.get(de.WebRTCMinBitrate))/1e3:t.WebRTCSettings.MinBitrate/1e3),this.config.setNumericSetting(de.WebRTCMaxBitrate,n&&r.has(de.WebRTCMaxBitrate)?Number.parseInt(r.get(de.WebRTCMaxBitrate))/1e3:t.WebRTCSettings.MaxBitrate/1e3),this.config.setNumericSetting(de.WebRTCFPS,n&&r.has(de.WebRTCFPS)?Number.parseInt(r.get(de.WebRTCFPS)):t.WebRTCSettings.FPS))}_onQualityControlOwnership(e){this.config.setFlagEnabled(oe.IsQualityController,e)}requestLatencyTest(){return!!this._webRtcController.videoPlayer.isVideoReady()&&(this._webRtcController.sendLatencyTest(),!0)}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}}})(),r})()));
@@ -0,0 +1,39 @@
1
+ import { Config } from '../Config/Config';
2
+ import { PixelStreaming } from '../PixelStreaming/PixelStreaming';
3
+ export declare class AFKController {
4
+ closeTimeout: number;
5
+ active: boolean;
6
+ countdownActive: boolean;
7
+ warnTimer: ReturnType<typeof setTimeout>;
8
+ countDown: number;
9
+ countDownTimer: ReturnType<typeof setInterval>;
10
+ config: Config;
11
+ pixelStreaming: PixelStreaming;
12
+ onDismissAfk: () => void;
13
+ onAFKTimedOutCallback: () => void;
14
+ constructor(config: Config, pixelStreaming: PixelStreaming, onDismissAfk: () => void);
15
+ /**
16
+ * The methods that occur when an afk event listener is clicked
17
+ */
18
+ onAfkClick(): void;
19
+ /**
20
+ * Start the warning timer if a timeout is set greater that 0 seconds
21
+ */
22
+ startAfkWarningTimer(): void;
23
+ /**
24
+ * Stop the afk warning timer
25
+ */
26
+ stopAfkWarningTimer(): void;
27
+ /**
28
+ * Pause the timer which when elapsed will warn the user they are inactive.
29
+ */
30
+ pauseAfkWarningTimer(): void;
31
+ /**
32
+ * If the user interacts then reset the warning timer.
33
+ */
34
+ resetAfkWarningTimer(): void;
35
+ /**
36
+ * Show the AFK overlay and begin the countDown
37
+ */
38
+ activateAfkEvent(): void;
39
+ }
@@ -0,0 +1,217 @@
1
+ import { SettingFlag } from './SettingFlag';
2
+ import { SettingNumber } from './SettingNumber';
3
+ import { SettingText } from './SettingText';
4
+ import { SettingOption } from './SettingOption';
5
+ import { EventEmitter } from '../Util/EventEmitter';
6
+ /**
7
+ * A collection of flags that can be toggled and are core to all Pixel Streaming experiences.
8
+ * These are used in the `Config.Flags` map.
9
+ */
10
+ export declare class Flags {
11
+ static AutoConnect: "AutoConnect";
12
+ static AutoPlayVideo: "AutoPlayVideo";
13
+ static AFKDetection: "TimeoutIfIdle";
14
+ static BrowserSendOffer: "OfferToReceive";
15
+ static HoveringMouseMode: "HoveringMouse";
16
+ static ForceMonoAudio: "ForceMonoAudio";
17
+ static ForceTURN: "ForceTURN";
18
+ static FakeMouseWithTouches: "FakeMouseWithTouches";
19
+ static IsQualityController: "ControlsQuality";
20
+ static MatchViewportResolution: "MatchViewportRes";
21
+ static PreferSFU: "preferSFU";
22
+ static StartVideoMuted: "StartVideoMuted";
23
+ static SuppressBrowserKeys: "SuppressBrowserKeys";
24
+ static UseMic: "UseMic";
25
+ static KeyboardInput: "KeyboardInput";
26
+ static MouseInput: "MouseInput";
27
+ static TouchInput: "TouchInput";
28
+ static GamepadInput: "GamepadInput";
29
+ static XRControllerInput: "XRControllerInput";
30
+ }
31
+ export type FlagsKeys = Exclude<keyof typeof Flags, 'prototype'>;
32
+ export type FlagsIds = typeof Flags[FlagsKeys];
33
+ /**
34
+ * A collection of numeric parameters that are core to all Pixel Streaming experiences.
35
+ *
36
+ */
37
+ export declare class NumericParameters {
38
+ static AFKTimeoutSecs: "AFKTimeout";
39
+ static MinQP: "MinQP";
40
+ static MaxQP: "MaxQP";
41
+ static WebRTCFPS: "WebRTCFPS";
42
+ static WebRTCMinBitrate: "WebRTCMinBitrate";
43
+ static WebRTCMaxBitrate: "WebRTCMaxBitrate";
44
+ static MaxReconnectAttempts: "MaxReconnectAttempts";
45
+ }
46
+ export type NumericParametersKeys = Exclude<keyof typeof NumericParameters, 'prototype'>;
47
+ export type NumericParametersIds = typeof NumericParameters[NumericParametersKeys];
48
+ /**
49
+ * A collection of textual parameters that are core to all Pixel Streaming experiences.
50
+ *
51
+ */
52
+ export declare class TextParameters {
53
+ static SignallingServerUrl: "ss";
54
+ }
55
+ export type TextParametersKeys = Exclude<keyof typeof TextParameters, 'prototype'>;
56
+ export type TextParametersIds = typeof TextParameters[TextParametersKeys];
57
+ /**
58
+ * A collection of enum based parameters that are core to all Pixel Streaming experiences.
59
+ *
60
+ */
61
+ export declare class OptionParameters {
62
+ static PreferredCodec: "PreferredCodec";
63
+ static StreamerId: "StreamerId";
64
+ }
65
+ export type OptionParametersKeys = Exclude<keyof typeof OptionParameters, 'prototype'>;
66
+ export type OptionParametersIds = typeof OptionParameters[OptionParametersKeys];
67
+ /**
68
+ * Utility types for inferring data type based on setting ID
69
+ */
70
+ export type OptionIds = FlagsIds | NumericParametersIds | TextParametersIds | OptionParametersIds;
71
+ export type OptionKeys<T> = T extends FlagsIds ? boolean : T extends NumericParametersIds ? number : T extends TextParametersIds ? string : T extends OptionParametersIds ? string : never;
72
+ export type AllSettings = {
73
+ [K in OptionIds]: OptionKeys<K>;
74
+ };
75
+ export interface ConfigParams {
76
+ /** Initial Pixel Streaming settings */
77
+ initialSettings?: Partial<AllSettings>;
78
+ /** If useUrlParams is set true, will read initial values from URL parameters and persist changed settings into URL */
79
+ useUrlParams?: boolean;
80
+ }
81
+ export declare class Config {
82
+ private flags;
83
+ private numericParameters;
84
+ private textParameters;
85
+ private optionParameters;
86
+ private _useUrlParams;
87
+ constructor(config?: ConfigParams);
88
+ /**
89
+ * True if reading configuration initial values from URL parameters, and
90
+ * persisting changes in URL when changed.
91
+ */
92
+ get useUrlParams(): boolean;
93
+ /**
94
+ * Populate the default settings for a Pixel Streaming application
95
+ */
96
+ private populateDefaultSettings;
97
+ /**
98
+ * Add a callback to fire when the numeric setting is toggled.
99
+ * @param id The id of the flag.
100
+ * @param onChangedListener The callback to fire when the numeric value changes.
101
+ */
102
+ _addOnNumericSettingChangedListener(id: NumericParametersIds, onChangedListener: (newValue: number) => void): void;
103
+ _addOnOptionSettingChangedListener(id: OptionParametersIds, onChangedListener: (newValue: string) => void): void;
104
+ /**
105
+ * @param id The id of the numeric setting we are interested in getting a value for.
106
+ * @returns The numeric value stored in the parameter with the passed id.
107
+ */
108
+ getNumericSettingValue(id: NumericParametersIds): number;
109
+ /**
110
+ * @param id The id of the text setting we are interested in getting a value for.
111
+ * @returns The text value stored in the parameter with the passed id.
112
+ */
113
+ getTextSettingValue(id: TextParametersIds): string;
114
+ /**
115
+ * Set number in the setting.
116
+ * @param id The id of the numeric setting we are interested in.
117
+ * @param value The numeric value to set.
118
+ */
119
+ setNumericSetting(id: NumericParametersIds, value: number): void;
120
+ /**
121
+ * Add a callback to fire when the flag is toggled.
122
+ * @param id The id of the flag.
123
+ * @param onChangeListener The callback to fire when the value changes.
124
+ */
125
+ _addOnSettingChangedListener(id: FlagsIds, onChangeListener: (newFlagValue: boolean) => void): void;
126
+ /**
127
+ * Add a callback to fire when the text is changed.
128
+ * @param id The id of the flag.
129
+ * @param onChangeListener The callback to fire when the value changes.
130
+ */
131
+ _addOnTextSettingChangedListener(id: TextParametersIds, onChangeListener: (newTextValue: string) => void): void;
132
+ /**
133
+ * Get the option which has the given id.
134
+ * @param id The id of the option.
135
+ * @returns The SettingOption object matching id
136
+ */
137
+ getSettingOption(id: OptionParametersIds): SettingOption;
138
+ /**
139
+ * Get the value of the configuration flag which has the given id.
140
+ * @param id The unique id for the flag.
141
+ * @returns True if the flag is enabled.
142
+ */
143
+ isFlagEnabled(id: FlagsIds): boolean;
144
+ /**
145
+ * Set flag to be enabled/disabled.
146
+ * @param id The id of the flag to toggle.
147
+ * @param flagEnabled True if the flag should be enabled.
148
+ */
149
+ setFlagEnabled(id: FlagsIds, flagEnabled: boolean): void;
150
+ /**
151
+ * Set the text setting.
152
+ * @param id The id of the setting
153
+ * @param settingValue The value to set in the setting.
154
+ */
155
+ setTextSetting(id: TextParametersIds, settingValue: string): void;
156
+ /**
157
+ * Set the option setting list of options.
158
+ * @param id The id of the setting
159
+ * @param settingOptions The values the setting could take
160
+ */
161
+ setOptionSettingOptions(id: OptionParametersIds, settingOptions: Array<string>): void;
162
+ /**
163
+ * Set option enum settings selected option.
164
+ * @param id The id of the setting
165
+ * @param settingOptions The value to select out of all the options
166
+ */
167
+ setOptionSettingValue(id: OptionParametersIds, settingValue: string): void;
168
+ /**
169
+ * Set the label for the flag.
170
+ * @param id The id of the flag.
171
+ * @param label The new label to use for the flag.
172
+ */
173
+ setFlagLabel(id: FlagsIds, label: string): void;
174
+ /**
175
+ * Set a subset of all settings in one function call.
176
+ *
177
+ * @param settings A (partial) list of settings to set
178
+ */
179
+ setSettings(settings: Partial<AllSettings>): void;
180
+ /**
181
+ * Get all settings
182
+ * @returns All setting values as an object with setting ids as keys
183
+ */
184
+ getSettings(): Partial<AllSettings>;
185
+ /**
186
+ * Get all Flag settings as an array.
187
+ * @returns All SettingFlag objects
188
+ */
189
+ getFlags(): Array<SettingFlag>;
190
+ /**
191
+ * Get all Text settings as an array.
192
+ * @returns All SettingText objects
193
+ */
194
+ getTextSettings(): Array<SettingText>;
195
+ /**
196
+ * Get all Number settings as an array.
197
+ * @returns All SettingNumber objects
198
+ */
199
+ getNumericSettings(): Array<SettingNumber>;
200
+ /**
201
+ * Get all Option settings as an array.
202
+ * @returns All SettingOption objects
203
+ */
204
+ getOptionSettings(): Array<SettingOption>;
205
+ /**
206
+ * Emit events when settings change.
207
+ * @param eventEmitter
208
+ */
209
+ _registerOnChangeEvents(eventEmitter: EventEmitter): void;
210
+ }
211
+ /**
212
+ * The enum associated with the mouse being locked or hovering
213
+ */
214
+ export declare enum ControlSchemeType {
215
+ LockedMouse = 0,
216
+ HoveringMouse = 1
217
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Base class for a setting that has a text label and an arbitrary setting value it stores.
3
+ */
4
+ export declare class SettingBase {
5
+ id: string;
6
+ description: string;
7
+ _label: string;
8
+ _value: unknown;
9
+ onChange: (changedValue: unknown, setting: SettingBase) => void;
10
+ onChangeEmit: (changedValue: unknown) => void;
11
+ constructor(id: string, label: string, description: string, defaultSettingValue: unknown, defaultOnChangeListener?: (changedValue: unknown, setting: SettingBase) => void);
12
+ /**
13
+ * Set the label text for the setting.
14
+ * @param label setting label.
15
+ */
16
+ set label(inLabel: string);
17
+ /**
18
+ * @returns The label text for the setting.
19
+ */
20
+ get label(): string;
21
+ /**
22
+ * @return The setting's value.
23
+ */
24
+ get value(): unknown;
25
+ /**
26
+ * Update the setting's stored value.
27
+ * @param inValue The new value for the setting.
28
+ */
29
+ set value(inValue: unknown);
30
+ }