UNPKG

@nethesis/phone-island

Version:
1 lines 56.7 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t,r=require("../../_virtual/janus.js");t=r.__module,e=function(){t.sessions=new Map,t.isExtensionEnabled=function(){if(navigator.mediaDevices&&navigator.mediaDevices.getDisplayMedia)return!0;if(window.navigator.userAgent.match("Chrome")){let e=parseInt(window.navigator.userAgent.match(/Chrome\/(.*) /)[1],10),r=33;return window.navigator.userAgent.match("Linux")&&(r=35),e>=26&&e<=r||t.extension.isInstalled()}return!0};var e={extensionId:"hapfgfdkleiggjjpfpenajgdnfckjpaj",isInstalled:function(){return null!==document.querySelector("#janus-extension-installed")},getScreen:function(e){let t=window.setTimeout((function(){let t=new Error("NavigatorUserMediaError");return t.name='The required Chrome extension is not installed: click <a href="#">here</a> to install it. (NOTE: this will need you to refresh the page)',e(t)}),1e3);this.cache[t]=e,window.postMessage({type:"janusGetScreen",id:t},"*")},init:function(){let e={};this.cache=e,window.addEventListener("message",(function(t){if(t.origin==window.location.origin)if("janusGotScreen"==t.data.type&&e[t.data.id]){let r=e[t.data.id];if(delete e[t.data.id],""===t.data.sourceId){let e=new Error("NavigatorUserMediaError");e.name="You cancelled the request for permission, giving up...",r(e)}else r(null,t.data.sourceId)}else"janusGetScreenPending"==t.data.type&&(console.log("clearing ",t.data.id),window.clearTimeout(t.data.id))}))}};function t(e){if((e=e||{}).success="function"==typeof e.success?e.success:t.noop,e.error="function"==typeof e.error?e.error:t.noop,e.destroyed="function"==typeof e.destroyed?e.destroyed:t.noop,!t.initDone)return e.error("Library not initialized"),{};if(!t.isWebrtcSupported())return e.error("WebRTC not supported by this browser"),{};if(t.log("Library initialized: "+t.initDone),!e.server)return e.error("Invalid server url"),{};let r=!1,n=null,o={},a=null,i=null,s=0,c=e.server;t.isArray(c)?(t.log("Multiple servers provided ("+c.length+"), will use the first that works"),c=null,i=e.server,t.debug(i)):0===c.indexOf("ws")?(r=!0,t.log("Using WebSockets to contact Janus: "+c)):(r=!1,t.log("Using REST API to contact Janus: "+c));let d=e.iceServers||[{urls:"stun:stun.l.google.com:19302"}],l=e.iceTransportPolicy,u=e.bundlePolicy,f=!1;void 0!==e.withCredentials&&null!==e.withCredentials&&(f=!0===e.withCredentials);let p=10;void 0!==e.max_poll_events&&null!==e.max_poll_events&&(p=e.max_poll_events),p<1&&(p=1);let g=null;void 0!==e.token&&null!==e.token&&(g=e.token);let m=null;void 0!==e.apisecret&&null!==e.apisecret&&(m=e.apisecret),this.destroyOnUnload=!0,void 0!==e.destroyOnUnload&&null!==e.destroyOnUnload&&(this.destroyOnUnload=!0===e.destroyOnUnload);let v=25e3;void 0!==e.keepAlivePeriod&&null!==e.keepAlivePeriod&&(v=e.keepAlivePeriod),isNaN(v)&&(v=25e3);let h=6e4;function b(e){let t={high:9e5,medium:3e5,low:1e5};return null!=e&&(e.high&&(t.high=e.high),e.medium&&(t.medium=e.medium),e.low&&(t.low=e.low)),t}void 0!==e.longPollTimeout&&null!==e.longPollTimeout&&(h=e.longPollTimeout),isNaN(h)&&(h=6e4);let w=!1,y=null,S=new Map,k=this,C=0,T=new Map;function I(){if(null==y)return;if(t.debug("Long poll..."),!w)return void t.warn("Is the server down? (connected=false)");let r=c+"/"+y+"?rid="+(new Date).getTime();p&&(r=r+"&maxev="+p),g&&(r=r+"&token="+encodeURIComponent(g)),m&&(r=r+"&apisecret="+encodeURIComponent(m)),t.httpAPICall(r,{verb:"GET",withCredentials:f,success:R,timeout:h,error:function(r,n){if(t.error(r+":",n),C++,C>3)return w=!1,void e.error("Lost connection to the server (is it down?)");I()}})}function R(e,o){if(C=0,r||null==y||!0===o||I(),r||!t.isArray(e))if("keepalive"!==e.janus)if("server_info"!==e.janus)if("ack"!==e.janus)if("success"!==e.janus)if("trickle"===e.janus){const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);if(!n)return void t.debug("This handle is not attached to this session");let o=e.candidate;t.debug("Got a trickled candidate on session "+y),t.debug(o);let a=n.webrtcStuff;a.pc&&a.remoteSdp?(t.debug("Adding remote candidate:",o),o&&!0!==o.completed?a.pc.addIceCandidate(o):a.pc.addIceCandidate(t.endOfCandidates)):(t.debug("We didn't do setRemoteDescription (trickle got here before the offer?), caching candidate"),a.candidates||(a.candidates=[]),a.candidates.push(o),t.debug(a.candidates))}else{if("webrtcup"===e.janus){t.debug("Got a webrtcup event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);return n?void n.webrtcState(!0):void t.debug("This handle is not attached to this session")}if("hangup"===e.janus){t.debug("Got a hangup event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);if(!n)return void t.debug("This handle is not attached to this session");n.webrtcState(!1,e.reason),n.hangup()}else if("detached"===e.janus){t.debug("Got a detached event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);if(!n)return;n.ondetached(),n.detach()}else if("media"===e.janus){t.debug("Got a media event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);if(!n)return void t.debug("This handle is not attached to this session");n.mediaState(e.type,e.receiving,e.mid)}else if("slowlink"===e.janus){t.debug("Got a slowlink event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");const n=S.get(r);if(!n)return void t.debug("This handle is not attached to this session");n.slowLink(e.uplink,e.lost,e.mid)}else{if("error"===e.janus){t.error("Ooops: "+e.error.code+" "+e.error.reason),t.debug(e);let r=e.transaction;if(r){let t=T.get(r);t&&t(e),T.delete(r)}return}if("event"===e.janus){t.debug("Got a plugin event on session "+y),t.debug(e);const r=e.sender;if(!r)return void t.warn("Missing sender...");let n=e.plugindata;if(!n)return void t.warn("Missing plugindata...");t.debug(" -- Event is coming from "+r+" ("+n.plugin+")");let o=n.data;t.debug(o);const a=S.get(r);if(!a)return void t.warn("This handle is not attached to this session");let i=e.jsep;i&&(t.debug("Handling SDP as well..."),t.debug(i));let s=a.onmessage;s?(t.debug("Notifying application..."),s(o,i)):t.debug("No provided notification callback")}else{if("timeout"===e.janus)return t.error("Timeout on session "+y),t.debug(e),void(r&&n.close(3504,"Gateway timeout"));t.warn("Unknown message/event '"+e.janus+"' on session "+y),t.debug(e)}}}else{t.debug("Got a success on session "+y),t.debug(e);const r=e.transaction;if(r){const t=T.get(r);t&&t(e),T.delete(r)}}else{t.debug("Got an ack on session "+y),t.debug(e);const r=e.transaction;if(r){const t=T.get(r);t&&t(e),T.delete(r)}}else{t.debug("Got info on the Janus instance"),t.debug(e);const r=e.transaction;if(r){const t=T.get(r);t&&t(e),T.delete(r)}}else t.vdebug("Got a keepalive on session "+y);else for(let t=0;t<e.length;t++)R(e[t],!0)}function A(){if(!c||!r||!w)return;a=setTimeout(A,v);let e={janus:"keepalive",session_id:y,transaction:t.randomString(12)};g&&(e.token=g),m&&(e.apisecret=m),n.send(JSON.stringify(e))}function D(d){let l=t.randomString(12),u={janus:"create",transaction:l};if(d.reconnect&&(w=!1,u.janus="claim",u.session_id=y,n&&(n.onopen=null,n.onerror=null,n.onclose=null,a&&(clearTimeout(a),a=null))),g&&(u.token=g),m&&(u.apisecret=m),!c&&t.isArray(i)&&(c=i[s],0===c.indexOf("ws")?(r=!0,t.log("Server #"+(s+1)+": trying WebSockets to contact Janus ("+c+")")):(r=!1,t.log("Server #"+(s+1)+": trying REST API to contact Janus ("+c+")"))),r){n=t.newWebSocket(c,"janus-protocol"),o={error:function(){if(t.error("Error connecting to the Janus WebSockets server... "+c),t.isArray(i)&&!d.reconnect)return s++,s===i.length?void d.error("Error connecting to any of the provided Janus servers: Is the server down?"):(c=null,void setTimeout((function(){D(d)}),200));d.error("Error connecting to the Janus WebSockets server: Is the server down?")},open:function(){T.set(l,(function(e){if(t.debug(e),"success"!==e.janus)return t.error("Ooops: "+e.error.code+" "+e.error.reason),void d.error(e.error.reason);a=setTimeout(A,v),w=!0,y=e.session_id?e.session_id:e.data.id,d.reconnect?t.log("Claimed session: "+y):t.log("Created session: "+y),t.sessions.set(y,k),d.success()})),n.send(JSON.stringify(u))},message:function(e){R(JSON.parse(e.data))},close:function(){c&&w&&(w=!1,e.error("Lost connection to the server (is it down?)"))}};for(let e in o)n.addEventListener(e,o[e])}else t.httpAPICall(c,{verb:"POST",withCredentials:f,body:u,success:function(e){if(t.debug(e),"success"!==e.janus)return t.error("Ooops: "+e.error.code+" "+e.error.reason),void d.error(e.error.reason);w=!0,y=e.session_id?e.session_id:e.data.id,d.reconnect?t.log("Claimed session: "+y):t.log("Created session: "+y),t.sessions.set(y,k),I(),d.success()},error:function(e,r){if(t.error(e+":",r),t.isArray(i)&&!d.reconnect)return s++,s===i.length?void d.error("Error connecting to any of the provided Janus servers: Is the server down?"):(c=null,void setTimeout((function(){D(d)}),200));""===r?d.error(e+": Is the server down?"):r&&r.error?d.error(e+": "+r.error.message):d.error(e+": "+r)}})}function P(e,o){if((o=o||{}).success="function"==typeof o.success?o.success:t.noop,o.error="function"==typeof o.error?o.error:t.noop,!w)return t.warn("Is the server down? (connected=false)"),void o.error("Is the server down? (connected=false)");let a=S.get(e);if(!a||!a.webrtcStuff)return t.warn("Invalid handle"),void o.error("Invalid handle");let i=o.message,s=o.jsep,d=t.randomString(12),l={janus:"message",body:i,transaction:d};if(a.token&&(l.token=a.token),m&&(l.apisecret=m),s){l.jsep={type:s.type,sdp:s.sdp},s.e2ee&&(l.jsep.e2ee=!0),"hml"!==s.rid_order&&"lmh"!==s.rid_order||(l.jsep.rid_order=s.rid_order),s.force_relay&&(l.jsep.force_relay=!0);let e=null,t=a.webrtcStuff;if(t.pc){let r=t.pc.getTransceivers();if(r&&r.length>0)for(let t in r){let n=r[t];if(n&&n.sender&&n.sender.track&&"video"===n.sender.track.kind){let r=n.sender.getParameters();r&&r.encodings&&r.encodings[0]&&r.encodings[0].scalabilityMode&&(e||(e=[]),e.push({mindex:parseInt(t),mid:n.mid,svc:r.encodings[0].scalabilityMode}))}}}e&&(l.jsep.svc=e)}if(t.debug("Sending message to plugin (handle="+e+"):"),t.debug(l),r)return l.session_id=y,l.handle_id=e,T.set(d,(function(e){if(t.debug("Message sent!"),t.debug(e),"success"===e.janus){let r=e.plugindata;if(!r)return t.warn("Request succeeded, but missing plugindata..."),void o.success();t.log("Synchronous transaction successful ("+r.plugin+")");let n=r.data;return t.debug(n),void o.success(n)}"ack"===e.janus?o.success():e.error?(t.error("Ooops: "+e.error.code+" "+e.error.reason),o.error(e.error.code+" "+e.error.reason)):(t.error("Unknown error"),o.error("Unknown error"))})),void n.send(JSON.stringify(l));t.httpAPICall(c+"/"+y+"/"+e,{verb:"POST",withCredentials:f,body:l,success:function(e){if(t.debug("Message sent!"),t.debug(e),"success"===e.janus){let r=e.plugindata;if(!r)return t.warn("Request succeeded, but missing plugindata..."),void o.success();t.log("Synchronous transaction successful ("+r.plugin+")");let n=r.data;return t.debug(n),void o.success(n)}"ack"===e.janus?o.success():e.error?(t.error("Ooops: "+e.error.code+" "+e.error.reason),o.error(e.error.code+" "+e.error.reason)):(t.error("Unknown error"),o.error("Unknown error"))},error:function(e,r){t.error(e+":",r),o.error(e+": "+r)}})}function E(e,o){if(!w)return void t.warn("Is the server down? (connected=false)");let a=S.get(e);if(!a||!a.webrtcStuff)return void t.warn("Invalid handle");let i={janus:"trickle",candidate:o,transaction:t.randomString(12)};if(a.token&&(i.token=a.token),m&&(i.apisecret=m),t.vdebug("Sending trickle candidate (handle="+e+"):"),t.vdebug(i),r)return i.session_id=y,i.handle_id=e,void n.send(JSON.stringify(i));t.httpAPICall(c+"/"+y+"/"+e,{verb:"POST",withCredentials:f,body:i,success:function(e){t.vdebug("Candidate sent!"),t.vdebug(e),"ack"===e.janus||t.error("Ooops: "+e.error.code+" "+e.error.reason)},error:function(e,r){t.error(e+":",r)}})}function j(e,r,n,o,a){let i=S.get(e);if(!i||!i.webrtcStuff)return void t.warn("Invalid handle");let s=i.webrtcStuff;if(!s.pc)return void t.warn("Invalid PeerConnection");let c=function(e){t.log("Received state change on data channel:",e);let r=e.target.label,n=e.target.protocol,o=s.dataChannel[r]?s.dataChannel[r].readyState:"null";if(t.log("State change on <"+r+"> data channel: "+o),"open"===o){if(s.dataChannel[r].pending&&s.dataChannel[r].pending.length>0){t.log("Sending pending messages on <"+r+">:",s.dataChannel[r].pending.length);for(let e of s.dataChannel[r].pending)t.log("Sending data on data channel <"+r+">"),t.debug(e),s.dataChannel[r].send(e);s.dataChannel[r].pending=[]}i.ondataopen(r,n)}};if(o)s.dataChannel[r]=o;else{let e=s.dataChannelOptions;n&&(e.protocol=n),s.dataChannel[r]=s.pc.createDataChannel(r,e)}s.dataChannel[r].onmessage=function(e){t.log("Received message on data channel:",e);let r=e.target.label;i.ondata(e.data,r)},s.dataChannel[r].onopen=c,s.dataChannel[r].onclose=c,s.dataChannel[r].onerror=function(e){t.error("Got error on data channel:",e)},s.dataChannel[r].pending=[],a&&s.dataChannel[r].pending.push(a)}function O(e,r){(r=r||{}).success="function"==typeof r.success?r.success:t.noop,r.error="function"==typeof r.error?r.error:t.noop;let n=S.get(e);if(!n||!n.webrtcStuff)return t.warn("Invalid handle"),void r.error("Invalid handle");let o=n.webrtcStuff,a=r.text||r.data;if(!a)return t.warn("Invalid data"),void r.error("Invalid data");let i=r.label?r.label:t.dataChanDefaultLabel;return o.dataChannel[i]?"open"!==o.dataChannel[i].readyState?(o.dataChannel[i].pending.push(a),void r.success()):(t.log("Sending data on data channel <"+i+">"),t.debug(a),o.dataChannel[i].send(a),void r.success()):(j(e,i,r.protocol,!1,a,r.protocol),void r.success())}function x(e,r){(r=r||{}).success="function"==typeof r.success?r.success:t.noop,r.error="function"==typeof r.error?r.error:t.noop;let n=S.get(e);if(!n||!n.webrtcStuff)return t.warn("Invalid handle"),void r.error("Invalid handle");let o=n.webrtcStuff;if(!o.dtmfSender){if(o.pc){let e=o.pc.getSenders().find((function(e){return e.track&&"audio"===e.track.kind}));if(!e)return t.warn("Invalid DTMF configuration (no audio track)"),void r.error("Invalid DTMF configuration (no audio track)");o.dtmfSender=e.dtmf,o.dtmfSender&&(t.log("Created DTMF Sender"),o.dtmfSender.ontonechange=function(e){t.debug("Sent DTMF tone: "+e.tone)})}if(!o.dtmfSender)return t.warn("Invalid DTMF configuration"),void r.error("Invalid DTMF configuration")}let a=r.dtmf;if(!a)return t.warn("Invalid DTMF parameters"),void r.error("Invalid DTMF parameters");let i=a.tones;if(!i)return t.warn("Invalid DTMF string"),void r.error("Invalid DTMF string");let s="number"==typeof a.duration?a.duration:500,c="number"==typeof a.gap?a.gap:50;t.debug("Sending DTMF string "+i+" (duration "+s+"ms, gap "+c+"ms)"),o.dtmfSender.insertDTMF(i,s,c),r.success()}function M(e,o){(o=o||{}).success="function"==typeof o.success?o.success:t.noop,o.error="function"==typeof o.error?o.error:t.noop;let a=!0===o.noRequest;t.log("Destroying handle "+e+" (only-locally="+a+")"),Q(e);let i=S.get(e);if(!i||i.detached)return S.delete(e),void o.success();if(i.detached=!0,a)return S.delete(e),void o.success();if(!w)return t.warn("Is the server down? (connected=false)"),void o.error("Is the server down? (connected=false)");let s={janus:"detach",transaction:t.randomString(12)};if(i.token&&(s.token=i.token),m&&(s.apisecret=m),r)return s.session_id=y,s.handle_id=e,n.send(JSON.stringify(s)),S.delete(e),void o.success();t.httpAPICall(c+"/"+y+"/"+e,{verb:"POST",withCredentials:f,body:s,success:function(r){t.log("Destroyed handle:"),t.debug(r),"success"!==r.janus&&t.error("Ooops: "+r.error.code+" "+r.error.reason),S.delete(e),o.success()},error:function(r,n){t.error(r+":",n),S.delete(e),o.success()}})}function N(e,r){let n=S.get(e);if(!n||!n.webrtcStuff)throw t.warn("Invalid handle"),"Invalid handle";let o=n.webrtcStuff;if(o.pc)return;let a={iceServers:d,iceTransportPolicy:l,bundlePolicy:u,sdpSemantics:"unified-plan"},i=!1;if(r.tracks)for(let e of r.tracks)if(e.transforms&&(e.transforms.sender||e.transforms.receiver)){i=!0;break}r.externalEncryption&&(i=!0,o.externalEncryption=!0),RTCRtpSender&&(RTCRtpSender.prototype.createEncodedStreams||RTCRtpSender.prototype.createEncodedAudioStreams&&RTCRtpSender.prototype.createEncodedVideoStreams)&&i&&(o.insertableStreams=!0,a.forceEncodedAudioInsertableStreams=!0,a.forceEncodedVideoInsertableStreams=!0,a.encodedInsertableStreams=!0),t.log("Creating PeerConnection"),o.pc=new RTCPeerConnection(a),t.debug(o.pc),o.pc.getStats&&(o.volume={},o.bitrate.value="0 kbits/sec"),t.log("Preparing local SDP and gathering candidates (trickle="+o.trickle+")"),o.pc.onconnectionstatechange=function(){o.pc&&n.connectionState(o.pc.connectionState)},o.pc.oniceconnectionstatechange=function(){o.pc&&n.iceState(o.pc.iceConnectionState)},o.pc.onicecandidate=function(n){if(!n.candidate||n.candidate.candidate&&n.candidate.candidate.indexOf("endOfCandidates")>0)t.log("End of candidates."),o.iceDone=!0,!0===o.trickle?E(e,{completed:!0}):function(e,r){(r=r||{}).success="function"==typeof r.success?r.success:t.noop,r.error="function"==typeof r.error?r.error:t.noop;let n=S.get(e);if(!n||!n.webrtcStuff)return void t.warn("Invalid handle, not sending anything");let o=n.webrtcStuff;t.log("Sending offer/answer SDP..."),o.mySdp?(o.mySdp={type:o.pc.localDescription.type,sdp:o.pc.localDescription.sdp},!1===o.trickle&&(o.mySdp.trickle=!1),t.debug(r),o.sdpSent=!0,r.success(o.mySdp)):t.warn("Local SDP instance is invalid, not sending anything...")}(e,r);else{let t={candidate:n.candidate.candidate,sdpMid:n.candidate.sdpMid,sdpMLineIndex:n.candidate.sdpMLineIndex};!0===o.trickle&&E(e,t)}},o.pc.ontrack=function(e){if(t.log("Handling Remote Track",e),!e.streams)return;if(!e.track)return;let r=e.transceiver?e.transceiver.mid:e.track.id;try{e.transceiver&&e.transceiver.mid&&e.track.id&&(n.mids||(n.mids={}),n.mids[e.track.id]=e.transceiver.mid),n.onremotetrack(e.track,r,!0,{reason:"created"})}catch(e){t.error("Error calling onremotetrack",e)}if(e.track.onended)return;let a=null;t.log("Adding onended callback to track:",e.track),e.track.onended=function(r){t.log("Remote track removed:",r),clearTimeout(a);let i=o.pc?o.pc.getTransceivers():null,s=i?i.find((e=>e.receiver.track===r.target)):null,c=s?s.mid:r.target.id;c===r.target.id&&n.mids&&n.mids[e.track.id]&&(c=n.mids[e.track.id]);try{n.onremotetrack(r.target,c,!1,{reason:"ended"})}catch(e){t.error("Error calling onremotetrack on removal",e)}delete n.mids[e.track.id]},e.track.onmute=function(r){t.log("Remote track muted:",r),a||(a=setTimeout((function(){t.log("Removing remote track");let i=o.pc?o.pc.getTransceivers():null,s=i?i.find((e=>e.receiver.track===r.target)):null,c=s?s.mid:r.target.id;c===r.target.id&&n.mids&&n.mids[e.track.id]&&(c=n.mids[e.track.id]);try{n.onremotetrack(r.target,c,!1,{reason:"mute"})}catch(e){t.error("Error calling onremotetrack on mute",e)}a=null}),2520))},e.track.onunmute=function(e){if(t.log("Remote track flowing again:",e),null!=a)clearTimeout(a),a=null;else try{let t=o.pc?o.pc.getTransceivers():null,r=t?t.find((t=>t.receiver.track===e.target)):null,a=r?r.mid:e.target.id;n.onremotetrack(e.target,a,!0,{reason:"unmute"})}catch(e){t.error("Error calling onremotetrack on unmute",e)}}}}async function V(e,r,n){(n=n||{}).success="function"==typeof n.success?n.success:t.noop,n.error="function"==typeof n.error?n.error:H;let o=n.jsep;if(r&&o)return t.error("Provided a JSEP to a createOffer"),void n.error("Provided a JSEP to a createOffer");if(!(r||o&&o.type&&o.sdp))return t.error("A valid JSEP is required for createAnswer"),void n.error("A valid JSEP is required for createAnswer");if(n.media&&!n.tracks){if(n.tracks=t.mediaToTracks(n.media),!0===n.simulcast||!0===n.simulcast2||n.svc)for(let e of n.tracks)if("video"===e.type){!0===n.simulcast||!0===n.simulcast2?e.simulcast=!0:n.svc&&(e.svc=n.svc);break}t.warn("Deprecated media object passed, use tracks instead. Automatically translated to:",n.tracks)}if(n.tracks&&!Array.isArray(n.tracks))return t.error("Tracks must be an array"),void n.error("Tracks must be an array");let a=S.get(e);if(!a||!a.webrtcStuff)return t.warn("Invalid handle"),void n.error("Invalid handle");let i=a.webrtcStuff;var s;i.trickle=(s=n.trickle,t.debug("isTrickleEnabled:",s),!1!==s);try{if(N(e,n),r&&await _(e,n),o){if(await i.pc.setRemoteDescription(o),t.log("Remote description accepted!"),i.remoteSdp=o.sdp,i.candidates&&i.candidates.length>0){for(let e=0;e<i.candidates.length;e++){let r=i.candidates[e];t.debug("Adding remote candidate:",r),r&&!0!==r.completed?i.pc.addIceCandidate(r):i.pc.addIceCandidate(t.endOfCandidates)}i.candidates=[]}await _(e,n);let r=await async function(e,r){(r=r||{}).customizeSdp="function"==typeof r.customizeSdp?r.customizeSdp:t.noop;let n=S.get(e);if(!n||!n.webrtcStuff)throw t.warn("Invalid handle"),"Invalid handle";let o=n.webrtcStuff;t.log("Creating answer (iceDone="+o.iceDone+")");let a=await o.pc.createAnswer();t.debug(a);let i={type:"answer",sdp:a.sdp};return r.customizeSdp(i),a.sdp=i.sdp,t.log("Setting local description"),o.mySdp={type:"answer",sdp:a.sdp},await o.pc.setLocalDescription(a),o.iceDone||o.trickle?((o.insertableStreams||o.externalEncryption)&&(a.e2ee=!0),a):(t.log("Waiting for all candidates..."),null)}(e,n);n.success(r)}else{let r=await async function(e,r){(r=r||{}).customizeSdp="function"==typeof r.customizeSdp?r.customizeSdp:t.noop;let n=S.get(e);if(!n||!n.webrtcStuff)throw t.warn("Invalid handle"),"Invalid handle";let o=n.webrtcStuff;t.log("Creating offer (iceDone="+o.iceDone+")");let a={},i=!0===r.iceRestart;i&&(a.iceRestart=!0),t.debug(a);let s=await o.pc.createOffer(a);t.debug(s);let c={type:"offer",sdp:s.sdp};return r.customizeSdp(c),s.sdp=c.sdp,t.log("Setting local description"),o.mySdp={type:"offer",sdp:s.sdp},await o.pc.setLocalDescription(s),o.mediaConstraints=a,o.iceDone||o.trickle?((o.insertableStreams||o.externalEncryption)&&(s.e2ee=!0),s):(t.log("Waiting for all candidates..."),null)}(e,n);n.success(r)}}catch(e){t.error(e),n.error(e)}}function L(e,r){(r=r||{}).success="function"==typeof r.success?r.success:t.noop,r.error="function"==typeof r.error?r.error:H,r.customizeSdp="function"==typeof r.customizeSdp?r.customizeSdp:t.noop;let n=r.jsep,o=S.get(e);if(!o||!o.webrtcStuff)return t.warn("Invalid handle"),void r.error("Invalid handle");let a=o.webrtcStuff;if(n){if(!a.pc)return t.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep"),void r.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep");r.customizeSdp(n),a.pc.setRemoteDescription(n).then((function(){if(t.log("Remote description accepted!"),a.remoteSdp=n.sdp,a.candidates&&a.candidates.length>0){for(let e=0;e<a.candidates.length;e++){let r=a.candidates[e];t.debug("Adding remote candidate:",r),r&&!0!==r.completed?a.pc.addIceCandidate(r):a.pc.addIceCandidate(t.endOfCandidates)}a.candidates=[]}r.success()}),r.error)}else r.error("Invalid JSEP")}async function G(e,r){if((r=r||{}).success="function"==typeof r.success?r.success:t.noop,r.error="function"==typeof r.error?r.error:t.noop,r.tracks&&!Array.isArray(r.tracks))return t.error("Tracks must be an array"),void r.error("Tracks must be an array");for(let e of r.tracks)(e.add||!e.replace&&!e.remove)&&(e.replace=!0);try{await _(e,r),r.success()}catch(e){t.error(e),r.error(e)}}async function _(e,r){let n=S.get(e);if(!n||!n.webrtcStuff)throw t.warn("Invalid handle, not sending anything"),"Invalid handle";let o=n.webrtcStuff;if(!o.pc)throw t.warn("Invalid PeerConnection"),"Invalid PeerConnection";let a=r.tracks;if(!a||!Array.isArray(a)||0===a.length)return;let i=!1,s={};for(let e of a){if(delete e.gumGroup,!e.type||!["audio","video"].includes(e.type))continue;if(!e.capture||e.capture instanceof MediaStreamTrack)continue;let t=e.group?e.group:"default";s[t]||(s[t]={}),s[t][e.type]||(e.gumGroup=t,s[t][e.type]=e)}let c=Object.keys(s);for(let e of c){let t=s[e];t.audio&&t.video||(t.audio&&delete t.audio.gumGroup,t.video&&delete t.video.gumGroup,delete s[e])}let d=!!r.jsep;for(let c of a){if(!c.type){t.warn("Missing track type:",c);continue}if("data"===c.type){if(o.pc.ondatachannel){t.warn("Data channel exists already, not creating another one");continue}t.log("Creating default data channel"),j(e,t.dataChanDefaultLabel,null,!1),o.pc.ondatachannel=function(r){t.log("Data channel created by Janus:",r),j(e,r.channel.label,r.channel.protocol,r.channel)};continue}if(void 0!==c.add&&null!==c.add||void 0!==c.remove&&null!==c.remove||void 0!==c.replace&&null!==c.replace||(c.add=!0),c.add&&c.remove||c.add&&c.remove&&c.replace){t.warn("Conflicting actions for track, ignoring:",c);continue}c.add&&c.replace?(t.warn("Both add and replace provided, falling back to replace:",c),delete c.add):c.remove&&c.replace&&(t.warn("Both remove and replace provided, falling back to remove:",c),delete c.replace);let a=c.type;"screen"===c.type&&(a="video");let l=null,u=null;if(c.mid?l=o.pc.getTransceivers().find((e=>e.mid===c.mid&&e.receiver.track.kind===a)):c.add||(l=o.pc.getTransceivers().find((e=>e.receiver.track.kind===a))),c.replace||c.remove){if(!l){t.warn("Couldn't find a transceiver for track:",c);continue}if(!l.sender){t.warn("No sender in the transceiver for track:",c);continue}u=l.sender}if(d&&!l&&(l=o.pc.getTransceivers().find((e=>e.receiver.track.kind===a)),!l)){t.warn("Couldn't find a transceiver for track:",c);continue}let f=null,p=null;if((c.remove||c.replace)&&(t.log("Removing track from PeerConnection",c),p=u.track?u.track.id:null,await u.replaceTrack(null),p&&o.myStream)){let e=null;if("audio"===a&&o.myStream.getAudioTracks()&&o.myStream.getAudioTracks().length)for(let r of o.myStream.getAudioTracks())r.id===p&&(e=r,t.log("Removing audio track:",e));else if("video"===a&&o.myStream.getVideoTracks()&&o.myStream.getVideoTracks().length)for(let r of o.myStream.getVideoTracks())r.id===p&&(e=r,t.log("Removing video track:",e));if(e){try{o.myStream.removeTrack(e),n.onlocaltrack(e,!1)}catch(e){t.error("Error calling onlocaltrack on removal for renegotiation",e)}if(!0!==e.dontStop)try{e.stop()}catch(e){}}}if(c.capture){if(c.gumGroup&&s[c.gumGroup]&&s[c.gumGroup].stream){let e=s[c.gumGroup].stream;f="audio"===c.type?e.getAudioTracks()[0]:e.getVideoTracks()[0],delete s[c.gumGroup].stream,delete s[c.gumGroup],delete c.gumGroup}else if(c.capture instanceof MediaStreamTrack)f=c.capture;else{i||(i=!0,n.consentDialog(!0));let e=t.trackConstraints(c),r=null;if("audio"===c.type||"video"===c.type){if(c.gumGroup){let r="audio"===c.type?"video":"audio";if(s[c.gumGroup]&&s[c.gumGroup][r]){let n=s[c.gumGroup][r],o=t.trackConstraints(n);e[r]=o[r]}}r=await navigator.mediaDevices.getUserMedia(e),c.gumGroup&&e.audio&&e.video&&(s[c.gumGroup].stream=r,delete c.gumGroup)}else r=await navigator.mediaDevices.getDisplayMedia(e);f="audio"===c.type?r.getAudioTracks()[0]:r.getVideoTracks()[0]}if(c.replace){await u.replaceTrack(f);let e="sendrecv";!1!==c.recv&&"inactive"!==l.direction&&"sendonly"!==l.direction||(e="sendonly"),l.setDirection?l.setDirection(e):l.direction=e}else{if(o.myStream||(o.myStream=new MediaStream),!o.pc)try{N(e,r)}catch(e){throw t.warn("Could not create PeerConnection"),"Could not create PeerConnection: "+e}if("audio"===a||!c.simulcast&&!c.svc)u=o.pc.addTrack(f,o.myStream),l=o.pc.getTransceivers().find((e=>e.sender===u));else if(c.simulcast){if("firefox"!==t.webRTCAdapter.browserDetails.browser){t.log("Enabling rid-based simulcasting:",f);let e=b(c.simulcastMaxBitrates);o.myStream||(o.myStream=new MediaStream),l=o.pc.addTransceiver(f,{direction:"sendrecv",streams:[o.myStream],sendEncodings:c.sendEncodings||[{rid:"h",active:!0,scalabilityMode:"L1T2",maxBitrate:e.high},{rid:"m",active:!0,scalabilityMode:"L1T2",maxBitrate:e.medium,scaleResolutionDownBy:2},{rid:"l",active:!0,scalabilityMode:"L1T2",maxBitrate:e.low,scaleResolutionDownBy:4}]})}else if(t.log("Enabling Simulcasting for Firefox (RID)"),o.myStream||(o.myStream=new MediaStream),l=o.pc.addTransceiver(f,{direction:"sendrecv",streams:[o.myStream]}),u=l?l.sender:null,u){let e=u.getParameters();e||(e={});let t=b(c.simulcastMaxBitrates);e.encodings=c.sendEncodings||[{rid:"h",active:!0,maxBitrate:t.high},{rid:"m",active:!0,maxBitrate:t.medium,scaleResolutionDownBy:2},{rid:"l",active:!0,maxBitrate:t.low,scaleResolutionDownBy:4}],u.setParameters(e)}}else t.log("Enabling SVC ("+c.svc+"):",f),o.myStream||(o.myStream=new MediaStream),l=o.pc.addTransceiver(f,{direction:"sendrecv",streams:[o.myStream],sendEncodings:[{scalabilityMode:c.svc}]});if(u||(u=l?l.sender:null),c.codec)if("firefox"===t.webRTCAdapter.browserDetails.browser)t.warn("setCodecPreferences not supported in Firefox, ignoring codec for track:",c);else if("string"!=typeof c.codec)t.warn("Invalid codec value, ignoring for track:",c);else{let e=a+"/"+c.codec.toLowerCase(),r=RTCRtpReceiver.getCapabilities(a).codecs.filter((function(t){return t.mimeType.toLowerCase()===e}));if(r&&0!==r.length){if(l)try{l.setCodecPreferences(r)}catch(e){t.warn("Failed enforcing codec for this "+a+" track:",e)}}else t.warn("Codec not supported in this browser for this track, ignoring:",c)}if(c.bitrate)if(c.simulcast||c.svc)t.warn("Ignoring bitrate for simulcast/SVC track, use sendEncodings for that");else if(isNaN(c.bitrate)||c.bitrate<0)t.warn("Ignoring invalid bitrate for track:",c);else if(u){let e=u.getParameters();e&&e.encodings&&0!==e.encodings.length?(e.encodings[0].maxBitrate=c.bitrate,await u.setParameters(e)):t.warn("No encodings in the sender parameters, ignoring bitrate for track:",c)}if("video"===a&&c.framerate)if(c.simulcast||c.svc)t.warn("Ignoring framerate for simulcast/SVC track, use sendEncodings for that");else if(isNaN(c.framerate)||c.framerate<0)t.warn("Ignoring invalid framerate for track:",c);else if(u){let e=u.getParameters();e&&e.encodings&&0!==e.encodings.length?(e.encodings[0].maxFramerate=c.framerate,await u.setParameters(e)):t.warn("No encodings in the sender parameters, ignoring framerate for track:",c)}if(c.transforms){if(u&&c.transforms.sender){let e=null;RTCRtpSender.prototype.createEncodedStreams?e=u.createEncodedStreams():(RTCRtpSender.prototype.createAudioEncodedStreams||RTCRtpSender.prototype.createEncodedVideoStreams)&&("audio"===a?e=u.createEncodedAudioStreams():"video"===a&&(e=u.createEncodedVideoStreams())),e&&(console.log("Insertable Streams sender transform:",e),e.readableStream&&e.writableStream?e.readableStream.pipeThrough(c.transforms.sender).pipeTo(e.writableStream):e.readable&&e.writable&&e.readable.pipeThrough(c.transforms.sender).pipeTo(e.writable))}if(l&&l.receiver&&c.transforms.receiver){let e=null;RTCRtpReceiver.prototype.createEncodedStreams?e=l.receiver.createEncodedStreams():(RTCRtpReceiver.prototype.createAudioEncodedStreams||RTCRtpReceiver.prototype.createEncodedVideoStreams)&&("audio"===a?e=l.receiver.createEncodedAudioStreams():"video"===a&&(e=l.receiver.createEncodedVideoStreams())),e&&(console.log("Insertable Streams receiver transform:",e),e.readableStream&&e.writableStream?e.readableStream.pipeThrough(c.transforms.receiver).pipeTo(e.writableStream):e.readable&&e.writable&&e.readable.pipeThrough(c.transforms.receiver).pipeTo(e.writable))}}}f&&!0===c.dontStop&&(f.dontStop=!0)}else if(c.recv&&(l||(l=o.pc.addTransceiver(a)),l)){if(c.codec)if("firefox"===t.webRTCAdapter.browserDetails.browser)t.warn("setCodecPreferences not supported in Firefox, ignoring codec for track:",c);else if("string"!=typeof c.codec)t.warn("Invalid codec value, ignoring for track:",c);else{let e=a+"/"+c.codec.toLowerCase(),r=RTCRtpReceiver.getCapabilities(a).codecs.filter((function(t){return t.mimeType.toLowerCase()===e}));if(r&&0!==r.length)try{l.setCodecPreferences(r)}catch(e){t.warn("Failed enforcing codec for this "+a+" track:",e)}else t.warn("Codec not supported in this browser for this track, ignoring:",c)}if(l.receiver&&c.transforms&&c.transforms.receiver){let e=null;RTCRtpReceiver.prototype.createEncodedStreams?e=l.receiver.createEncodedStreams():(RTCRtpReceiver.prototype.createAudioEncodedStreams||RTCRtpReceiver.prototype.createEncodedVideoStreams)&&("audio"===a?e=l.receiver.createEncodedAudioStreams():"video"===a&&(e=l.receiver.createEncodedVideoStreams())),e&&(console.log("Insertable Streams receiver transform:",e),e.readableStream&&e.writableStream?e.readableStream.pipeThrough(c.transforms.receiver).pipeTo(e.writableStream):e.readable&&e.writable&&e.readable.pipeThrough(c.transforms.receiver).pipeTo(e.writable))}}if(f){o.myStream||(o.myStream=new MediaStream),o.myStream.addTrack(f),f.onended=function(e){t.log("Local track removed:",e);try{n.onlocaltrack(e.target,!1)}catch(e){t.error("Error calling onlocaltrack following end",e)}};try{n.onlocaltrack(f,!0)}catch(e){t.error("Error calling onlocaltrack for track add",e)}}if(l){let e=l.direction,r=null,n=f&&l.sender.track,o=!1!==c.recv&&l.receiver.track;n&&o?r="sendrecv":n&&!o?r="sendonly":!n&&o?r="recvonly":n||o||(r="inactive"),r&&r!==e&&(t.warn("Changing direction of transceiver to "+r+" (was "+e+")",c),l.setDirection?l.setDirection(r):l.direction=r)}}i&&n.consentDialog(!1)}function J(e){let r=S.get(e);if(!r||!r.webrtcStuff)return t.warn("Invalid handle"),null;let n=r.webrtcStuff;if(!n.pc)return t.warn("Invalid PeerConnection"),null;let o=[],a=n.pc.getTransceivers();for(let e of a){let t=null;e.sender&&e.sender.track&&(t={mid:e.mid},t.type=e.sender.track.kind,t.id=e.sender.track.id,t.label=e.sender.track.label),t&&o.push(t)}return o}function F(e){let r=S.get(e);if(!r||!r.webrtcStuff)return t.warn("Invalid handle"),null;let n=r.webrtcStuff;if(!n.pc)return t.warn("Invalid PeerConnection"),null;let o=[],a=n.pc.getTransceivers();for(let e of a){let t=null;e.receiver&&e.receiver.track&&(t={mid:e.mid},t.type=e.receiver.track.kind,t.id=e.receiver.track.id,t.label=e.receiver.track.label),t&&o.push(t)}return o}function U(e,r,n,o){o="function"==typeof o?o:t.noop;let a=S.get(e);if(!a||!a.webrtcStuff)return t.warn("Invalid handle"),void o(0);let i=n?"remote":"local",s=a.webrtcStuff;if(s.volume[i]||(s.volume[i]={value:0}),s.pc&&s.pc.getStats&&("chrome"===t.webRTCAdapter.browserDetails.browser||"safari"===t.webRTCAdapter.browserDetails.browser)){let e=s.pc;if(r){let a=s.pc.getTransceivers().find((e=>e.mid===r&&"audio"===e.receiver.track.kind));if(!a)return t.warn("No audio transceiver with mid "+r),void o(0);if(n&&!a.receiver)return t.warn("Remote transceiver track unavailable"),void o(0);if(!n&&!a.sender)return t.warn("Local transceiver track unavailable"),void o(0);e=n?a.receiver:a.sender}return e.getStats().then((function(e){e.forEach((function(e){e&&"audio"===e.kind&&(n&&!e.remoteSource||!n&&"media-source"!==e.type||o(e.audioLevel?e.audioLevel:0))}))})),s.volume[i].value}return t.warn("Getting the "+i+" volume unsupported by browser"),void o(0)}function W(e,r,n){let o=S.get(e);if(!o||!o.webrtcStuff)return t.warn("Invalid handle"),!0;let a=o.webrtcStuff;if(!a.pc)return t.warn("Invalid PeerConnection"),!0;if(!a.myStream)return t.warn("Invalid local MediaStream"),!0;if(n){if(!a.myStream.getVideoTracks()||0===a.myStream.getVideoTracks().length)return t.warn("No video track"),!0;if(r){let e=a.pc.getTransceivers().find((e=>e.mid===r&&"video"===e.receiver.track.kind));return e?e.sender&&e.sender.track?!e.sender.track.enabled:(t.warn("No video sender with mid "+r),!0):(t.warn("No video transceiver with mid "+r),!0)}return!a.myStream.getVideoTracks()[0].enabled}if(!a.myStream.getAudioTracks()||0===a.myStream.getAudioTracks().length)return t.warn("No audio track"),!0;if(r){let e=a.pc.getTransceivers().find((e=>e.mid===r&&"audio"===e.receiver.track.kind));return e?e.sender&&e.sender.track?!e.sender.track.enabled:(t.warn("No audio sender with mid "+r),!0):(t.warn("No audio transceiver with mid "+r),!0)}return!a.myStream.getAudioTracks()[0].enabled}function B(e,r,n,o){let a=S.get(e);if(!a||!a.webrtcStuff)return t.warn("Invalid handle"),!1;let i=a.webrtcStuff;if(!i.pc)return t.warn("Invalid PeerConnection"),!1;if(!i.myStream)return t.warn("Invalid local MediaStream"),!1;if(n){if(!i.myStream.getVideoTracks()||0===i.myStream.getVideoTracks().length)return t.warn("No video track"),!1;if(r){let e=i.pc.getTransceivers().find((e=>e.mid===r&&"video"===e.receiver.track.kind));if(!e)return t.warn("No video transceiver with mid "+r),!1;if(!e.sender||!e.sender.track)return t.warn("No video sender with mid "+r),!1;e.sender.track.enabled=!o}else for(const e of i.myStream.getVideoTracks())e.enabled=!o}else{if(!i.myStream.getAudioTracks()||0===i.myStream.getAudioTracks().length)return t.warn("No audio track"),!1;if(r){let e=i.pc.getTransceivers().find((e=>e.mid===r&&"audio"===e.receiver.track.kind));if(!e)return t.warn("No audio transceiver with mid "+r),!1;if(!e.sender||!e.sender.track)return t.warn("No audio sender with mid "+r),!1;e.sender.track.enabled=!o}else for(const e of i.myStream.getAudioTracks())e.enabled=!o}return!0}function z(e,r){let n=S.get(e);if(!n||!n.webrtcStuff)return t.warn("Invalid handle"),"Invalid handle";let o=n.webrtcStuff;if(!o.pc)return"Invalid PeerConnection";if(o.pc.getStats){let e=o.pc,n=r||"default";if(r){let n=o.pc.getTransceivers().find((e=>e.mid===r&&"video"===e.receiver.track.kind));if(!n)return t.warn("No video transceiver with mid "+r),"No video transceiver with mid "+r;if(!n.receiver)return t.warn("No video receiver with mid "+r),"No video receiver with mid "+r;e=n.receiver}return o.bitrate[n]||(o.bitrate[n]={timer:null,bsnow:null,bsbefore:null,tsnow:null,tsbefore:null,value:"0 kbits/sec"}),o.bitrate[n].timer?o.bitrate[n].value:(t.log("Starting bitrate timer"+(r?" for mid "+r:"")+" (via getStats)"),o.bitrate[n].timer=setInterval((function(){e.getStats().then((function(e){e.forEach((function(e){if(!e)return;let r=!1;if(("video"===e.mediaType||"video"===e.kind||e.id.toLowerCase().indexOf("video")>-1)&&"inbound-rtp"===e.type&&e.id.indexOf("rtcp")<0?r=!0:"ssrc"!=e.type||!e.bytesReceived||"VP8"!==e.googCodecName&&""!==e.googCodecName||(r=!0),r)if(o.bitrate[n].bsnow=e.bytesReceived,o.bitrate[n].tsnow=e.timestamp,null===o.bitrate[n].bsbefore||null===o.bitrate[n].tsbefore)o.bitrate[n].bsbefore=o.bitrate[n].bsnow,o.bitrate[n].tsbefore=o.bitrate[n].tsnow;else{let e=o.bitrate[n].tsnow-o.bitrate[n].tsbefore;"safari"===t.webRTCAdapter.browserDetails.browser&&(e/=1e3);let r=Math.round(8*(o.bitrate[n].bsnow-o.bitrate[n].bsbefore)/e);"safari"===t.webRTCAdapter.browserDetails.browser&&(r=parseInt(r/1e3)),o.bitrate[n].value=r+" kbits/sec",o.bitrate[n].bsbefore=o.bitrate[n].bsnow,o.bitrate[n].tsbefore=o.bitrate[n].tsnow}}))}))}),1e3),"0 kbits/sec")}return t.warn("Getting the video bitrate unsupported by browser"),"Feature unsupported by browser"}function q(e,r,n){let o=S.get(e);if(!o||!o.webrtcStuff)return void t.warn("Invalid handle");let a=o.webrtcStuff;if(!a.pc)return void t.warn("Invalid PeerConnection");let i=a.pc.getTransceivers().find((e=>e.mid===r));if(!i)return void t.warn("No transceiver with mid",r);if(!i.sender)return void t.warn("No sender for transceiver with mid",r);let s=i.sender.getParameters();s&&s.encodings&&0!==s.encodings.length?s.encodings.length>1?t.warn("Ignoring bitrate for simulcast track, use sendEncodings for that"):isNaN(n)||n<0?t.warn("Invalid bitrate (must be a positive integer)"):(s.encodings[0].maxBitrate=n,i.sender.setParameters(s)):t.warn("No parameters encodings")}function H(e){t.error("WebRTC error:",e)}function Q(e,o){t.log("Cleaning WebRTC stuff");let a=S.get(e);if(!a)return;let i=a.webrtcStuff;if(i){if(!0===o){let o={janus:"hangup",transaction:t.randomString(12)};a.token&&(o.token=a.token),m&&(o.apisecret=m),t.debug("Sending hangup request (handle="+e+"):"),t.debug(o),r?(o.session_id=y,o.handle_id=e,n.send(JSON.stringify(o))):t.httpAPICall(c+"/"+y+"/"+e,{verb:"POST",withCredentials:f,body:o})}i.volume&&(i.volume.local&&i.volume.local.timer&&clearInterval(i.volume.local.timer),i.volume.remote&&i.volume.remote.timer&&clearInterval(i.volume.remote.timer));for(let e in i.bitrate)i.bitrate[e].timer&&clearInterval(i.bitrate[e].timer);i.bitrate={},!i.streamExternal&&i.myStream&&(t.log("Stopping local stream tracks"),t.stopAllTracks(i.myStream)),i.streamExternal=!1,i.myStream=null;try{i.pc.close()}catch(e){}i.pc=null,i.candidates=null,i.mySdp=null,i.remoteSdp=null,i.iceDone=!1,i.dataChannel={},i.dtmfSender=null,i.insertableStreams=!1,i.externalEncryption=!1}a.oncleanup()}D(e),this.getServer=function(){return c},this.isConnected=function(){return w},this.reconnect=function(e){(e=e||{}).success="function"==typeof e.success?e.success:t.noop,e.error="function"==typeof e.error?e.error:t.noop,e.reconnect=!0,D(e)},this.getSessionId=function(){return y},this.getInfo=function(e){!function(e){if((e=e||{}).success="function"==typeof e.success?e.success:t.noop,e.error="function"==typeof e.error?e.error:t.noop,t.log("Getting info on Janus instance"),!w)return t.warn("Is the server down? (connected=false)"),void e.error("Is the server down? (connected=false)");let o=t.randomString(12),a={janus:"info",transaction:o};if(g&&(a.token=g),m&&(a.apisecret=m),r)return T.set(o,(function(r){t.log("Server info:"),t.debug(r),"server_info"!==r.janus&&t.error("Ooops: "+r.error.code+" "+r.error.reason),e.success(r)})),void n.send(JSON.stringify(a));t.httpAPICall(c,{verb:"POST",withCredentials:f,body:a,success:function(r){t.log("Server info:"),t.debug(r),"server_info"!==r.janus&&t.error("Ooops: "+r.error.code+" "+r.error.reason),e.success(r)},error:function(r,n){t.error(r+":",n),""===n?e.error(r+": Is the server down?"):e.error(r+": "+n)}})}(e)},this.destroy=function(i){!function(i){(i=i||{}).success="function"==typeof i.success?i.success:t.noop,i.error="function"==typeof i.error?i.error:t.noop;let s=!0===i.unload,d=!0;void 0!==i.notifyDestroyed&&null!==i.notifyDestroyed&&(d=!0===i.notifyDestroyed);let l=!0===i.cleanupHandles;if(t.log("Destroying session "+y+" (unload="+s+")"),!y)return t.warn("No session to destroy"),i.success(),void(d&&e.destroyed());if(l)for(const e of S.keys())M(e,{noRequest:!0});if(!w)return t.warn("Is the server down? (connected=false)"),y=null,void i.success();let u={janus:"destroy",transaction:t.randomString(12)};if(g&&(u.token=g),m&&(u.apisecret=m),s)return r?(n.onclose=null,n.close(),n=null):navigator.sendBeacon(c+"/"+y,JSON.stringify(u)),t.log("Destroyed session:"),y=null,w=!1,i.success(),void(d&&e.destroyed());if(r){u.session_id=y;let t=function(){for(let e in o)n.removeEventListener(e,o[e]);n.removeEventListener("message",r),n.removeEventListener("error",s),a&&clearTimeout(a),n.close()},r=function(r){let n=JSON.parse(r.data);n.session_id==u.session_id&&n.transaction==u.transaction&&(t(),i.success(),d&&e.destroyed())},s=function(){t(),i.error("Failed to destroy the server: Is the server down?"),d&&e.destroyed()};return n.addEventListener("message",r),n.addEventListener("error",s),void(1===n.readyState?n.send(JSON.stringify(u)):s())}t.httpAPICall(c+"/"+y,{verb:"POST",withCredentials:f,body:u,success:function(r){t.log("Destroyed session:"),t.debug(r),y=null,w=!1,"success"!==r.janus&&t.error("Ooops: "+r.error.code+" "+r.error.reason),i.success(),d&&e.destroyed()},error:function(r,n){t.error(r+":",n),y=null,w=!1,i.success(),d&&e.destroyed()}})}(i)},this.attach=function(e){!function(e){if((e=e||{}).success="function"==typeof e.success?e.success:t.noop,e.error="function"==typeof e.error?e.error:t.noop,e.dataChannelOptions=e.dataChannelOptions||{ordered:!0},e.consentDialog="function"==typeof e.consentDialog?e.consentDialog:t.noop,e.connectionState="function"==typeof e.connectionState?e.connectionState:t.noop,e.iceState="function"==typeof e.iceState?e.iceState:t.noop,e.mediaState="function"==typeof e.mediaState?e.mediaState:t.noop,e.webrtcState="function"==typeof e.webrtcState?e.webrtcState:t.noop,e.slowLink="function"==typeof e.slowLink?e.slowLink:t.noop,e.onmessage="function"==typeof e.onmessage?e.onmessage:t.noop,e.onlocaltrack="function"==typeof e.onlocaltrack?e.onlocaltrack:t.noop,e.onremotetrack="function"==typeof e.onremotetrack?e.onremotetrack:t.noop,e.ondata="function"==typeof e.ondata?e.ondata:t.noop,e.ondataopen="function"==typeof e.ondataopen?e.ondataopen:t.noop,e.oncleanup="function"==typeof e.oncleanup?e.oncleanup:t.noop,e.ondetached="function"==typeof e.ondetached?e.ondetached:t.noop,!w)return t.warn("Is the server down? (connected=false)"),void e.error("Is the server down? (connected=false)");let o=e.plugin;if(!o)return t.error("Invalid plugin"),void e.error("Invalid plugin");let a=e.opaqueId,i=e.loopIndex,s=e.token?e.token:g,d=t.randomString(12),l={janus:"attach",plugin:o,opaque_id:a,loop_index:i,transaction:d};if(s&&(l.token=s),m&&(l.apisecret=m),r)return T.set(d,(function(r){if(t.debug(r),"success"!==r.janus)return t.error("Ooops: "+r.error.code+" "+r.error.reason),void e.error("Ooops: "+r.error.code+" "+r.error.reason);let n=r.data.id;t.log("Created handle: "+n);let a={session:k,plugin:o,id:n,token:s,detached:!1,webrtcStuff:{started:!1,myStream:null,streamExternal:!1,mySdp:null,mediaConstraints:null,pc:null,dataChannelOptions:e.dataChannelOptions,dataChannel:{},dtmfSender:null,trickle:!0,iceDone:!1,bitrate:{}},getId:function(){return n},getPlugin:function(){return o},getVolume:function(e,t){return U(n,e,!0,t)},getRemoteVolume:function(e,t){return U(n,e,!0,t)},getLocalVolume:function(e,t){return U(n,e,!1,t)},isAudioMuted:function(e){return W(n,e,!1)},muteAudio:function(e){return B(n,e,!1,!0)},unmuteAudio:function(e){return B(n,e,!1,!1)},isVideoMuted:function(e){return W(n,e,!0)},muteVideo:function(e){return B(n,e,!0,!0)},unmuteVideo:function(e){return B(n,e,!0,!1)},getBitrate:function(e){return z(n,e)},setMaxBitrate:function(e,t){return q(n,e,t)},send:function(e){P(n,e)},data:function(e){O(n,e)},dtmf:function(e){x(n,e)},consentDialog:e.consentDialog,connectionState:e.connectionState,iceState:e.iceState,mediaState:e.mediaState,webrtcState:e.webrtcState,slowLink:e.slowLink,onmessage:e.onmessage,createOffer:function(e){V(n,!0,e)},createAnswer:function(e){V(n,!1,e)},handleRemoteJsep:function(e){L(n,e)},replaceTracks:function(e){G(n,e)},getLocalTracks:function(){return J(n)},getRemoteTracks:function(){return F(n)},onlocaltrack:e.onlocaltrack,onremotetrack:e.onremotetrack,ondata:e.ondata,ondataopen:e.ondataopen,oncleanup:e.oncleanup,ondetached:e.ondetached,hangup:function(e){Q(n,!0===e)},detach:function(e){M(n,e)}};S.set(n,a),e.success(a)})),l.session_id=y,void n.send(JSON.stringify(l));t.httpAPICall(c+"/"+y,{verb:"POST",withCredentials:f,body:l,success:function(r){if(t.debug(r),"success"!==r.janus)return t.error("Ooops: "+r.error.code+" "+r.error.reason),void e.error("Ooops: "+r.error.code+" "+r.error.reason);let n=r.data.id;t.log("Created handle: "+n);let a={session:k,plugin:o,id:n,token:s,detached:!1,webrtcStuff:{started:!1,myStream:null,streamExternal:!1,mySdp:null,mediaConstraints:null,pc:null,dataChannelOptions:e.dataChannelOptions,dataChannel:{},dtmfSender:null,trickle:!0,iceDone:!1,bitrate:{}},getId:function(){return n},getPlugin:function(){return o},getVolume:function(e,t){return U(n,e,!0,t)},getRemoteVolume:function(e,t){return U(n,e,!0,t)},getLocalVolume:function(e,t){return U(n,e,!1,t)},isAudioMuted:function(e){return W(n,e,!1)},muteAudio:function(e){return B(n,e,!1,!0)},unmuteAudio:function(e){return B(n,e,!1,!1)},isVideoMuted:function(e){return W(n,e,!0)},muteVideo:function(e){return B(n,e,!0,!0)},unmuteVideo:function(e){return B(n,e,!0,!1)},getBitrate:function(e){return z(n,e)},setMaxBitrate:function(e,t){return q(n,e,t)},send:function(e){P(n,e)},data:function(e){O(n,e)},dtmf:function(e){x(n,e)},consentDialog:e.consentDialog,connectionState:e.connectionState,iceState:e.iceState,mediaState:e.mediaState,webrtcState:e.webrtcState,slowLink:e.slowLink,onmessage:e.onmessage,createOffer:function(e){V(n,!0,e)},createAnswer:function(e){V(n,!1,e)},handleRemoteJsep:function(e){L(n,e)},replaceTracks:function(e){G(n,e)},getLocalTracks:function(){return J(n)},getRemoteTracks:function(){return F(n)},onlocaltrack:e.onlocaltrack,onremotetrack:e.onremotetrack,ondata:e.ondata,ondataopen:e.ondataopen,oncleanup:e.oncleanup,ondetached:e.ondetached,hangup:function(e){Q(n,!0===e)},detach:function(e){M(n,e)}};S.set(n,a),e.success(a)},error:function(r,n){t.error(r+":",n),""===n?e.error(r+": Is the server down?"):e.error(r+": "+n)}})}(e)}}return t.useDefaultDependencies=function(r){let n=r&&r.fetch||fetch,o=r&&r.Promise||Promise,a=r&&r.WebSocket||WebSocket;return{newWebSocket:function(e,t){return new a(e,t)},extension:r&&r.extension||e,isArray:function(e){return Array.isArray(e)},webRTCAdapter:r&&r.adapter||adapter,httpAPICall:function(e,r){let a={method:r.verb,headers:{Accept:"application/json, text/plain, */*"},cache:"no-cache"};"POST"===r.verb&&(a.headers["Content-Type"]="application/json"),void 0!==r.withCredentials&&(a.credentials=!0===r.withCredentials?"include":r.withCredentials?r.withCredentials:"omit"),r.body&&(a.body=JSON.stringify(r.body));let i=n(e,a).catch((function(e){return o.reject({message:"Probably a network error, is the server down?",error:e})}));if(r.timeout){let e=new o((function(e,t){let n=setTimeout((function(){return clearTimeout(n),t({message:"Request timed out",timeout:r.timeout})}),r.timeout)}));i=o.race([i,e])}return i.then((function(e){return e.ok?typeof r.success==typeof t.noop?e.json().then((function(e){try{r.success(e)}catch(e){t.error("Unhandled httpAPICall success callback error",e)}}),(function(t){return o.reject({message:"Failed to parse response body",error:t,response:e})})):void 0:o.reject({message:"API call failed",response:e})})).catch((function(e){typeof r.error==typeof t.noop&&r.error(e.message||"<< internal error >>",e)})),i}}},t.useOldDependencies=function(r){let n=r&&r.jQuery||jQuery,o=r&&r.WebSocket||WebSocket;return{newWebSocket:function(e,t){return new o(e,t)},isArray:function(e){return