opensips-js 0.1.39 → 0.1.40

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.
@@ -155,5 +155,5 @@ a=accept-types:text/plain text/html
155
155
  a=path:${t.getHeader("Use-Path")} msrp://${this._ua._configuration.authorization_user}.${this._ua._configuration.realm}:2856/${this.auth_id};ws
156
156
  `),this._newMSRPSession("local",this._request),this._from_tag||(this._from_tag=this._request.from._parameters.tag),this._id=this._request.call_id+this._from_tag,new Wr(this._ua,this._request,{onRequestTimeout:()=>{this.onRequestTimeout(),console.log("to")},onTransportError:s=>{this.onTransportError(),console.log(s)},onAuthenticated:s=>{this._request=s},onReceiveResponse:s=>{this._receiveInviteResponse(s),s.status_code===200&&(s.parseSDP(!0),this._status=Ae.STATUS_CONFIRMED,this.target_addr=s.sdp.media[0].invalid[1].value.replaceAll("path:","").split(" ").reverse(),this.status="active",this.emit("active"),this.emit("confirmed"))}}).send(),this._status=Ae.STATUS_INVITE_SENT}terminate(t={}){const n=t.cause||H.causes.BYE,o=ke.cloneArray(t.extraHeaders),a=t.body;let s,r=t.status_code,_=t.reason_phrase;if(this._status===Ae.STATUS_TERMINATED)throw new Ns.InvalidStateError(this._status);switch(this.status="terminated",this._status){case Ae.STATUS_NULL:case Ae.STATUS_INVITE_SENT:case Ae.STATUS_1XX_RECEIVED:if(r&&(r<200||r>=700))throw new TypeError(`Invalid status_code: ${r}`);r&&(_=_||H.REASON_PHRASE[r]||"",s=`SIP ;cause=${r} ;text="${_}"`),this._status===Ae.STATUS_NULL||this._status===Ae.STATUS_INVITE_SENT?(this._is_canceled=!0,this._cancel_reason=s):this._status===Ae.STATUS_1XX_RECEIVED&&this._request.cancel(s),this._status=Ae.STATUS_CANCELED,this._failed("local",null,H.causes.CANCELED);break;case Ae.STATUS_WAITING_FOR_ANSWER:case Ae.STATUS_ANSWERED:if(r=r||480,r<300||r>=700)throw new TypeError(`Invalid status_code: ${r}`);this._request.reply(r,_,o,a),this._failed("local",null,H.causes.REJECTED);break;case Ae.STATUS_WAITING_FOR_ACK:case Ae.STATUS_CONFIRMED:if(_=t.reason_phrase||H.REASON_PHRASE[r]||"",r&&(r<200||r>=700))throw new TypeError(`Invalid status_code: ${r}`);if(r&&o.push(`Reason: SIP ;cause=${r}; text="${_}"`),this._status===Ae.STATUS_WAITING_FOR_ACK&&this._direction==="incoming"&&this._request.server_transaction.state!==Ht.C.STATUS_TERMINATED){const d=this._dialog;this.receiveRequest=({method:h})=>{h===H.ACK&&(this.sendRequest(H.BYE,{extraHeaders:o,body:a}),d.terminate())},this._request.server_transaction.on("stateChanged",()=>{this._request.server_transaction.state===Ht.C.STATUS_TERMINATED&&(this.sendRequest(H.BYE,{extraHeaders:o,body:a}),d.terminate())}),this._ended("local",null,n),this._dialog=d,this._ua.newDialog(d)}else this.sendRequest(H.BYE,{extraHeaders:o,body:a}),this._ended("local",null,n)}}sendRequest(t,n){return this._dialog.sendRequest(t,n)}authenticate(t){this.status="auth";let n=new Vn("");n.method="AUTH",n.addHeader("To-Path",`msrp://${this._ua._configuration.realm}:2856;ws`),n.addHeader("From-Path",`msrp://${this.credentials.username}.${this.credentials.realm}:2856/${this.auth_id};ws`),t&&n.addHeader("Authorization",t.toString());let o=n.toString(),a=[];for(var s=0;s<o.length;s++)a.push(o.charCodeAt(s).toString(16));this._connection.send(n.toString())}onmessage(t){const n=new Vn(t.data);if(this.status==="auth"&&n.code===401){const o=this.parseAuth(n.getHeader("WWW-Authenticate")),a=new Ng(this.credentials);a.authenticate({method:"AUTH",ruri:`msrp://${this._ua._configuration.realm}:2856;ws`,body:null},o,ke.createRandomToken(12)),this.authenticate(a)}this.status==="auth"&&n.code===200&&this._direction==="outgoing"?(this.my_addr.push(n.getHeader("To-Path")),this.my_addr.push(n.getHeader("Use-Path")),this.status="active",this.inviteParty(n)):this.status==="auth"&&n.code===200&&this._direction==="incoming"?(this.my_addr.push(n.getHeader("To-Path")),this.my_addr.push(n.getHeader("Use-Path")),this.status="active",this.acceptParty(n),this.emit("confirmed")):n.method==="SEND"&&(this._sendOk(n),this._sendReport(n),n.direction="incoming",this.emit("newMessage",n),this._msgHistory.push(n),this.emit("msgHistoryUpdate",this._msgHistory)),n.code===480&&this._close()}onclose(){console.log("close")}onopen(){const t=new RTCPeerConnection({iceServers:[]});t.createDataChannel(""),t.createOffer().then(t.setLocalDescription.bind(t)),t.onicecandidate=n=>{if(!n||!n.candidate||!n.candidate.candidate)return;const o=/([0-9]{1,3}(\.[0-9]{1,3}){3})/,a=n.candidate.candidate.match(o);this.my_ip=a&&a[1],t.onicecandidate=()=>{},this.authenticate(null)}}onerror(t){console.log(t)}_receiveInviteResponse(t){if(console.log("resp0000000000000",t),this._dialog&&t.status_code>=200&&t.status_code<=299)if(console.log("200000000000000"),this._dialog.id.call_id===t.call_id&&this._dialog.id.local_tag===t.from_tag&&this._dialog.id.remote_tag===t.to_tag){this.sendRequest(H.ACK);return}else{const n=new uo(this,t,"UAC");if(n.error!==void 0){console.log(n.error);return}this.sendRequest(H.ACK),this.sendRequest(H.BYE);return}if(this._is_canceled){t.status_code>=100&&t.status_code<200?this._request.cancel(this._cancel_reason):t.status_code>=200&&t.status_code<299&&this._acceptAndTerminate(t);return}if(!(this._status!==Ae.STATUS_INVITE_SENT&&this._status!==Ae.STATUS_1XX_RECEIVED))switch(console.log("start Switch"),!0){case/^100$/.test(t.status_code):this._status=Ae.STATUS_1XX_RECEIVED;break;case/^1[0-9]{2}$/.test(t.status_code):{if(!t.to_tag){console.log("1xx response received without to tag");break}if(t.hasHeader("contact")&&!this._createDialog(t,"UAC",!0))break;if(this._status=Ae.STATUS_1XX_RECEIVED,!t.body){this._progress("remote",t);break}const n={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",n);const o=new RTCSessionDescription({type:"answer",sdp:n.sdp});this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>this._connection.setRemoteDescription(o)).then(()=>this._progress("remote",t)).catch(a=>{console.log('emit "peerconnection:setremotedescriptionfailed" [error:%o]',a),this.emit("peerconnection:setremotedescriptionfailed",a)});break}case/^2[0-9]{2}$/.test(t.status_code):{if(console.log("maybe here???"),this._status=Ae.STATUS_CONFIRMED,!t.body){this._acceptAndTerminate(t,400,H.causes.MISSING_SDP),console.log("failed 3"),this._failed("remote",t,H.causes.BAD_MEDIA_DESCRIPTION);break}if(!this._createDialog(t,"UAC"))break;const n={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",n),new RTCSessionDescription({type:"answer",sdp:n.sdp}),this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>{if(this._connection.signalingState==="stable")return this._connection.createOffer(this._rtcOfferConstraints).then(o=>this._connection.setLocalDescription(o)).catch(o=>{this._acceptAndTerminate(t,500,o.toString()),console.log("failed 4"),this._failed("local",t,H.causes.WEBRTC_ERROR)})}).then(()=>{this._handleSessionTimersInIncomingResponse(t),this._accepted("remote",t),this.sendRequest(H.ACK),this._confirmed("local",null)});break}default:{const n=ke.sipErrorCause(t.status_code);console.log("failed 5"),this._failed("remote",t,n)}}}sendMSRP(t){const n=new Vn("");let o="";this.my_addr[1]&&(o=this.my_addr[1]),this.target_addr[1]&&(o+=" "+this.target_addr[1]),this.target_addr[0]&&(o+=" "+this.target_addr[0]),n.method="SEND",n.addHeader("To-Path",o),n.addHeader("From-Path",`${this.my_addr[0]}`),n.addHeader("Message-ID",ke.createRandomToken(10)),n.addHeader("Byte-Range","1-25/25"),n.addHeader("Content-Type","text/plain"),n.addHeader("Success-Report","yes"),n.addHeader("Failure-Report","yes"),n.body=t;let a=n.toString();console.log(a);let s=[];for(var r=0;r<a.length;r++)s.push(a.charCodeAt(r).toString(16));console.log(s),this._connection.send(n.toString()),n.direction="outgoing",this.emit("newMessage",n),this._msgHistory.push(n),this.emit("msgHistoryUpdate",this._msgHistory)}_sendOk(t){let n=t.ident,o=t.getHeader("Message-ID"),a=new Vn("");a.method="200 OK",a.addHeader("To-Path",`${this.my_addr[1]}`),a.addHeader("From-Path",`${this.my_addr[0]}`),a.addHeader("Message-ID",o),a.ident=n;let s=a.toString();console.log(s);let r=[];for(var _=0;_<s.length;_++)r.push(s.charCodeAt(_).toString(16));console.log(r),this._connection.send(a.toString())}_sendReport(t){let n=t.ident,o=t.getHeader("Message-ID"),a=new Vn("");a.method="REPORT",a.addHeader("To-Path",`${t.getHeader("From-Path")}`),a.addHeader("From-Path",`${this.my_addr[0]}`),a.addHeader("Message-ID",o),a.addHeader("Byte-Range","1-25/25"),a.addHeader("Status","000 200 OK"),a.ident=n;let s=a.toString();console.log(s);let r=[];for(var _=0;_<s.length;_++)r.push(s.charCodeAt(_).toString(16));console.log(r),this._connection.send(a.toString())}parseAuth(t){const n={},o=t.replace("Digest","").split(",");for(const a of o){const s=a.trim().split("=");n[s[0]]=s[1].match('^"(.+)"$')[1]}return n}init_incoming(t,n){let o;const a=t.hasHeader("Content-Type")?t.getHeader("Content-Type").toLowerCase():void 0;if(t.body&&a!=="application/sdp"){t.reply(415);return}if(this._status=Ae.STATUS_INVITE_RECEIVED,this._from_tag=t.from_tag,this._id=t.call_id+this._from_tag,this._request=t,this._contact=this._ua.contact.toString(),t.hasHeader("expires")&&(o=t.getHeader("expires")*1e3),t.to_tag=ke.newTag(),!this._createDialog(t,"UAS",!0)){t.reply(500,"Missing Contact header field");return}t.body?this._late_sdp=!1:this._late_sdp=!0,this._status=Ae.STATUS_WAITING_FOR_ANSWER,this._timers.userNoAnswerTimer=setTimeout(()=>{t.reply(408),console.log("failed 6"),this._failed("local",null,H.causes.NO_ANSWER)},this._ua.configuration.no_answer_timeout),o&&(this._timers.expiresTimer=setTimeout(()=>{this._status===Ae.STATUS_WAITING_FOR_ANSWER&&(t.reply(487),console.log("failed 7"),this._failed("system",null,H.causes.EXPIRES))},o)),this._direction="incoming",this._local_identity=t.to,this._remote_identity=t.from,n&&n(this),t.parseSDP(!0),this.target_addr=t.sdp.media[0].invalid[1].value.replaceAll("path:","").split(" ").reverse(),this._newMSRPSession("remote",t),this._status!==Ae.STATUS_TERMINATED&&(t.reply(180,null,[`Contact: ${this._ua._contact}`]),this._progress("local",null))}_failed(t,n,o){this.emit("_failed",{originator:t,message:n||null,cause:o}),this._close(),this.emit("failed",{originator:t,message:n||null,cause:o})}_close(){if(console.log("CLOSE SESSION"),this._status!==Ae.STATUS_TERMINATED){if(this._status=Ae.STATUS_TERMINATED,this._connection)try{this._connection.close()}catch(t){console.log("close() | error closing the RTCPeerConnection: %o",t)}for(const t in this._timers)Object.prototype.hasOwnProperty.call(this._timers,t)&&clearTimeout(this._timers[t]);clearTimeout(this._sessionTimers.timer),this._dialog&&(this._dialog.terminate(),delete this._dialog);for(const t in this._earlyDialogs)Object.prototype.hasOwnProperty.call(this._earlyDialogs,t)&&(this._earlyDialogs[t].terminate(),delete this._earlyDialogs[t]);for(const t in this._referSubscribers)Object.prototype.hasOwnProperty.call(this._referSubscribers,t)&&delete this._referSubscribers[t];this._ua.destroyMSRPSession(this)}}_createDialog(t,n,o){const a=n==="UAS"?t.to_tag:t.from_tag,s=n==="UAS"?t.from_tag:t.to_tag,r=t.call_id+a+s;let _=this._earlyDialogs[r];if(o)return _?!0:(_=new uo(this,t,n,uo.C.STATUS_EARLY),_.error?(console.log("failed 8"),this._failed("remote",t,H.causes.INTERNAL_ERROR),!1):(this._earlyDialogs[r]=_,!0));{if(this._from_tag=t.from_tag,this._to_tag=t.to_tag,_)return _.update(t,n),this._dialog=_,delete this._earlyDialogs[r],!0;const d=new uo(this,t,n);return d.error?(console.log("failed 9"),this._failed("remote",t,H.causes.INTERNAL_ERROR),!1):(this._dialog=d,!0)}}_newMSRPSession(t,n){this._ua.newMSRPSession(this,{originator:t,session:this,request:n})}_progress(t,n){this.emit("progress",{originator:t,response:n||null})}isEnded(){switch(this._status){case Ae.STATUS_CANCELED:case Ae.STATUS_TERMINATED:return!0;default:return!1}}_accepted(t,n){console.log("session accepted"),this._start_time=new Date,console.log('emit "accepted"'),this.emit("accepted",{originator:t,response:n||null})}_confirmed(t,n){console.log("session confirmed"),this._is_confirmed=!0,console.log('emit "confirmed"'),this.emit("confirmed",{originator:t,ack:n||null})}_ended(t,n,o){console.log("session ended"),this._end_time=new Date,this._close(),console.log('emit "ended"'),this.emit("ended",{originator:t,message:n||null,cause:o})}_runKeepAliveTimer(){if(!this._sessionTimers||!this._sessionTimers.enabled||this._sessionTimers.running)return;if(this._sessionTimers.currentExpires||(this._sessionTimers.currentExpires=this._sessionTimers.defaultExpires||30),!this._sessionTimers.refresher){console.log("Not the refresher; waiting for remote keep-alive");return}const t=this._sessionTimers.currentExpires;this._sessionTimers.running=!0,clearTimeout(this._sessionTimers.timer),this._sessionTimers.timer=setTimeout(()=>{if(this._connection.readyState===WebSocket.OPEN)try{this._sendKeepAlive(),console.log("Session timer: sending MSRP keep-alive")}catch(n){console.error("Failed to send keep-alive:",n)}this._sessionTimers.running=!1,this._runKeepAliveTimer()},t*1e3*.5)}_handleSessionTimersInIncomingResponse(t){if(!this._sessionTimers.enabled)return;let n;t.session_expires&&t.session_expires>=H.MIN_SESSION_EXPIRES?(this._sessionTimers.currentExpires=t.session_expires,n=t.session_expires_refresher||"uac"):(this._sessionTimers.currentExpires=this._sessionTimers.defaultExpires,n="uac"),this._sessionTimers.refresher=n==="uac",this._runKeepAliveTimer()}receiveRequest(t){if(console.log("receiveRequest()"),t.method===H.CANCEL)(this._status===Ae.STATUS_WAITING_FOR_ANSWER||this._status===Ae.STATUS_ANSWERED)&&(this._status=Ae.STATUS_CANCELED,this._request.reply(487),console.log("failed 10"),this._failed("remote",t,H.causes.CANCELED));else switch(t.method){case H.ACK:if(this._status!==Ae.STATUS_WAITING_FOR_ACK)return;if(this._status=Ae.STATUS_CONFIRMED,clearTimeout(this._timers.ackTimer),clearTimeout(this._timers.invite2xxTimer),this._late_sdp){if(!t.body){this.terminate({cause:H.causes.MISSING_SDP,status_code:400});break}const n={originator:"remote",type:"answer",sdp:t.body};console.log('emit "sdp"'),this.emit("sdp",n);const o=new RTCSessionDescription({type:"answer",sdp:n.sdp});this._connectionPromiseQueue=this._connectionPromiseQueue.then(()=>this._connection.setRemoteDescription(o)).then(()=>{this._is_confirmed||this._confirmed("remote",t)}).catch(a=>{this.terminate({cause:H.causes.BAD_MEDIA_DESCRIPTION,status_code:488}),console.log('emit "peerconnection:setremotedescriptionfailed" [error:%o]',a),this.emit("peerconnection:setremotedescriptionfailed",a)})}else this._is_confirmed||this._confirmed("remote",t);break;case H.BYE:this._status===Ae.STATUS_CONFIRMED||this._status===Ae.STATUS_WAITING_FOR_ACK?(t.reply(200),this._ended("remote",t,H.causes.BYE)):this._status===Ae.STATUS_INVITE_RECEIVED||this._status===Ae.STATUS_WAITING_FOR_ANSWER?(t.reply(200),this._request.reply(487,"BYE Received"),this._ended("remote",t,H.causes.BYE)):t.reply(403,"Wrong Status");break;case H.INVITE:this._status===Ae.STATUS_CONFIRMED?t.hasHeader("replaces")?this._receiveReplaces(t):this._receiveReinvite(t):t.reply(403,"Wrong Status");break;case H.INFO:this._status===Ae.STATUS_1XX_RECEIVED||this._status===Ae.STATUS_WAITING_FOR_ANSWER||this._status===Ae.STATUS_ANSWERED||this._status===Ae.STATUS_WAITING_FOR_ACK||this._status===Ae.STATUS_CONFIRMED?(t.hasHeader("Content-Type")?t.getHeader("Content-Type").toLowerCase():void 0)!==void 0?new ru(this).init_incoming(t):t.reply(415):t.reply(403,"Wrong Status");break;case H.UPDATE:this._status===Ae.STATUS_CONFIRMED?this._receiveUpdate(t):t.reply(403,"Wrong Status");break;case H.REFER:this._status===Ae.STATUS_CONFIRMED?this._receiveRefer(t):t.reply(403,"Wrong Status");break;case H.NOTIFY:this._status===Ae.STATUS_CONFIRMED?this._receiveNotify(t):t.reply(403,"Wrong Status");break;default:t.reply(501)}}onTransportError(){console.log("onTransportError()"),this._status!==Ae.STATUS_TERMINATED&&this.terminate({status_code:500,reason_phrase:H.causes.CONNECTION_ERROR,cause:H.causes.CONNECTION_ERROR})}onRequestTimeout(){console.log("onRequestTimeout()"),this._status!==Ae.STATUS_TERMINATED&&this.terminate({status_code:408,reason_phrase:H.causes.REQUEST_TIMEOUT,cause:H.causes.REQUEST_TIMEOUT})}onDialogError(){console.log("onDialogError()"),this._status!==Ae.STATUS_TERMINATED&&this.terminate({status_code:500,reason_phrase:H.causes.DIALOG_ERROR,cause:H.causes.DIALOG_ERROR})}}var ST=Yt();const Cu=Me(ST),yo=new no("Parser"),ET=(c,t)=>{let n,o,a=c.indexOf(`\r
157
157
  `);if(a===-1){yo.warn("parseMessage() | no CRLF found, not a SIP message");return}const s=c.substring(0,a);let r=Cu.parse(s,"Request_Response");if(r===-1){yo.warn(`parseMessage() | error parsing first line of SIP message: "${s}"`);return}else r.status_code?(n=new Ln.IncomingResponse,n.status_code=r.status_code,n.reason_phrase=r.reason_phrase):(n=new Ln.IncomingRequest(t),n.method=r.method,n.ruri=r.uri);n.data=c;let _=a+2;for(;;){if(a=yT(c,_),a===-2){o=_+2;break}else if(a===-1){yo.warn("parseMessage() | malformed message");return}if(r=CT(n,c,_,a),r!==!0){yo.warn("parseMessage() |",r.error);return}_=a+2}if(n.hasHeader("content-length")){const d=n.getHeader("content-length");n.body=c.substr(o,d)}else n.body=c.substring(o);return n};function yT(c,t){let n=t,o=0,a=0;if(c.substring(n,n+2).match(/(^\r\n)/))return-2;for(;o===0;){if(a=c.indexOf(`\r
158
- `,n),a===-1)return a;!c.substring(a+2,a+4).match(/(^\r\n)/)&&c.charAt(a+2).match(/(^\s+)/)?n=a+2:o=a}return o}function CT(c,t,n,o){let a;const s=t.indexOf(":",n),r=t.substring(n,s).trim(),_=t.substring(s+1,o).trim();switch(r.toLowerCase()){case"via":case"v":c.addHeader("via",_),c.getHeaders("via").length===1?(a=c.parseHeader("Via"),a&&(c.via=a,c.via_branch=a.branch)):a=0;break;case"from":case"f":c.setHeader("from",_),a=c.parseHeader("from"),a&&(c.from=a,c.from_tag=a.getParam("tag"));break;case"to":case"t":c.setHeader("to",_),a=c.parseHeader("to"),a&&(c.to=a,c.to_tag=a.getParam("tag"));break;case"record-route":if(a=Cu.parse(_,"Record_Route"),a===-1)a=void 0;else for(const d of a)c.addHeader("record-route",_.substring(d.possition,d.offset)),c.headers["Record-Route"][c.getHeaders("record-route").length-1].parsed=d.parsed;break;case"call-id":case"i":c.setHeader("call-id",_),a=c.parseHeader("call-id"),a&&(c.call_id=_);break;case"contact":case"m":if(a=Cu.parse(_,"Contact"),a===-1)a=void 0;else for(const d of a)c.addHeader("contact",_.substring(d.possition,d.offset)),c.headers.Contact[c.getHeaders("contact").length-1].parsed=d.parsed;break;case"content-length":case"l":c.setHeader("content-length",_),a=c.parseHeader("content-length");break;case"content-type":case"c":c.setHeader("content-type",_),a=c.parseHeader("content-type");break;case"cseq":c.setHeader("cseq",_),a=c.parseHeader("cseq"),a&&(c.cseq=a.value),c instanceof Ln.IncomingResponse&&(c.method=a.method);break;case"max-forwards":c.setHeader("max-forwards",_),a=c.parseHeader("max-forwards");break;case"www-authenticate":c.setHeader("www-authenticate",_),a=c.parseHeader("www-authenticate");break;case"proxy-authenticate":c.setHeader("proxy-authenticate",_),a=c.parseHeader("proxy-authenticate");break;case"session-expires":case"x":c.setHeader("session-expires",_),a=c.parseHeader("session-expires"),a&&(c.session_expires=a.expires,c.session_expires_refresher=a.refresher);break;case"refer-to":case"r":c.setHeader("refer-to",_),a=c.parseHeader("refer-to"),a&&(c.refer_to=a);break;case"replaces":c.setHeader("replaces",_),a=c.parseHeader("replaces"),a&&(c.replaces=a);break;case"event":case"o":c.setHeader("event",_),a=c.parseHeader("event"),a&&(c.event=a);break;default:c.addHeader(r,_),a=0}return a===void 0?{error:`error parsing header "${r}"`}:!0}const AT={parseMessage:ET},si=new no("Registrator"),Co=10;class RT{constructor(t,n){this._reg_id=1,this._ua=t,this._transport=n,this._registrar=t.configuration.registrar_server,this._expires=t.configuration.register_expires,this._call_id=vs.createRandomToken(22),this._cseq=0,this._to_uri=t.configuration.uri,this._registrationTimer=null,this._registering=!1,this._registered=!1,this._contact=this._ua.contact.toString();const o=this._contact.indexOf(">");if(o!==-1){const a=this._contact.slice(0,o)+this._contact.slice(o+1,this._contact.length);this._contact=a}this._extra_contact="",this._extraContactParams="",this._extra_contact+=";+sip.ice",this._extraHeaders=[],this._sipInstance=`"<urn:uuid:${this._ua.configuration.instance_id}>"`,this._extra_contact+=`;reg-id=${this._reg_id}`,this._extra_contact+=`;+sip.instance=${this._sipInstance}`}get registered(){return this._registered}setExtraHeaders(t){Array.isArray(t)||(t=[]),this._extraHeaders=t.slice()}setExtraContactParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)){const o=t[n];this._extraContactParams+=`;${n}`,o&&(this._extraContactParams+=`=${o}`)}}setExtraContactUriParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)){const o=t[n];this._extraContactParams+=`;${n}`,o&&(this._extraContactParams+=`=${o}`)}}register(){if(this._registering){si.debug("Register request in progress...");return}const t=this._extraHeaders.slice();t.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=${this._expires}`),t.push(`Expires: ${this._expires}`);const n=new Tt.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},t),o=new Wr(this._ua,n,{onRequestTimeout:()=>{this._registrationFailure(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._registrationFailure(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:a=>{if(a.cseq===this._cseq)switch(this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),!0){case/^1[0-9]{2}$/.test(a.status_code):break;case/^2[0-9]{2}$/.test(a.status_code):{if(this._registering=!1,!a.hasHeader("Contact")){si.debug("no Contact header in response to REGISTER, response ignored");break}const s=a.headers.Contact.reduce((h,m)=>h.concat(m.parsed),[]);let r=s.find(h=>this._sipInstance===h.getParam("+sip.instance")&&this._reg_id===parseInt(h.getParam("reg-id")));if(r||(r=s.find(h=>h.uri.user===this._ua.contact.uri.user)),!r){si.debug("no Contact header pointing to us, response ignored");break}this._ua.clearKeepAliveInterval(),this._ua.setLastRegisterTimestamp();let _=r.getParam("expires");!_&&a.hasHeader("expires")&&(_=a.getHeader("expires")),_||(_=this._expires),_=Number(_),_<Co&&(_=Co);const d=_>64?_*1e3/2+Math.floor((_/2-32)*1e3*Math.random()):Math.floor(_*1e3/2);this._registrationTimer=setTimeout(()=>{this._registrationTimer=null,this._ua.listeners("registrationExpiring").length===0?this.register():this._ua.emit("registrationExpiring")},d),r.hasParam("temp-gruu")&&(this._ua.contact.temp_gruu=r.getParam("temp-gruu").replace(/"/g,"")),r.hasParam("pub-gruu")&&(this._ua.contact.pub_gruu=r.getParam("pub-gruu").replace(/"/g,"")),this._registered||(this._registered=!0,this._ua.registered({response:a}));break}case/^423$/.test(a.status_code):{a.hasHeader("min-expires")?(this._expires=Number(a.getHeader("min-expires")),this._expires<Co&&(this._expires=Co),this.register()):(si.debug("423 response received for REGISTER without Min-Expires"),this._registrationFailure(a,H.causes.SIP_FAILURE_CODE));break}default:{const s=vs.sipErrorCause(a.status_code);this._registrationFailure(a,s)}}}});this._registering=!0,o.send()}unregister(t={}){if(!this._registered){si.debug("already unregistered");return}this._registered=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null);const n=this._extraHeaders.slice();t.all?n.push(`Contact: *${this._extraContactParams}`):n.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=0`),n.push("Expires: 0");const o=new Tt.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},n);new Wr(this._ua,o,{onRequestTimeout:()=>{this._unregistered(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._unregistered(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:s=>{switch(!0){case/^1[0-9]{2}$/.test(s.status_code):break;case/^2[0-9]{2}$/.test(s.status_code):this._unregistered(s);break;default:{const r=vs.sipErrorCause(s.status_code);this._unregistered(s,r)}}}}).send()}close(){this._registered&&this.unregister()}onTransportClosed(){this._registering=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),this._registered&&(this._registered=!1,this._ua.unregistered({}))}_registrationFailure(t,n){this._registering=!1,this._ua.registrationFailed({response:t||null,cause:n}),this._registered&&(this._registered=!1,this._ua.unregistered({response:t||null,cause:n}))}_unregistered(t,n){this._registering=!1,this._registered=!1,this._ua.unregistered({response:t||null,cause:n||null})}}const tt=console,Ps={STATUS_INIT:0,STATUS_READY:1,STATUS_USER_CLOSED:2,STATUS_NOT_READY:3,CONFIGURATION_ERROR:1,NETWORK_ERROR:2},IT=dT;class bT extends IT{constructor(t){super(t),this._msrp_sessions=[],this._transactions={nist:{},nict:{},ist:{},ict:{}},this._janus_sessions=[],this.newStreamPlugins=[],this.processStreamPlugins=[],this.optionsInterval=null,this.lastOptionsTimestamp=null,this.lastRegisterTimestamp=null,this._registrator=new RT(this)}setLastRegisterTimestamp(){this.lastRegisterTimestamp=Date.now()}call(t,n){return super.call(t,n)}joinVideoCall(t,n,o){tt.debug("call()");const a=new Eo(this);return a.configureMedia({audio:!0,video:!0}),a.connect(t,n,o),a}startScreenShare(){tt.debug("startScreenShare()");for(const t in this._janus_sessions)this._janus_sessions[t].connectScreenShare()}changeMediaConstraints(t){for(const n in this._janus_sessions)this._janus_sessions[n].changeMediaConstraints(t)}startBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].connectBlur()}stopBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].stopBlur()}_loadConfig(t){try{ti.load(this._configuration,t)}catch(s){throw s}this._configuration.display_name===0&&(this._configuration.display_name="0"),this._configuration.instance_id||(this._configuration.instance_id=vs.newUUID());let n;typeof window<"u"&&typeof window.document<"u"?n=window==null?void 0:window.navigator.userAgent:typeof self<"u"&&self.navigator&&(n=self.navigator.userAgent),n+=" "+De.USER_AGENT,this._configuration.user_agent=t.overrideUserAgent&&typeof t.overrideUserAgent=="function"?t.overrideUserAgent(n):n,t.onTransportCallback&&typeof t.onTransportCallback=="function"&&(this.onTransportCallback=t.onTransportCallback),this._configuration.jssip_id=vs.createRandomToken(5);const o=this._configuration.uri.clone();o.user=null,this._configuration.hostport_params=o.toString().replace(/^sip:/i,"");try{this._transport=new $m(this._configuration.sockets,{max_interval:this._configuration.connection_recovery_max_interval,min_interval:this._configuration.connection_recovery_min_interval}),this._transport.onconnecting=wT.bind(this),this._transport.onconnect=OT.bind(this),this._transport.ondisconnect=DT.bind(this),this._transport.ondata=NT.bind(this)}catch(s){throw tt.warn(s),new Ns.ConfigurationError("sockets",this._configuration.sockets)}if(delete this._configuration.sockets,this._configuration.authorization_user||(this._configuration.authorization_user=this._configuration.uri.user),!this._configuration.registrar_server){const s=this._configuration.uri.clone();s.user=null,s.clearParams(),s.clearHeaders(),this._configuration.registrar_server=s}this._configuration.no_answer_timeout*=1e3,this._configuration.contact_uri?this._configuration.via_host=this._configuration.contact_uri.host:this._configuration.contact_uri=new ln("sip",vs.createRandomToken(8),this._configuration.via_host,null,{transport:"ws"}),this._contact={pub_gruu:null,temp_gruu:null,uri:this._configuration.contact_uri,toString(s={}){const r=s.anonymous||null,_=s.outbound||null;let d="<";return r?d+=this.temp_gruu||"sip:anonymous@anonymous.invalid;transport=ws":d+=this.pub_gruu||this.uri.toString(),_&&(r?!this.temp_gruu:!this.pub_gruu)&&(d+=";ob"),d+=">",d}};const a=["authorization_user","password","realm","ha1","authorization_jwt","display_name","register"];for(const s in this._configuration)Object.prototype.hasOwnProperty.call(this._configuration,s)&&(a.indexOf(s)!==-1?Object.defineProperty(this._configuration,s,{writable:!0,configurable:!1}):Object.defineProperty(this._configuration,s,{writable:!1,configurable:!1}));tt.debug("configuration parameters after validation:");for(const s in this._configuration)if(Object.prototype.hasOwnProperty.call(ti.settings,s))switch(s){case"uri":case"registrar_server":tt.debug(`- ${s}: ${this._configuration[s]}`);break;case"password":case"ha1":case"authorization_jwt":tt.debug(`- ${s}: NOT SHOWN`);break;default:tt.debug(`- ${s}: ${JSON.stringify(this._configuration[s])}`)}}newMSRPSession(t,n){t.on("msgHistoryUpdate",o=>{console.log(o)}),this._msrp_sessions[t.id]=t,this.emit("newMSRPSession",n)}newJanusSession(t,n){this._janus_sessions[t.id]=t,this.newStreamPlugins.forEach(o=>{o.setSession(t)}),this.processStreamPlugins.forEach(o=>{o.setSession(t)}),this.emit("newJanusSession",n)}kill(){}destroyMSRPSession(t){delete this._msrp_sessions[t.id]}destroyJanusSession(t){delete this._janus_sessions[t.id]}clearKeepAliveInterval(){clearInterval(this.optionsInterval),this.optionsInterval=null}receiveRequest(t){var s,r,_,d;const n=t.method;if(t.ruri.user!==this._configuration.uri.user&&t.ruri.user!==this._contact.uri.user){tt.debug("Request-URI does not point to us"),t.method!==De.ACK&&t.reply_sl(404);return}if(t.ruri.scheme===De.SIPS){t.reply_sl(416);return}if(Ht.checkTransaction(this,t))return;if(n===De.INVITE?new Ht.InviteServerTransaction(this,this._transport,t):n!==De.ACK&&n!==De.CANCEL&&new Ht.NonInviteServerTransaction(this,this._transport,t),n===De.OPTIONS){if(this.lastOptionsTimestamp=Date.now(),this.optionsInterval||(this.emit("initKeepAliveInterval"),this.optionsInterval=setInterval(()=>{const m=Date.now(),T=this.lastOptionsTimestamp>m-35e3,S=this.lastRegisterTimestamp+this._configuration.register_expires*1e3>m;T&&S&&this.emit("keepAliveInterval")},35e3)),this.listeners("newOptions").length===0){t.reply(200);return}new Af.Options(this).init_incoming(t)}else if(n===De.MESSAGE){if(this.listeners("newMessage").length===0){t.reply(405);return}new Af.Message(this).init_incoming(t)}else if(n===De.INVITE&&!t.to_tag&&this.listeners("newRTCSession").length===0){t.reply(405);return}let o,a;if(t.to_tag)if(o=this._findDialog(t.call_id,t.from_tag,t.to_tag),o)o.receiveRequest(t);else if(n===De.NOTIFY)if(a=this._findSession(t),a)a.receiveRequest(t);else{if(t.body)try{const h=JSON.parse(t.body)||{};(r=(s=h.plugindata)==null?void 0:s.data)!=null&&r.publishers&&Object.values(this._janus_sessions)[0].receivePublishers(h),(d=(_=h.plugindata)==null?void 0:_.data)!=null&&d.unpublished&&Object.values(this._janus_sessions)[0].receiveUnpublished(h.plugindata.data.unpublished)}catch(h){console.error(h)}t.reply(200)}else n!==De.ACK&&t.reply(481);else switch(n){case De.INVITE:if(window.RTCPeerConnection)if(t.hasHeader("replaces")){const h=t.replaces;o=this._findDialog(h.call_id,h.from_tag,h.to_tag),o?(a=o.owner,a.isEnded()?t.reply(603):a.receiveRequest(t)):t.reply(481)}else t.body.search(/MSRP/ig)>-1?(a=new yu(this),a.init_incoming(t)):t.body.search(/JANUS/ig)>-1||(a=new ym(this),a.init_incoming(t));else tt.warn("INVITE received but WebRTC is not supported"),t.reply(488);break;case De.BYE:t.reply(481);break;case De.CANCEL:a=this._findSession(t),a?a.receiveRequest(t):tt.debug("received CANCEL request for a non existent session");break;case De.ACK:break;case De.NOTIFY:this.emit("sipEvent",{event:t.event,request:t}),t.reply(200);break;default:t.reply(405);break}}startMSRP(t,n){tt.debug("startMSRP()",n);const o=new yu(this);return o.connect(t),o}startJanus(t,n){tt.debug("startJanus()",n);const o=new yu(this);return o.connect(t),o}terminateMSRPSessions(t){tt.debug("terminateSessions()");for(const n in this._msrp_sessions)this._msrp_sessions[n].isEnded()||this._msrp_sessions[n].terminate(t)}terminateJanusSessions(t){tt.debug("terminateSessions()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||this._janus_sessions[n].terminate(t)}enableJanusAudio(t){tt.debug("enableJanusAudio()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||(t?this._janus_sessions[n].startAudio():this._janus_sessions[n].stopAudio())}enableJanusVideo(t){tt.debug("enableJanusVideo()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||(t?this._janus_sessions[n].startVideo():this._janus_sessions[n].stopVideo())}terminateAllSessions(){for(const t in this._sessions)if(Object.prototype.hasOwnProperty.call(this._sessions,t)){tt.debug(`closing session ${t}`);try{this._sessions[t].terminate()}catch(n){console.error(n)}}}stop(t=!0){if(tt.debug("stop()"),this._dynConfiguration={},this._status===Ps.STATUS_USER_CLOSED){tt.debug("UA already closed");return}this._registrator.close();const n=Object.keys(this._sessions).length;t&&this.terminateAllSessions();for(const a in this._msrp_sessions)if(Object.prototype.hasOwnProperty.call(this._msrp_sessions,a)){tt.debug(`closing session ${a}`);try{this._msrp_sessions[a].terminate()}catch(s){console.error(s)}}for(const a in this._janus_sessions)if(Object.prototype.hasOwnProperty.call(this._janus_sessions,a)){tt.debug(`closing session ${a}`);try{this._janus_sessions[a].terminate()}catch(s){console.error(s)}}for(const a in this._applicants)if(Object.prototype.hasOwnProperty.call(this._applicants,a))try{this._applicants[a].close()}catch(s){console.error(s)}this._status=Ps.STATUS_USER_CLOSED,Object.keys(this._transactions.nict).length+Object.keys(this._transactions.nist).length+Object.keys(this._transactions.ict).length+Object.keys(this._transactions.ist).length===0&&n===0?this._transport.disconnect():this._closeTimer=setTimeout(()=>{this._closeTimer=null,this._transport.disconnect()},2e3)}}function wT(c){this.emit("connecting",c)}function OT(c){this._status!==Ps.STATUS_USER_CLOSED&&(this._status=Ps.STATUS_READY,this._error=null,this.emit("connected",c),this._dynConfiguration.register&&this._registrator.register())}function DT(c){const t=["nict","ict","nist","ist"];for(const n of t)for(const o in this._transactions[n])Object.prototype.hasOwnProperty.call(this._transactions[n],o)&&this._transactions[n][o].onTransportError();this.emit("disconnected",c),this._registrator.onTransportClosed(),this._status!==Ps.STATUS_USER_CLOSED&&(this._status=Ps.STATUS_NOT_READY,this._error=Ps.NETWORK_ERROR)}function NT(c){const t=c.transport;let n=c.message;const o=n;if(n=AT.parseMessage(n,this),this.onTransportCallback&&typeof this.onTransportCallback=="function"&&this.onTransportCallback(n,o),!!n&&!(this._status===Ps.STATUS_USER_CLOSED&&n instanceof Ln.IncomingRequest)&&Zm(n,this,t)){if(n instanceof Ln.IncomingRequest)n.transport=t,this.receiveRequest(n);else if(n instanceof Ln.IncomingResponse){let a;switch(n.method){case De.INVITE:if(a=this._transactions.ict[n.via_branch],a){const s=n.status_code;if((s===100||s===180||s===183)&&this.audio&&typeof this.audio.handleSipResponseForRingback=="function"){let r=null;if(a._session&&a._session.id)r=a._session.id;else if(n.call_id&&this._sessions){const d=Object.values(this._sessions).find(h=>h._id&&h._id.includes(n.call_id)||h.id&&h.id.includes(n.call_id)||h.call_id===n.call_id);d&&(d.id||d._id)&&(r=d.id||d._id)}else n.call_id&&(r=n.call_id);r&&this.audio.handleSipResponseForRingback(r,s)}a.receiveResponse(n)}break;case De.ACK:break;default:a=this._transactions.nict[n.via_branch],a&&a.receiveResponse(n);break}}}}const xT=["roomId","_audioMuted","_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","_localHold","_videoMuted","status","start_time","_remote_identity","audioTag","isOnHold","localMuted","autoAnswer","putOnHoldTimestamp"],UT=["_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","status","start_time","_remote_identity","target_addr"];function vd(c){const t={};return xT.forEach(n=>{c[n]!==void 0&&(t[n]=c[n])}),t.localHold=c._localHold,t}function Sd(c){const t={};return UT.forEach(n=>{c[n]!==void 0&&(t[n]=c[n])}),t}async function Au(c,t,n){const o=c.createMediaStreamSource(t),a=c.createMediaStreamDestination(),s=c.createGain();return o.connect(s),s.connect(a),s.gain.value=n,a.stream}function kT(c,t,n,o){if(Ed())return;const a=document.createElement("audio");a.id=t._id,a.className="audioTag",a.srcObject=c,a.setSinkId(n),a.volume=o,a.play(),t.audioTag=a}function PT(c){if(c&&typeof c.log=="function"&&typeof c.warn=="function"&&typeof c.error=="function")return!0}function Ed(){return/Mobi|react-native|Android|iPhone/i.test(navigator.userAgent)}const MT=ot,LT=Yt(),Ot=new MT("WebSocketInterface");var $T=class{constructor(t){Ot.debug('new() [url:"%s"]',t),this._url=t,this._sip_uri=null,this._via_transport=null,this._ws=null;const n=LT.parse(t,"absoluteURI");if(n===-1)throw Ot.warn(`invalid WebSocket URI: ${t}`),new TypeError(`Invalid argument: ${t}`);if(n.scheme!=="wss"&&n.scheme!=="ws")throw Ot.warn(`invalid WebSocket URI scheme: ${n.scheme}`),new TypeError(`Invalid argument: ${t}`);this._sip_uri=`sip:${n.host}${n.port?`:${n.port}`:""};transport=ws`,this._via_transport=n.scheme.toUpperCase()}get via_transport(){return this._via_transport}set via_transport(t){this._via_transport=t.toUpperCase()}get sip_uri(){return this._sip_uri}get url(){return this._url}connect(){if(Ot.debug("connect()"),this.isConnected()){Ot.debug(`WebSocket ${this._url} is already connected`);return}else if(this.isConnecting()){Ot.debug(`WebSocket ${this._url} is connecting`);return}this._ws&&this.disconnect(),Ot.debug(`connecting to WebSocket ${this._url}`);try{this._ws=new WebSocket(this._url,"sip"),this._ws.binaryType="arraybuffer",this._ws.onopen=this._onOpen.bind(this),this._ws.onclose=this._onClose.bind(this),this._ws.onmessage=this._onMessage.bind(this),this._ws.onerror=this._onError.bind(this)}catch(t){this._onError(t)}}disconnect(){Ot.debug("disconnect()"),this._ws&&(this._ws.onopen=()=>{},this._ws.onclose=()=>{},this._ws.onmessage=()=>{},this._ws.onerror=()=>{},this._ws.close(),this._ws=null)}send(t){return Ot.debug("send()"),this.isConnected()?(this._ws.send(t),!0):(Ot.warn("unable to send message, WebSocket is not open"),!1)}isConnected(){return this._ws&&this._ws.readyState===this._ws.OPEN}isConnecting(){return this._ws&&this._ws.readyState===this._ws.CONNECTING}_onOpen(){Ot.debug(`WebSocket ${this._url} connected`),this.onconnect()}_onClose({wasClean:t,code:n,reason:o}){Ot.debug(`WebSocket ${this._url} closed`),t===!1&&Ot.debug("WebSocket abrupt disconnection"),this.ondisconnect(!t,n,o)}_onMessage({data:t}){Ot.debug("received WebSocket message"),this.ondata(t)}_onError(t){Ot.warn(`WebSocket ${this._url} error: `,t)}};const Ru=Tl,HT=De,FT=Ts,VT=gt(),jT=gd,qT=ps(),BT=Ba(),GT=Yt(),WT=$T;Nn("JsSIP")("version %s",Ru.version);var KT={C:HT,Exceptions:FT,Utils:VT,UA:jT,URI:qT,NameAddrHeader:BT,WebSocketInterface:WT,Grammar:GT,debug:Nn,get name(){return Ru.title},get version(){return Ru.version}};const YT=Me(KT);function Iu(c){return c<10?`0${c}`:`${c}`}function JT(c){let t=c.hours||0,n=c.minutes||0,o=c.seconds||0;o++,o===60&&(o=0,n++,n===60&&(n=0,t++));const a=`${Iu(t)}:${Iu(n)}:${Iu(o)}`;return{seconds:o,minutes:n,hours:t,formatted:a}}function zT(c){let t=0;for(let n=0;n<c.length;n++)t+=c[n]*c[n];return Math.sqrt(t/c.length)}async function XT(c,t,n=150){const o=t.createMediaStreamSource(c),a=t.createDelay();a.delayTime.value=n/1e3;const s=t.createGain();s.gain.value=0;const r=t.createMediaStreamDestination();return o.connect(a).connect(s).connect(r),{stream:r.stream,setSpeaking:_=>{s.gain.value=_?1:0}}}var yt={};yt.forEach=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)if(a in c){const s=Promise.resolve(c[a]).then(r=>t.call(n||globalThis,r,a,c));o.push(s)}await Promise.all(o)},yt.forEachSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)o in c&&await t.call(n||globalThis,await c[o],o,c)},yt.map=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&(o[a]=Promise.resolve(c[a]).then(s=>t.call(n||globalThis,s,a,c)));return Promise.all(o)},yt.mapSeries=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&(o[a]=await t.call(n||globalThis,await c[a],a,c));return o},yt.find=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o();let s=1;for(let r=0;r<c.length;r++){const _=d=>{d?o(c[r]):s===c.length&&o(),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.findSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(await t.call(n||globalThis,await c[o],o,c))return c[o]},yt.findIndex=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(-1);let s=1;for(let r=0;r<c.length;r++){const _=d=>{d?o(r):s===c.length&&o(-1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.findIndexSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(await t.call(n||globalThis,await c[o],o,c))return o},yt.some=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(!1);let s=1;for(let r=0;r<c.length;r++){if(!(r in c)){s++;continue}const _=d=>{d?o(!0):s===c.length&&o(!1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.someSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(o in c&&await t.call(n||globalThis,await c[o],o,c))return!0;return!1},yt.every=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(!0);let s=1;for(let r=0;r<c.length;r++){if(!(r in c)){s++;continue}const _=d=>{d?s===c.length&&o(!0):o(!1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.everySeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(o in c&&!await t.call(n||globalThis,await c[o],o,c))return!1;return!0},yt.filter=(c,t,n)=>new Promise(async(o,a)=>{const s=[];for(let _=0;_<c.length;_++)_ in c&&(s[_]=Promise.resolve(c[_]).then(d=>t.call(n||globalThis,d,_,c)).catch(a));const r=[];for(let _=0;_<s.length;_++)await s[_]&&r.push(await c[_]);o(r)}),yt.filterSeries=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&await t.call(n||globalThis,await c[a],a,c)&&o.push(await c[a]);return o},yt.reduce=async(c,t,n)=>{if(c.length===0&&n===void 0)throw TypeError("Reduce of empty array with no initial value");let o,a;for(n!==void 0?(a=n,o=0):(a=c[0],o=1),o;o<c.length;o++)o in c&&(a=await t(await a,await c[o],o,c));return a};var yd={};(function(c){const t=yt;Object.keys(t).forEach(n=>{const o=n.charAt(0).toUpperCase()+n.slice(1);c[`async${o}`]=async function(...a){return t[n](this,...a)}})})(yd);var QT=Object.assign(yt,{instanceMethods:yd});const Xt={NEW_CALL:"new_call",CALL_CONFIRMED:"confirmed",CALL_FAILED:"failed",CALL_PROGRESS:"progress",CALL_ENDED:"ended"},Ao={TRYING:100,RINGING:180,SESSION_PROGRESS:183,OK:200,MOVED_TEMPORARILY:302,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,REQUEST_TIMEOUT:408,BUSY_HERE:486,REQUEST_TERMINATED:487,INTERNAL_SERVER_ERROR:500,SERVICE_UNAVAILABLE:503,BUSY_EVERYWHERE:600,DECLINE:603};var ZT={exports:{}};(function(c){var t=function(n){var o=Object.prototype,a=o.hasOwnProperty,s=Object.defineProperty||function(Q,K,G){Q[K]=G.value},r,_=typeof Symbol=="function"?Symbol:{},d=_.iterator||"@@iterator",h=_.asyncIterator||"@@asyncIterator",m=_.toStringTag||"@@toStringTag";function T(Q,K,G){return Object.defineProperty(Q,K,{value:G,enumerable:!0,configurable:!0,writable:!0}),Q[K]}try{T({},"")}catch{T=function(K,G,re){return K[G]=re}}function S(Q,K,G,re){var pe=K&&K.prototype instanceof ie?K:ie,Ie=Object.create(pe.prototype),Pe=new P(re||[]);return s(Ie,"_invoke",{value:Y(Q,G,Pe)}),Ie}n.wrap=S;function E(Q,K,G){try{return{type:"normal",arg:Q.call(K,G)}}catch(re){return{type:"throw",arg:re}}}var C="suspendedStart",A="suspendedYield",R="executing",L="completed",b={};function ie(){}function N(){}function F(){}var me={};T(me,d,function(){return this});var _e=Object.getPrototypeOf,U=_e&&_e(_e(B([])));U&&U!==o&&a.call(U,d)&&(me=U);var x=F.prototype=ie.prototype=Object.create(me);N.prototype=F,s(x,"constructor",{value:F,configurable:!0}),s(F,"constructor",{value:N,configurable:!0}),N.displayName=T(F,m,"GeneratorFunction");function q(Q){["next","throw","return"].forEach(function(K){T(Q,K,function(G){return this._invoke(K,G)})})}n.isGeneratorFunction=function(Q){var K=typeof Q=="function"&&Q.constructor;return K?K===N||(K.displayName||K.name)==="GeneratorFunction":!1},n.mark=function(Q){return Object.setPrototypeOf?Object.setPrototypeOf(Q,F):(Q.__proto__=F,T(Q,m,"GeneratorFunction")),Q.prototype=Object.create(x),Q},n.awrap=function(Q){return{__await:Q}};function j(Q,K){function G(Ie,Pe,Re,oe){var ye=E(Q[Ie],Q,Pe);if(ye.type==="throw")oe(ye.arg);else{var lt=ye.arg,at=lt.value;return at&&typeof at=="object"&&a.call(at,"__await")?K.resolve(at.__await).then(function(Ee){G("next",Ee,Re,oe)},function(Ee){G("throw",Ee,Re,oe)}):K.resolve(at).then(function(Ee){lt.value=Ee,Re(lt)},function(Ee){return G("throw",Ee,Re,oe)})}}var re;function pe(Ie,Pe){function Re(){return new K(function(oe,ye){G(Ie,Pe,oe,ye)})}return re=re?re.then(Re,Re):Re()}s(this,"_invoke",{value:pe})}q(j.prototype),T(j.prototype,h,function(){return this}),n.AsyncIterator=j,n.async=function(Q,K,G,re,pe){pe===void 0&&(pe=Promise);var Ie=new j(S(Q,K,G,re),pe);return n.isGeneratorFunction(K)?Ie:Ie.next().then(function(Pe){return Pe.done?Pe.value:Ie.next()})};function Y(Q,K,G){var re=C;return function(Ie,Pe){if(re===R)throw new Error("Generator is already running");if(re===L){if(Ie==="throw")throw Pe;return je()}for(G.method=Ie,G.arg=Pe;;){var Re=G.delegate;if(Re){var oe=V(Re,G);if(oe){if(oe===b)continue;return oe}}if(G.method==="next")G.sent=G._sent=G.arg;else if(G.method==="throw"){if(re===C)throw re=L,G.arg;G.dispatchException(G.arg)}else G.method==="return"&&G.abrupt("return",G.arg);re=R;var ye=E(Q,K,G);if(ye.type==="normal"){if(re=G.done?L:A,ye.arg===b)continue;return{value:ye.arg,done:G.done}}else ye.type==="throw"&&(re=L,G.method="throw",G.arg=ye.arg)}}}function V(Q,K){var G=K.method,re=Q.iterator[G];if(re===r)return K.delegate=null,G==="throw"&&Q.iterator.return&&(K.method="return",K.arg=r,V(Q,K),K.method==="throw")||G!=="return"&&(K.method="throw",K.arg=new TypeError("The iterator does not provide a '"+G+"' method")),b;var pe=E(re,Q.iterator,K.arg);if(pe.type==="throw")return K.method="throw",K.arg=pe.arg,K.delegate=null,b;var Ie=pe.arg;if(!Ie)return K.method="throw",K.arg=new TypeError("iterator result is not an object"),K.delegate=null,b;if(Ie.done)K[Q.resultName]=Ie.value,K.next=Q.nextLoc,K.method!=="return"&&(K.method="next",K.arg=r);else return Ie;return K.delegate=null,b}q(x),T(x,m,"Generator"),T(x,d,function(){return this}),T(x,"toString",function(){return"[object Generator]"});function X(Q){var K={tryLoc:Q[0]};1 in Q&&(K.catchLoc=Q[1]),2 in Q&&(K.finallyLoc=Q[2],K.afterLoc=Q[3]),this.tryEntries.push(K)}function k(Q){var K=Q.completion||{};K.type="normal",delete K.arg,Q.completion=K}function P(Q){this.tryEntries=[{tryLoc:"root"}],Q.forEach(X,this),this.reset(!0)}n.keys=function(Q){var K=Object(Q),G=[];for(var re in K)G.push(re);return G.reverse(),function pe(){for(;G.length;){var Ie=G.pop();if(Ie in K)return pe.value=Ie,pe.done=!1,pe}return pe.done=!0,pe}};function B(Q){if(Q){var K=Q[d];if(K)return K.call(Q);if(typeof Q.next=="function")return Q;if(!isNaN(Q.length)){var G=-1,re=function pe(){for(;++G<Q.length;)if(a.call(Q,G))return pe.value=Q[G],pe.done=!1,pe;return pe.value=r,pe.done=!0,pe};return re.next=re}}return{next:je}}n.values=B;function je(){return{value:r,done:!0}}return P.prototype={constructor:P,reset:function(Q){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(k),!Q)for(var K in this)K.charAt(0)==="t"&&a.call(this,K)&&!isNaN(+K.slice(1))&&(this[K]=r)},stop:function(){this.done=!0;var Q=this.tryEntries[0],K=Q.completion;if(K.type==="throw")throw K.arg;return this.rval},dispatchException:function(Q){if(this.done)throw Q;var K=this;function G(oe,ye){return Ie.type="throw",Ie.arg=Q,K.next=oe,ye&&(K.method="next",K.arg=r),!!ye}for(var re=this.tryEntries.length-1;re>=0;--re){var pe=this.tryEntries[re],Ie=pe.completion;if(pe.tryLoc==="root")return G("end");if(pe.tryLoc<=this.prev){var Pe=a.call(pe,"catchLoc"),Re=a.call(pe,"finallyLoc");if(Pe&&Re){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0);if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else if(Pe){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0)}else if(Re){if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else throw new Error("try statement without catch or finally")}}},abrupt:function(Q,K){for(var G=this.tryEntries.length-1;G>=0;--G){var re=this.tryEntries[G];if(re.tryLoc<=this.prev&&a.call(re,"finallyLoc")&&this.prev<re.finallyLoc){var pe=re;break}}pe&&(Q==="break"||Q==="continue")&&pe.tryLoc<=K&&K<=pe.finallyLoc&&(pe=null);var Ie=pe?pe.completion:{};return Ie.type=Q,Ie.arg=K,pe?(this.method="next",this.next=pe.finallyLoc,b):this.complete(Ie)},complete:function(Q,K){if(Q.type==="throw")throw Q.arg;return Q.type==="break"||Q.type==="continue"?this.next=Q.arg:Q.type==="return"?(this.rval=this.arg=Q.arg,this.method="return",this.next="end"):Q.type==="normal"&&K&&(this.next=K),b},finish:function(Q){for(var K=this.tryEntries.length-1;K>=0;--K){var G=this.tryEntries[K];if(G.finallyLoc===Q)return this.complete(G.completion,G.afterLoc),k(G),b}},catch:function(Q){for(var K=this.tryEntries.length-1;K>=0;--K){var G=this.tryEntries[K];if(G.tryLoc===Q){var re=G.completion;if(re.type==="throw"){var pe=re.arg;k(G)}return pe}}throw new Error("illegal catch attempt")},delegateYield:function(Q,K,G){return this.delegate={iterator:B(Q),resultName:K,nextLoc:G},this.method==="next"&&(this.arg=r),b}},n}(c.exports);try{regeneratorRuntime=t}catch{typeof globalThis=="object"?globalThis.regeneratorRuntime=t:Function("r","regeneratorRuntime = r")(t)}})(ZT);var Cd={exports:{}};(function(c){(function(t,n){c.exports?c.exports=n():t.log=n()})(cs,function(){var t=function(){},n="undefined",o=typeof window!==n&&typeof window.navigator!==n&&/Trident\/|MSIE /.test(window.navigator.userAgent),a=["trace","debug","info","warn","error"];function s(A,R){var L=A[R];if(typeof L.bind=="function")return L.bind(A);try{return Function.prototype.bind.call(L,A)}catch{return function(){return Function.prototype.apply.apply(L,[A,arguments])}}}function r(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function _(A){return A==="debug"&&(A="log"),typeof console===n?!1:A==="trace"&&o?r:console[A]!==void 0?s(console,A):console.log!==void 0?s(console,"log"):t}function d(A,R){for(var L=0;L<a.length;L++){var b=a[L];this[b]=L<A?t:this.methodFactory(b,A,R)}this.log=this.debug}function h(A,R,L){return function(){typeof console!==n&&(d.call(this,R,L),this[A].apply(this,arguments))}}function m(A,R,L){return _(A)||h.apply(this,arguments)}function T(A,R,L){var b=this,ie;R=R??"WARN";var N="loglevel";typeof A=="string"?N+=":"+A:typeof A=="symbol"&&(N=void 0);function F(x){var q=(a[x]||"silent").toUpperCase();if(!(typeof window===n||!N)){try{window.localStorage[N]=q;return}catch{}try{window.document.cookie=encodeURIComponent(N)+"="+q+";"}catch{}}}function me(){var x;if(!(typeof window===n||!N)){try{x=window.localStorage[N]}catch{}if(typeof x===n)try{var q=window.document.cookie,j=q.indexOf(encodeURIComponent(N)+"=");j!==-1&&(x=/^([^;]+)/.exec(q.slice(j))[1])}catch{}return b.levels[x]===void 0&&(x=void 0),x}}function _e(){if(!(typeof window===n||!N)){try{window.localStorage.removeItem(N);return}catch{}try{window.document.cookie=encodeURIComponent(N)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch{}}}b.name=A,b.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},b.methodFactory=L||m,b.getLevel=function(){return ie},b.setLevel=function(x,q){if(typeof x=="string"&&b.levels[x.toUpperCase()]!==void 0&&(x=b.levels[x.toUpperCase()]),typeof x=="number"&&x>=0&&x<=b.levels.SILENT){if(ie=x,q!==!1&&F(x),d.call(b,x,A),typeof console===n&&x<b.levels.SILENT)return"No console available for logging"}else throw"log.setLevel() called with invalid level: "+x},b.setDefaultLevel=function(x){R=x,me()||b.setLevel(x,!1)},b.resetLevel=function(){b.setLevel(R,!1),_e()},b.enableAll=function(x){b.setLevel(b.levels.TRACE,x)},b.disableAll=function(x){b.setLevel(b.levels.SILENT,x)};var U=me();U==null&&(U=R),b.setLevel(U,!1)}var S=new T,E={};S.getLogger=function(R){if(typeof R!="symbol"&&typeof R!="string"||R==="")throw new TypeError("You must supply a name when creating a logger.");var L=E[R];return L||(L=E[R]=new T(R,S.getLevel(),S.methodFactory)),L};var C=typeof window!==n?window.log:void 0;return S.noConflict=function(){return typeof window!==n&&window.log===S&&(window.log=C),S},S.getLoggers=function(){return E},S.default=S,S})})(Cd);var It=Cd.exports;const Ss=()=>`${new Date().toISOString()} | metrics`,Es=(c,t,n)=>`${c} | ${t} | ${n}`;It.setDefaultLevel(It.levels.TRACE);const ev=c=>{It.info(Es(Ss(),"log ",`set log level to ${c?"verbose":"info"}`)),It.setLevel(c?It.levels.TRACE:It.levels.INFO)},tv=c=>{const t=[...Object.keys(It.levels)];t.includes(c)?(It.info(Es(Ss(),"log ",`update log level to ${c.toLowerCase()}`)),It.setLevel(c)):It.warn(Es(Ss(),"log ","Incorrect log level please choose one of "),t)},Ue=(c,t,n)=>{n?It.debug(Es(Ss(),c,t),n):It.debug(Es(Ss(),c,t))},bu=(c,t)=>{It.info(Es(Ss(),c,t))},on=(c,t)=>{It.info(Es(Ss(),c,t))},Ro=(c,t)=>{It.warn(Es(Ss(),c,t))},jn=(c,t)=>{It.error(Es(Ss(),c,t))};function sv(c){return Math.floor(Math.random()*c).toString()}function Ad(c,t){let n=t;return c.forEach(o=>{n=n.replace(o,"")}),n}function nv(c,t){let n="";for(let o=0;o<t;o+=1)n+=c[sv(c.length)];return n}function rv({length:c=20,useLetters:t=!0,useNumbers:n=!0,includeSymbols:o=[],excludeSymbols:a=[]}={}){let s="abcdefghijklmnopqrstuvwxyz",r="0123456789",_=[],d=[],h=[];return t&&(a.length&&(s=Ad(a,s)),d=s.split("")),n&&(a.length&&(r=Ad(a,r)),h=r.split("")),_=[...d,...h,...o],nv(_,c)}var iv=rv;const ni=Me(iv),lv=()=>"WebRTCMetrics",ov=()=>"5.0.3",$e={INBOUND:"inbound",OUTBOUND:"outbound"},ys={IDLE:"idle",RUNNING:"running",MUTED:"muted"},ri={NEW:"new",CHECKING:"checking",CONNECTED:"connected",COMPLETED:"completed",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"},av=()=>({...{delta_time_to_measure_probes_ms:0,delta_time_consumed_to_measure_ms:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,total_time_decoded_in:0,total_time_encoded_out:0,probes:[]}}),Rd={level_in:0,codec_id_in:"",codec_in:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,mos_in:0,mos_emodel_in:0,ssrc:"",direction:$e.INBOUND},Id={level_out:0,codec_id_out:"",codec_out:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,timestamp_out:null,mos_out:0,mos_emodel_out:0,ssrc:"",direction:$e.OUTBOUND},bd={codec_id_in:"",size_in:{width:null,height:null,framerate:null},codec_in:{mime_type:null,clock_rate:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,decoder_in:null,delta_ms_decode_frame_in:0,total_frames_decoded_in:0,total_time_decoded_in:0,delta_nack_sent_in:0,delta_pli_sent_in:0,total_nack_sent_in:0,total_pli_sent_in:0,ssrc:"",direction:$e.INBOUND},wd={codec_id_out:"",size_out:{width:null,height:null,framerate:null},codec_out:{mime_type:null,clock_rate:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,encoder_out:null,delta_ms_encode_frame_out:0,total_time_encoded_out:0,total_frames_encoded_out:0,delta_nack_received_out:0,delta_pli_received_out:0,total_nack_received_out:0,total_pli_received_out:0,limitation_out:{reason:null,durations:null,resolutionChanges:0},timestamp_out:null,ssrc:"",direction:$e.OUTBOUND},uv=c=>{const t={pname:"",call_id:"",user_id:"",timestamp:null,count:0,audio:{},video:{},network:{infrastructure:3,local_candidate_id:"",local_candidate_type:"",local_candidate_protocol:"",local_candidate_relay_protocol:"",remote_candidate_id:"",remote_candidate_type:"",remote_candidate_protocol:""},data:{total_KBytes_in:0,total_KBytes_out:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,delta_kbs_bandwidth_in:0,delta_kbs_bandwidth_out:0,delta_rtt_connectivity_ms:null,total_rtt_connectivity_ms:0,total_rtt_connectivity_measure:0},experimental:{time_to_measure_ms:0}};if(c){const n={...c,audio:{},video:{},data:{...c.data},network:{...c.network},experimental:{...c.experimental}};return Object.keys(c.audio).forEach(o=>{n.audio[o]={...c.audio[o]}}),Object.keys(c.video).forEach(o=>{n.video[o]={...c.video[o]}}),n}return{...t,audio:{},video:{},data:{...t.data},network:{...t.network},experimental:{...t.experimental}}},cv={refreshEvery:2e3,startAfter:0,stopAfter:-1,verbose:!1,pname:`p-${ni()}`,cid:`c-${ni()}`,uid:`u-${ni()}`,record:!1,ticket:!0},Qt={CANDIDATE_PAIR:"candidate-pair",CODEC:"codec",INBOUND_RTP:"inbound-rtp",LOCAL_CANDIDATE:"local-candidate",MEDIA_SOURCE:"media-source",OUTBOUND_RTP:"outbound-rtp",REMOTE_CANDIDATE:"remote-candidate",REMOTE_INBOUND_RTP:"remote-inbound-rtp",TRACK:"track"},W={AUDIO_LEVEL:"audioLevel",AVAILABLE_OUTGOING_BITRATE:"availableOutgoingBitrate",AVAILABLE_INCOMING_BITRATE:"availableIncomingBitrate",BYTES_RECEIVED:"bytesReceived",BYTES_SENT:"bytesSent",CANDIDATE_TYPE:"candidateType",CHANNELS:"channels",CLOCK_RATE:"clockRate",CODEC_ID:"codecId",CURRENT_ROUND_TRIP_TIME:"currentRoundTripTime",ROUND_TRIP_TIME:"roundTripTime",FRACTION_LOST:"fractionLost",FRAME_HEIGHT:"frameHeight",FRAME_WIDTH:"frameWidth",QUALITY_LIMITATION_REASON:"qualityLimitationReason",QUALITY_LIMITATION_DURATIONS:"qualityLimitationDurations",QUALITY_LIMITATION_RESOLUTION_CHANGES:"qualityLimitationResolutionChanges",ID:"id",JITTER:"jitter",KIND:"kind",MEDIA_TYPE:"mediaType",MIME_TYPE:"mimeType",LOCAL_CANDIDATE_ID:"localCandidateId",NETWORK_TYPE:"networkType",RELAY_PROTOCOL:"relayProtocol",NOMINATED:"nominated",PACKETS_LOST:"packetsLost",PACKETS_RECEIVED:"packetsReceived",PACKETS_SENT:"packetsSent",PROTOCOL:"protocol",PORT:"port",REMOTE_CANDIDATE_ID:"remoteCandidateId",REMOTE_SOURCE:"remoteSource",RESPONSES_RECEIVED:"responsesReceived",SDP_FMTP_LINE:"sdpFmtpLine",SSRC:"ssrc",SELECTED:"selected",STATE:"state",TIMESTAMP:"timestamp",TOTAL_ROUND_TRIP_TIME:"totalRoundTripTime",TOTAL_ROUND_TRIP_TIME_MEASUREMENTS:"roundTripTimeMeasurements",TYPE:"type",DECODER_IMPLEMENTATION:"decoderImplementation",ENCODER_IMPLEMENTATION:"encoderImplementation",FRAMES_DECODED:"framesDecoded",FRAMES_ENCODED:"framesEncoded",FRAMES_PER_SECOND:"framesPerSecond",TOTAL_DECODE_TIME:"totalDecodeTime",TOTAL_ENCODE_TIME:"totalEncodeTime",PLI:"pliCount",NACK:"nackCount"},M={SUCCEEDED:"succeeded",AUDIO:"audio",VIDEO:"video"},ii={ETHERNET:0,CELLULAR_5G:2,WIFI:3,CELLULAR_4G:5,CELLULAR:10},wu={ETHERNET:"ethernet",CELLULAR_4G:"cellular",WIFI:"wifi"},ne={AUDIO:"audio",VIDEO:"video",NETWORK:"network",DATA:"data"},Ou="config ",fv=(c,t={},n)=>{const o={...n,...t};return t.pname||Ro(Ou,`Argument [String] 'cfg.pname' for the peerConnection name or id is missing - use generated '${n.pname}'`),t.cid||Ro(Ou,`Argument [String] 'cfg.cid' for the call name or id is missing - use generated '${n.cid}'`),t.uid||Ro(Ou,`Argument [String] 'cfg.uid' for the user name or id is missing - use generated '${n.uid}'`),o.pc=c,o},dv=(c={})=>{const t={...cv,...c};return t.name=lv(),t.version=ov(),t},li=(c,t,n,o=!1,a)=>{let s=c.map(r=>{if(!n)return r[t];if(!a)return r[t][n];const _=r[t][a];return _?_[n]:null});return s=s.filter(r=>o?Number.isFinite(r)&&r>0:Number.isFinite(r)),s.length===0?[]:s},Ms=c=>c.reduce((t,n)=>t+n,0)/c.length,hv=()=>`probe-${ni()}`,_v=()=>`coltr-${ni()}`,Od=c=>new Promise(t=>setTimeout(t,c)),Du=(c,t,n)=>{t?c.call(t,n):c(n)},Ke=(c,t,n,o)=>{const a=li(c,t,n,!0,o);if(a.length===0)return null;const s=a.reduce((h,m)=>h+m,0)/a.length;return s===0?null:a.map(h=>Math.abs(s-h)).reduce((h,m)=>h+m,0)/a.length*100/s},Qe=(c,t,n,o=!1,a)=>{const s=li(c,t,n,o,a);return s.length===0?null:s.reduce((r,_)=>r+_,0)/s.length},an=(c,t,n)=>li(c,t,n).reduce((a,s)=>a+s,0),Ye=(c,t,n,o)=>{const a=li(c,t,n,!0,o);return a.length===0?null:Math.min(...a)},Je=(c,t,n,o)=>{const a=li(c,t,n,!1,o);return a.length===0?null:Math.max(...a)},Ct=(c,t,n,o)=>{const a=c.slice().pop();if(!a)return null;if(!n)return a[t];if(!o)return a[t][n];const s=a[t][o];return s?s[n]:null},pv=c=>c.slice().pop(),dt=(c,t,n)=>{if(!t)return null;const o={};let a=t[M.AUDIO][c];a||(a=n===$e.INBOUND?{...Rd}:{...Id}),o[M.AUDIO]=a;let s=t[M.VIDEO][c];return s||(s=n===$e.INBOUND?{...bd}:{...wd}),o[M.VIDEO]=s,o},oi="exporter ",gv="2.0",Dd=(c,t,n)=>{if(!c||c.length===0)return 0;const o=c[c.length-1];if(!o)return 0;const a=o[t][n];if(a){const s=a.total_rtt_ms_out,r=a.total_rtt_measure_out;return!r||!s?Qe(c,t,"delta_rtt_ms_out",!1,n):Number(s/r)}return null},mv=(c,t)=>{if(!c||c.length===0)return 0;const n=c[c.length-1];if(!n)return 0;const o=n[t].total_rtt_connectivity_ms,a=n[t].total_rtt_connectivity_measure;return!a||!o?Qe(c,t,"delta_rtt_connectivity_ms"):Number(o/a)},Tv=c=>Ct(c,"network","local_candidate_type")!=="relay"?`direct/${Ct(c,"network","local_candidate_protocol")}`:`turn/${Ct(c,"network","local_candidate_relay_protocol")}`,vv=c=>{const t=Ct(c,"network","remote_candidate_type"),n=Ct(c,"network","remote_candidate_protocol");return t!=="relay"?`direct/${n}`:`turn/${n}`};class Sv{constructor(t){this._start=null,this._end=null,this._cfg=t,this._referenceReport=null,this._reports=[],this._events=[]}start(){bu(oi,"start() - start exporter...");const t=new Date;return this._start=t.toJSON(),t}stop(){bu(oi,"stop() - stop exporter...");const t=new Date;return this._end=t.toJSON(),t}saveReferenceReport(t){this._referenceReport=t}getReferenceReport(){return this._referenceReport}addReport(t){this._cfg.ticket&&(Ue(oi,`addReport() - add report to exporter at ${t.timestamp}`),this._reports.push(t))}addCustomEvent(t){this._events.push(t)}reset(){bu(oi,"resetReports() - reset reports"),this._reports=[],this._referenceReport=null,this._start=null,this._end=null}get ticket(){Ue(oi,"ticket() - generate ticket");const t=Ct(this._reports,"audio","total_packets_lost_in"),n=Ct(this._reports,"audio","total_packets_in"),o=Ct(this._reports,"video","total_packets_lost_in"),a=Ct(this._reports,"video","total_packets_in"),s={},r=pv(this._reports);return r&&(Object.keys(r[M.AUDIO]).forEach(_=>{const d=r[M.AUDIO][_];if(s[d.ssrc]={type:M.AUDIO,direction:d.direction},d.direction===$e.INBOUND){const h={avg:Qe(this._reports,M.AUDIO,"delta_jitter_ms_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_jitter_ms_in",_),max:Je(this._reports,M.AUDIO,"delta_jitter_ms_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_jitter_ms_in",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.AUDIO,"delta_kbs_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_kbs_in",_),max:Je(this._reports,M.AUDIO,"delta_kbs_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_kbs_in",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.AUDIO,"delta_KBytes_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_KBytes_in",_),max:Je(this._reports,M.AUDIO,"delta_KBytes_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_KBytes_in",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={emodel:{avg:Qe(this._reports,M.AUDIO,"mos_emodel_in",!1,_),min:Ye(this._reports,M.AUDIO,"mos_emodel_in",_),max:Je(this._reports,M.AUDIO,"mos_emodel_in",_),volatility:Ke(this._reports,M.AUDIO,"mos_emodel_in",_)},effective:{avg:Qe(this._reports,M.AUDIO,"mos_in",!1,_),min:Ye(this._reports,M.AUDIO,"mos_in",_),max:Je(this._reports,M.AUDIO,"mos_in",_),volatility:Ke(this._reports,M.AUDIO,"mos_in",_)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}},E=Ct(this._reports,M.AUDIO,"total_packets_lost_in",_),C=Ct(this._reports,M.AUDIO,"total_packets_in",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].mos=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A}else{const h={avg:Qe(this._reports,M.AUDIO,"delta_jitter_ms_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_jitter_ms_out",_),max:Je(this._reports,M.AUDIO,"delta_jitter_ms_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_jitter_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.AUDIO,"delta_kbs_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_kbs_out",_),max:Je(this._reports,M.AUDIO,"delta_kbs_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_kbs_out",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.AUDIO,"delta_KBytes_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_KBytes_out",_),max:Je(this._reports,M.AUDIO,"delta_KBytes_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_KBytes_out",_),_unit:{avg:"KB",min:"KB",max:"KB",bitrate:"kbs",volatility:"percent"}},S={avg:Dd(this._reports,M.AUDIO,_),min:Ye(this._reports,M.AUDIO,"delta_rtt_ms_out",_),max:Je(this._reports,M.AUDIO,"delta_rtt_ms_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_rtt_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Ct(this._reports,M.AUDIO,"total_packets_lost_out",_),C=Ct(this._reports,M.AUDIO,"total_packets_out",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}},R={emodel:{avg:Qe(this._reports,M.AUDIO,"mos_emodel_out",!1,_),min:Ye(this._reports,M.AUDIO,"mos_emodel_out",_),max:Je(this._reports,M.AUDIO,"mos_emodel_out",_),volatility:Ke(this._reports,M.AUDIO,"mos_emodel_out",_)},effective:{avg:Qe(this._reports,M.AUDIO,"mos_out",!1,_),min:Ye(this._reports,M.AUDIO,"mos_out",_),max:Je(this._reports,M.AUDIO,"mos_out",_),volatility:Ke(this._reports,M.AUDIO,"mos_out",_)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}};s[_].jitter=h,s[_].rtt=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A,s[_].mos=R}}),Object.keys(r[M.VIDEO]).forEach(_=>{const d=r[M.VIDEO][_];if(s[_]={type:M.VIDEO,direction:d.direction},d.direction===$e.INBOUND){const h={avg:Qe(this._reports,M.VIDEO,"delta_jitter_ms_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_jitter_ms_in",_),max:Je(this._reports,M.VIDEO,"delta_jitter_ms_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_jitter_ms_in",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.VIDEO,"delta_kbs_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_kbs_in",_),max:Je(this._reports,M.VIDEO,"delta_kbs_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_kbs_in",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.VIDEO,"delta_KBytes_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_KBytes_in",_),max:Je(this._reports,M.VIDEO,"delta_KBytes_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_KBytes_in",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S=Ct(this._reports,M.VIDEO,"total_packets_lost_in",_),E=Ct(this._reports,M.VIDEO,"total_packets_in",_),C={lost:S,avg:Math.round((S/(S+E)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].traffic=T,s[_].bitrate=m,s[_].loss=C}else{const h={avg:Qe(this._reports,M.VIDEO,"delta_jitter_ms_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_jitter_ms_out",_),max:Je(this._reports,M.VIDEO,"delta_jitter_ms_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_jitter_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.VIDEO,"delta_kbs_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_kbs_out",_),max:Je(this._reports,M.VIDEO,"delta_kbs_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_kbs_out",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.VIDEO,"delta_KBytes_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_KBytes_out",_),max:Je(this._reports,M.VIDEO,"delta_KBytes_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_KBytes_out",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={avg:Dd(this._reports,M.VIDEO,_),min:Ye(this._reports,M.VIDEO,"delta_rtt_ms_out",_),max:Je(this._reports,M.VIDEO,"delta_rtt_ms_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_rtt_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Ct(this._reports,M.VIDEO,"total_packets_lost_out",_),C=Ct(this._reports,M.VIDEO,"total_packets_out",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].rtt=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A}})),{version:gv,configuration:{frequency:this._cfg.refreshEvery},started:this._start,ended:this._end,ua:{agent:navigator.userAgent,pname:this._cfg.pname,user_id:this._cfg.uid},call:{call_id:this._cfg.cid,events:this._events},details:{count:this._reports.length,reports:this._cfg.record?this._reports:[],reference:this._referenceReport||null},ssrc:s,data:{rtt:{avg:mv(this._reports,"data"),min:Ye(this._reports,"data","delta_rtt_connectivity_ms"),max:Je(this._reports,"data","delta_rtt_connectivity_ms"),volatility:Ke(this._reports,"data","delta_rtt_connectivity_ms"),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},packetsLost:{audio:{in:{avg:Math.round((t/(t+n)*100||0)*100)/100}},video:{in:{avg:Math.round((o/(o+a)*100||0)*100)/100}},unit:{avg:"percent"}},bitrate:{in:{avg:Qe(this._reports,"data","delta_kbs_in"),min:Ye(this._reports,"data","delta_kbs_in"),max:Je(this._reports,"data","delta_kbs_in"),volatility:Ke(this._reports,"data","delta_kbs_in")},out:{avg:Qe(this._reports,"data","delta_kbs_out"),min:Ye(this._reports,"data","delta_kbs_out"),max:Je(this._reports,"data","delta_kbs_out"),volatility:Ke(this._reports,"data","delta_kbs_out")},unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},traffic:{in:{avg:Qe(this._reports,"data","delta_KBytes_in"),min:Ye(this._reports,"data","delta_KBytes_in"),max:Je(this._reports,"data","delta_KBytes_in"),volatility:Ke(this._reports,"data","delta_KBytes_in")},out:{avg:Qe(this._reports,"data","delta_KBytes_out"),min:Ye(this._reports,"data","delta_KBytes_out"),max:Je(this._reports,"data","delta_KBytes_out"),volatility:Ke(this._reports,"data","delta_KBytes_out")},unit:{avg:"KBytes",min:"KBytes",max:"KBytes",volatility:"percent"}},network:{localConnection:Tv(this._reports),remoteConnection:vv(this._reports)}}}}updateConfig(t){this._cfg=t}getLastReport(){return this._reports.slice().pop()||null}getBeforeLastReport(){const t=this._reports.slice();return t.pop(),t.pop()||null}getReportsNumber(){return this._reports.length}}const Ls="extractor ",Nd=(c,t,n,o)=>{let a=!1;const s=o[t].total_rtt_ms_out,r=o[t].total_rtt_measure_out,_=n?n[t].total_rtt_ms_out:0,d=n?n[t].total_rtt_measure_out:0,h={rtt:null,totalRTT:s,totalRTTMeasurements:r};if(c[W.TIMESTAMP]===o[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,W.ROUND_TRIP_TIME)||Object.prototype.hasOwnProperty.call(c,W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS)&&(a=!0,Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])===0||Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d===r))return h;const m=1e3*Number(c[W.ROUND_TRIP_TIME]);let T=s+m,S=r+1;return a&&(T=1e3*Number(c[W.TOTAL_ROUND_TRIP_TIME])-_,S=Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d),{rtt:m,totalRTT:T,totalRTTMeasurements:S}},Ev=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.CURRENT_ROUND_TRIP_TIME))return{rtt:null,totalRTT:o[t].total_rtt_connectivity_ms,totalRTTMeasurements:o[t].total_rtt_connectivity_measure};const a=1e3*Number(c[W.CURRENT_ROUND_TRIP_TIME]);let s=o[t].total_rtt_connectivity_ms+a,r=o[t].total_rtt_connectivity_measure+1;return Object.prototype.hasOwnProperty.call(c,W.TOTAL_ROUND_TRIP_TIME)&&(s=1e3*Number(c[W.TOTAL_ROUND_TRIP_TIME])-(n?n[t].total_rtt_connectivity_ms:0)),Object.prototype.hasOwnProperty.call(c,W.RESPONSES_RECEIVED)&&(r=Number(c[W.RESPONSES_RECEIVED])-(n?n[t].total_rtt_connectivity_measure:0)),{rtt:a,totalRTT:s,totalRTTMeasurements:r}},Io=(c,t,n)=>c[W.TIMESTAMP]===n[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,W.JITTER)?null:1e3*(Number(c[W.JITTER])||0),yv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,W.FRAMES_DECODED)||!Object.prototype.hasOwnProperty.call(c,W.TOTAL_DECODE_TIME))return{delta_ms_decode_frame:t[M.VIDEO].delta_ms_decode_frame_in,frames_decoded:t[M.VIDEO].total_frames_decoded_in,total_decode_time:t[M.VIDEO].total_time_decoded_in};const n=c[W.FRAMES_DECODED],o=c[W.TOTAL_DECODE_TIME],a=o-t[M.VIDEO].total_time_decoded_in,s=n-t[M.VIDEO].total_frames_decoded_in;return{delta_ms_decode_frame:s>0?a*1e3/s:0,frames_decoded:n,total_decode_time:o}},Cv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,W.FRAMES_ENCODED)||!Object.prototype.hasOwnProperty.call(c,W.TOTAL_ENCODE_TIME))return{delta_ms_encode_frame:t[M.VIDEO].delta_ms_encode_frame_out,frames_encoded:t[M.VIDEO].total_frames_encoded_out,total_encode_time:t[M.VIDEO].total_time_encoded_out};const n=c[W.FRAMES_ENCODED],o=c[W.TOTAL_ENCODE_TIME],a=o-t[M.VIDEO].total_time_encoded_out,s=n-t[M.VIDEO].total_frames_encoded_out;return{delta_ms_encode_frame:s>0&&a?a*1e3/s:0,frames_encoded:n,total_encode_time:o}},xd=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PACKETS_SENT)||!Object.prototype.hasOwnProperty.call(c,W.BYTES_SENT))return{packetsSent:n[t].total_packets_out,packetsLost:n[t].total_packets_lost_out,bytesSent:n[t].total_KBytes_out};const a=Number(c[W.PACKETS_SENT])||0-(o?o[t].total_packets_out:0),s=a-n[t].total_packets_out,r=Number(c[W.BYTES_SENT])/1024-(o?o[t].total_KBytes_out:0),_=r-n[t].total_KBytes_out,d=c[W.TIMESTAMP]||Date.now(),h=o?o.timestamp:null;let m=n.timestamp;!m&&h&&(m=h);const T=m?d-m:0,S=T>0?_*.008*1024/T*1e3:0;return{packetsSent:a,deltaPacketsSent:s,KBytesSent:r,deltaKBytesSent:_,kbsSent:S}},Ud=(c,t,n,o)=>{let a=n[t].total_packets_lost_out,s=0,r=0;return Object.prototype.hasOwnProperty.call(c,W.PACKETS_LOST)&&(a=Number(c[W.PACKETS_LOST])||0-(o?o[t].total_packets_lost_out:0),s=a-n[t].total_packets_lost_out),Object.prototype.hasOwnProperty.call(c,W.FRACTION_LOST)&&(r=Number(100*c[W.FRACTION_LOST])),{packetsLost:a,deltaPacketsLost:s,fractionLost:r}},kd=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PACKETS_RECEIVED)||!Object.prototype.hasOwnProperty.call(c,W.PACKETS_LOST)||!Object.prototype.hasOwnProperty.call(c,W.BYTES_RECEIVED))return{percent_packets_lost:n[t].percent_packets_lost_in,packetsReceived:n[t].total_packets_in,packetsLost:n[t].total_packets_lost_in,bytesReceived:n[t].total_KBytes_in};const a=Number(c[W.PACKETS_RECEIVED])||0-(o?o[t].total_packets_in:0),s=Number(c[W.PACKETS_LOST])||0-(o?o[t].total_packets_lost_in:0),r=s-n[t].total_packets_lost_in,_=a-n[t].total_packets_in,d=a!==n[t].total_packets_in?r*100/(r+_):0,h=Number(c[W.BYTES_RECEIVED])/1024-(o?o[t].total_KBytes_in:0),m=h-n[t].total_KBytes_in,T=c[W.TIMESTAMP]||Date.now(),S=o?o.timestamp:null;let E=n.timestamp;!E&&S&&(E=S);const C=E?T-E:0,A=C>0?m*.008*1024/C*1e3:0;return{percentPacketsLost:d,packetsReceived:a,deltaPacketsReceived:_,packetsLost:s,deltaPacketsLost:r,KBytesReceived:h,deltaKBytesReceived:m,kbsReceived:A}},Av=c=>c[W.CANDIDATE_TYPE]!=="relay"?"":c[W.RELAY_PROTOCOL]||"",Rv=c=>{if(!Object.prototype.hasOwnProperty.call(c,W.NETWORK_TYPE))return ii.WIFI;switch(c[W.NETWORK_TYPE]){case wu.ETHERNET:return ii.ETHERNET;case wu.CELLULAR_4G:return ii.CELLULAR_4G;case wu.WIFI:return ii.WIFI;default:return ii.CELLULAR}},Pd=c=>!Object.prototype.hasOwnProperty.call(c,W.FRAME_HEIGHT)||!Object.prototype.hasOwnProperty.call(c,W.FRAME_WIDTH)?{width:null,height:null,framerate:null}:{width:c[W.FRAME_WIDTH]||null,height:c[W.FRAME_HEIGHT]||null,framerate:c[W.FRAMES_PER_SECOND]},Iv=c=>{const t=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_REASON)?c[W.QUALITY_LIMITATION_REASON]:null,n=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_RESOLUTION_CHANGES)?c[W.QUALITY_LIMITATION_RESOLUTION_CHANGES]:null,o=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_DURATIONS)?c[W.QUALITY_LIMITATION_DURATIONS]:null;return o&&Object.keys(o).forEach(a=>{o[a]>1e3&&(o[a]=Number(o[a]/1e3))}),{reason:t,durations:o,resolutionChanges:n}},bv=(c,t,n)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PLI)||!Object.prototype.hasOwnProperty.call(c,W.NACK))return{pliCount:t.total_pli_sent_in,nackCount:t.total_nack_sent_in,deltaPliCount:0,deltaNackCount:0};const o=(c[W.PLI]||0)-(n?n[M.VIDEO].total_pli_sent_in:0),a=(c[W.NACK]||0)-(n?n[M.VIDEO].total_nack_sent_in:0);return{pliCount:o,nackCount:a,deltaPliCount:o-t[M.VIDEO].total_pli_sent_in,deltaNackCount:a-t[M.VIDEO].total_nack_sent_in}},wv=(c,t,n)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PLI)||!Object.prototype.hasOwnProperty.call(c,W.NACK))return{pliCount:t.total_pli_received_out,nackCount:t.total_nack_received_out,deltaPliCount:0,deltaNackCount:0};const o=(c[W.PLI]||0)-(n?n[M.VIDEO].total_pli_received_out:0),a=(c[W.NACK]||0)-(n?n[M.VIDEO].total_nack_received_out:0);return{pliCount:o,nackCount:a,deltaPliCount:o-t[M.VIDEO].total_pli_received_out,deltaNackCount:a-t[M.VIDEO].total_nack_received_out}},Ov=c=>({channels:c[W.CHANNELS]||null,clock_rate:c[W.CLOCK_RATE]||null,mime_type:c[W.MIME_TYPE]||null,sdp_fmtp_line:c[W.SDP_FMTP_LINE]||null}),Dv=c=>({clock_rate:c[W.CLOCK_RATE]||null,mime_type:c[W.MIME_TYPE]||null}),Nv=(c,t,n)=>{const o=(c[W.BYTES_RECEIVED]||0)/1024-(n?n.data.total_KBytes_in:0),a=(c[W.BYTES_SENT]||0)/1024-(n?n.data.total_KBytes_out:0),s=c[W.TIMESTAMP]||Date.now(),r=o-t.data.total_KBytes_in,_=a-t.data.total_KBytes_out,d=n?n.timestamp:null;let h=t.timestamp;!h&&d&&(h=d);const m=h?s-h:0,T=m>0?r*.008*1024/m*1e3:0,S=m>0?_*.008*1024/m*1e3:0;return{total_KBytes_received:o,total_KBytes_sent:a,delta_KBytes_received:r,delta_KBytes_sent:_,kbs_speed_received:T,kbs_speed_sent:S}},xv=c=>{const t=c[W.AVAILABLE_INCOMING_BITRATE]/1024||0,n=c[W.AVAILABLE_OUTGOING_BITRATE]/1024||0;return{kbs_incoming_bandwidth:t,kbs_outgoing_bandwidth:n}},Uv=(c,t,n,o)=>{if(!c)return[];switch(c[W.TYPE]){case Qt.CANDIDATE_PAIR:let a=!1;if(c[W.NOMINATED]&&c[W.STATE]===M.SUCCEEDED&&(a=!0,Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c),W.SELECTED in c&&!c[W.SELECTED]&&(a=!1)),a){const r=c[W.LOCAL_CANDIDATE_ID],_=c[W.REMOTE_CANDIDATE_ID],d=Nv(c,t,o),h=xv(c),m=Ev(c,"data",o,t);return[{type:ne.NETWORK,value:{local_candidate_id:r}},{type:ne.NETWORK,value:{remote_candidate_id:_}},{type:ne.DATA,value:{total_KBytes_in:d.total_KBytes_received}},{type:ne.DATA,value:{total_KBytes_out:d.total_KBytes_sent}},{type:ne.DATA,value:{delta_KBytes_in:d.delta_KBytes_received}},{type:ne.DATA,value:{delta_KBytes_out:d.delta_KBytes_sent}},{type:ne.DATA,value:{delta_kbs_in:d.kbs_speed_received}},{type:ne.DATA,value:{delta_kbs_out:d.kbs_speed_sent}},{type:ne.DATA,value:{delta_kbs_bandwidth_in:h.kbs_incoming_bandwidth}},{type:ne.DATA,value:{delta_kbs_bandwidth_out:h.kbs_outgoing_bandwidth}},{type:ne.DATA,value:{delta_rtt_connectivity_ms:m.rtt}},{type:ne.DATA,value:{total_rtt_connectivity_ms:m.totalRTT}},{type:ne.DATA,value:{total_rtt_connectivity_measure:m.totalRTTMeasurements}}]}break;case Qt.LOCAL_CANDIDATE:if(c[W.ID]===t.network.local_candidate_id)return[{type:ne.NETWORK,value:{infrastructure:Rv(c)}},{type:ne.NETWORK,value:{local_candidate_type:c[W.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{local_candidate_protocol:c[W.PROTOCOL]||""}},{type:ne.NETWORK,value:{local_candidate_relay_protocol:Av(c)}}];break;case Qt.REMOTE_CANDIDATE:if(c[W.ID]===t.network.remote_candidate_id)return[{type:ne.NETWORK,value:{remote_candidate_type:c[W.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{remote_candidate_protocol:c[W.PROTOCOL]||""}}];break;case Qt.INBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.INBOUND);_&&(_.timestamp=t.timestamp);const d=dt(r,o,$e.INBOUND);if(d&&(d.timestamp=o.timestamp),c[W.MEDIA_TYPE]===M.AUDIO){const h=kd(c,M.AUDIO,_,d),m=Io(c,M.AUDIO,_),T=c[W.CODEC_ID]||"";return[{ssrc:r,type:ne.AUDIO,value:{codec_id_in:T}},{ssrc:r,type:ne.AUDIO,value:{total_packets_in:h.packetsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_in:h.deltaPacketsReceived}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_in:h.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_in:h.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_in:h.percentPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_in:h.KBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_in:h.deltaKBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_in:h.kbsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_in:m}}]}if(c[W.MEDIA_TYPE]===M.VIDEO){const h=yv(c,_),m=kd(c,M.VIDEO,_,d),T=Io(c,M.VIDEO,_),S=c[W.DECODER_IMPLEMENTATION]||null,E=c[W.CODEC_ID]||null,C=Pd(c),A=bv(c,_,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_in:E}},{ssrc:r,type:ne.VIDEO,value:{total_packets_in:m.packetsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_in:m.deltaPacketsReceived}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_in:m.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_in:m.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_in:m.percentPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_in:m.KBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_in:m.deltaKBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_in:m.kbsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_in:T}},{ssrc:r,type:ne.VIDEO,value:{decoder_in:S}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_decode_frame_in:h.delta_ms_decode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_decoded_in:h.frames_decoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_decoded_in:h.total_decode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_sent_in:A.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_sent_in:A.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_sent_in:A.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_sent_in:A.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_in:C}}]}break}case Qt.OUTBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.OUTBOUND);_&&(_.timestamp=t.timestamp);const d=dt(r,o,$e.OUTBOUND);if(d&&(d.timestamp=o.timestamp),c[W.MEDIA_TYPE]===M.AUDIO){const h=c[W.CODEC_ID]||null,m=xd(c,M.AUDIO,_,d);return[{ssrc:r,type:ne.AUDIO,value:{codec_id_out:h}},{ssrc:r,type:ne.AUDIO,value:{total_packets_out:m.packetsSent}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_out:m.deltaPacketsSent}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_out:m.KBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_out:m.deltaKBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_out:m.kbsSent}}]}if(c[W.MEDIA_TYPE]===M.VIDEO){const h=c[W.ENCODER_IMPLEMENTATION]||null,m=c[W.CODEC_ID]||null,T=Cv(c,_),S=Pd(c),E=Iv(c),C=wv(c,_,d),A=xd(c,M.VIDEO,_,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_out:m}},{ssrc:r,type:ne.VIDEO,value:{total_packets_out:A.packetsSent}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_out:A.deltaPacketsSent}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_out:A.KBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_out:A.deltaKBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_out:A.kbsSent}},{ssrc:r,type:ne.VIDEO,value:{encoder_out:h}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_encode_frame_out:T.delta_ms_encode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_encoded_out:T.frames_encoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_encoded_out:T.total_encode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_received_out:C.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_received_out:C.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_received_out:C.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_received_out:C.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_out:S}},{ssrc:r,type:ne.VIDEO,value:{limitation_out:E}}]}break}case Qt.MEDIA_SOURCE:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);break}case Qt.TRACK:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);break}case Qt.CODEC:const s=[];return Object.keys(t[M.AUDIO]).forEach(r=>{const _=t[M.AUDIO][r];if(_.codec_id_in===c[W.ID]||_.codec_id_out===c[W.ID]){Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const d=Ov(c);c[W.ID]===_.codec_id_in?s.push({ssrc:_.ssrc,type:ne.AUDIO,value:{codec_in:d}}):s.push({ssrc:_.ssrc,type:ne.AUDIO,value:{codec_out:d}})}}),Object.keys(t[M.VIDEO]).forEach(r=>{const _=t[M.VIDEO][r];if(_.codec_id_in===c[W.ID]||_.codec_id_out===c[W.ID]){Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const d=Dv(c);c[W.ID]===_.codec_id_in?s.push({ssrc:_.ssrc,type:ne.VIDEO,value:{codec_in:d}}):s.push({ssrc:_.ssrc,type:ne.VIDEO,value:{codec_out:d}})}}),s;case Qt.REMOTE_INBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.OUTBOUND),d=dt(r,o,$e.OUTBOUND);if(c[W.KIND]===M.AUDIO){const h=Nd(c,M.AUDIO,d,_),m=Io(c,M.AUDIO,_),T=Ud(c,M.AUDIO,_,d);return[{ssrc:r,type:ne.AUDIO,value:{delta_rtt_ms_out:h.rtt}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_ms_out:h.totalRTT}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_measure_out:h.totalRTTMeasurements}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_out:m}},{ssrc:r,type:ne.AUDIO,value:{timestamp_out:c[W.TIMESTAMP]}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_out:T.fractionLost}}]}if(c[W.KIND]===M.VIDEO){const h=Nd(c,M.VIDEO,d,_),m=Io(c,M.VIDEO,_),T=Ud(c,M.VIDEO,_,d);return[{ssrc:r,type:ne.VIDEO,value:{delta_rtt_ms_out:h.rtt}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_ms_out:h.totalRTT}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_measure_out:h.totalRTTMeasurements}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_out:m}},{ssrc:r,type:ne.VIDEO,value:{timestamp_out:c[W.TIMESTAMP]}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_out:T.fractionLost}}]}break}}return[]},bo=c=>c<0?1:c>100?4.5:1+.035*c+7/1e6*c*(c-60)*(100-c),kv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.INBOUND),r=dt(a,n,$e.INBOUND),_=dt(a,o,$e.INBOUND),d=[],h=[],m=s[t].percent_packets_lost_in,T=s[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=_&&_[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=n&&n.data.delta_rtt_connectivity_ms||null,R=o&&o.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&h.push(T),n&&S&&h.push(S),o&&E&&h.push(E);const L=d.length>0?Ms(d):100,b=h.length>0?Ms(h):10,ie=93.2-m,N=.18*ie*ie-27.9*ie+1126.62,F=(L+b)/2,me=F-177.3<0?0:1,_e=.024*F+.11*(F-177.3)*me,U=N-_e;return bo(U)},Pv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.OUTBOUND),r=dt(a,n,$e.OUTBOUND),_=dt(a,o,$e.OUTBOUND),d=[],h=[],m=s[t].percent_packets_lost_out,T=s[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=_&&_[t].delta_rtt_ms_out||null,C=s[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=_&&_[t].delta_jitter_ms_out||null,L=c.data.delta_rtt_connectivity_ms,b=n&&n.data.delta_rtt_connectivity_ms||null,ie=o&&o.data.delta_rtt_connectivity_ms||null;T?d.push(T):L&&d.push(L),S?d.push(S):b&&d.push(b),E?d.push(E):ie&&d.push(ie),C&&h.push(C),n&&A&&h.push(A),o&&R&&h.push(R);const N=d.length>0?Ms(d):100,F=h.length>0?Ms(h):10,me=93.2-m,_e=.18*me*me-27.9*me+1126.62,U=(N+F)/2,x=U-177.3<0?0:1,q=.024*U+.11*(U-177.3)*x,j=_e-q;return bo(j)},Mv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.INBOUND),r=dt(a,n,$e.INBOUND),_=dt(a,o,$e.INBOUND),d=[],h=[],m=s[t].percent_packets_lost_in/100,T=s[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=_&&_[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=n&&n.data.delta_rtt_connectivity_ms||null,R=o&&o.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&h.push(T),r&&S&&h.push(S),_&&E&&h.push(E);const L=d.length>0?Ms(d):100,b=h.length>0?Ms(h):10,ie=0,N=19.8,F=29.7,me=30,_e=(L+b)/2+me,U=_e-177.3<0?0:1,x=.024*_e+.11*(_e-177.3)*U,j=93.2-(ie+N*Math.log(1+F*m)+x);return bo(j)},Lv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.OUTBOUND),r=dt(a,n,$e.OUTBOUND),_=dt(a,o,$e.OUTBOUND),d=[],h=[],m=s[t].percent_packets_lost_out/100,T=s[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=_&&_[t].delta_rtt_ms_out||null,C=s[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=_&&_[t].delta_jitter_ms_out||null,L=c.data.delta_rtt_connectivity_ms,b=n&&n.data.delta_rtt_connectivity_ms||null,ie=o&&o.data.delta_rtt_connectivity_ms||null;T?d.push(T):L&&d.push(L),S?d.push(S):b&&d.push(b),E?d.push(E):ie&&d.push(ie),C&&h.push(C),r&&A&&h.push(A),_&&R&&h.push(R);const N=d.length>0?Ms(d):100,F=h.length>0?Ms(h):10,me=0,_e=19.8,U=29.7,x=30,q=(N+F)/2+x,j=q-177.3<0?0:1,Y=.024*q+.11*(q-177.3)*j,X=93.2-(me+_e*Math.log(1+U*m)+Y);return bo(X)};class $v{constructor(t,n){this._callbacks={onreport:null,onticket:null},this._id=_v(),this._moduleName=this._id,this._probeId=n,this._config=t,this._exporter=new Sv(t),this._state=ys.IDLE,this.registerToPCEvents(),on(this._moduleName,`new collector created for probe ${this._probeId}`)}analyze(t,n,o,a){const s=(d,h)=>d===M.AUDIO?h===Qt.INBOUND_RTP?{...Rd}:{...Id}:h===Qt.INBOUND_RTP?{...bd}:{...wd},r=uv(n);r.pname=this._config.pname,r.call_id=this._config.cid,r.user_id=this._config.uid,r.count=n?n.count+1:1;let _=null;return t.forEach(d=>{!_&&d.timestamp&&(_=d.timestamp),Uv(d,r,r.pname,a).forEach(m=>{if(m.value&&m.type)if(m.ssrc){let T=r[m.type][m.ssrc];T||(T=s(m.type,d.type),T.ssrc=m.ssrc,r[m.type][m.ssrc]=T),Object.keys(m.value).forEach(S=>{T[S]=m.value[S]})}else Object.keys(m.value).forEach(T=>{r[m.type][T]=m.value[T]})})}),r.timestamp=_,Object.keys(r[M.AUDIO]).forEach(d=>{const h=r[M.AUDIO][d];h.direction===$e.INBOUND?(h.mos_emodel_in=kv(r,M.AUDIO,n,o,h.ssrc),h.mos_in=Mv(r,M.AUDIO,n,o,h.ssrc)):(h.mos_emodel_out=Pv(r,M.AUDIO,n,o,h.ssrc),h.mos_out=Lv(r,M.AUDIO,n,o,h.ssrc))}),r}async takeReferenceStats(){return new Promise((t,n)=>{const o=Date.now();setTimeout(async()=>{try{const a=Date.now()-o,s=Date.now(),r=await this._config.pc.getStats(),_=this.analyze(r,null,null,null),d=Date.now();_.experimental.time_to_measure_ms=d-s,_.experimental.time_to_wait_ms=a,this._exporter.saveReferenceReport(_),Ue(this._moduleName,`got reference report for probe ${this._probeId}`),t()}catch(a){n(a)}},this._config.startAfter)})}async collectStats(){try{if(this._state!==ys.RUNNING||!this._config.pc)return Ue(this._moduleName,`report discarded (too late) for probe ${this._probeId}`),null;const t=Date.now(),n=await this._config.pc.getStats(),o=this.analyze(n,this._exporter.getLastReport(),this._exporter.getBeforeLastReport(),this._exporter.getReferenceReport()),a=Date.now();return o.experimental.time_to_measure_ms=a-t,this._exporter.addReport(o),Ue(this._moduleName,`got report for probe ${this._probeId}#${this._exporter.getReportsNumber()+1}`),this.fireOnReport(o),o}catch(t){return jn(this._moduleName,`got error ${t}`),null}}async start(){Ue(this._moduleName,"starting"),this.state=ys.RUNNING,this._startedTime=this._exporter.start(),Ue(this._moduleName,"started")}async mute(){this.state=ys.MUTED,Ue(this._moduleName,"muted")}async unmute(){this.state=ys.RUNNING,Ue(this._moduleName,"unmuted")}async stop(t){if(Ue(this._moduleName,`stopping${t?" by watchdog":""}...`),this._stoppedTime=this._exporter.stop(),this.state=ys.IDLE,this._config.ticket){const{ticket:n}=this._exporter;this.fireOnTicket(n)}this._exporter.reset(),Ue(this._moduleName,"stopped")}registerCallback(t,n,o){t in this._callbacks?(this._callbacks[t]={callback:n,context:o},Ue(this._moduleName,`registered callback '${t}'`)):jn(this._moduleName,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):jn(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReport(t){this._callbacks.onreport&&Du(this._callbacks.onreport.callback,this._callbacks.onreport.context,t)}fireOnTicket(t){this._callbacks.onticket&&Du(this._callbacks.onticket.callback,this._callbacks.onticket.context,t)}updateConfig(t){this._config=t,this._exporter.updateConfig(t)}get state(){return this._state}set state(t){this._state=t,Ue(this._moduleName,`state changed to ${t}`)}addCustomEvent(t,n,o,a){this._exporter.addCustomEvent({at:typeof t=="object"?t.toJSON():t,category:n,name:o,description:a})}async registerToPCEvents(){const{pc:t}=this._config;if(navigator.mediaDevices.ondevicechange=async()=>{try{const n=await navigator.mediaDevices.enumerateDevices();this.addCustomEvent(new Date().toJSON(),"device",`${n.length} devices found`,"Media Devices state")}catch{jn(this._moduleName,"can't get devices")}},t){t.oniceconnectionstatechange=()=>{const o=t.iceConnectionState;o===ri.CONNECTED||o===ri.COMPLETED?this.addCustomEvent(new Date().toJSON(),"call",o,"ICE connection state"):o===ri.DISCONNECTED||o===ri.FAILED?this.addCustomEvent(new Date().toJSON(),"call",o,"ICE connection state"):o===ri.CLOSED&&this.addCustomEvent(new Date().toJSON(),"call","ended","ICE connection state")},t.onicegatheringstatechange=()=>{const o=t.iceGatheringState;this.addCustomEvent(new Date().toJSON(),"call",o,"ICE gathering state")},t.ontrack=o=>{this.addCustomEvent(new Date().toJSON(),"call",`${o.track.kind}track`,"MediaStreamTrack received")},t.onnegotiationneeded=()=>{this.addCustomEvent(new Date().toJSON(),"call","negotiation","Media changed")};const n=t.getReceivers();if(n&&n.length>0){const o=n[0],{transport:a}=o;if(a){const{iceTransport:s}=a;s&&(s.onselectedcandidatepairchange=()=>{this.addCustomEvent(new Date().toJSON(),"call","transport","Candidates Pair changed")})}}}}}class Hv{constructor(t){this._id=t.pname&&t.pname.substr(0,12).padEnd(12," ")||hv(),this._moduleName=this._id,on(this._moduleName,"probe created"),this._config=t,this._collector=new $v(this._config,this._id)}set onreport(t){t?this._collector.registerCallback("onreport",t):this._collector.unregisterCallback("onreport")}set onticket(t){t?this._collector.registerCallback("onticket",t):this._collector.unregisterCallback("onticket")}get id(){return this._id}get pname(){return this._config.pname}get cid(){return this._config.cid}get uid(){return this._config.uid}get state(){return this._collector.state}set state(t){this._collector.state=t}addCustomEvent(t,n,o,a=new Date().toJSON()){this._collector.addCustomEvent(a,n,t,o)}get isRunning(){return this._collector.state===ys.RUNNING}get isIdle(){return this._collector.state===ys.IDLE}updateUserId(t){this._config.uid=t,this._collector.updateConfig(this._config)}updateCallId(t){this._config.cid=t,this._collector.updateConfig(this._config)}start(){if(!this.isIdle){Ro(this._moduleName,"probe is already running");return}this._collector.start()}stop(t=!1){this.isRunning&&this._collector.stop(t)}async takeReferenceStats(){return this._collector.takeReferenceStats()}async collectStats(){return this._collector.collectStats()}}const bt="engine ";class Fv{constructor(t){this._config=t,this._probes=[],this._startedTime=null,this._callbacks={onresult:null},on(bt,`configured for probing every ${this._config.refreshEvery}ms`),on(bt,`configured for starting after ${this._config.startAfter}ms`),on(bt,`${!this._config.stopAfter||this._config.stopAfter!==-1?`configured for stopped after ${this._config.stopAfter}ms`:"configured for never stopped"}`),Ue(bt,"engine initialized")}get probes(){return this._probes}get isRunning(){return this._probes.some(t=>t.isRunning)}get isIdle(){return this._probes.every(t=>t.isIdle)}addNewProbe(t,n){if(!t)throw new Error("undefined peer connection");const o=fv(t,n,this._config),a=new Hv(o);return this._probes.push(a),Ue(bt,`${this._probes.length} probes registered`),a}removeExistingProbe(t){if(!t)throw new Error("undefined probe");t.state===ys.RUNNING&&t.stop(),this._probes=this._probes.filter(n=>t.id!==n.id)}async start(){const t=()=>{this._probes.forEach(s=>s.start())},n=async()=>Promise.all(this._probes.map(s=>s.takeReferenceStats())),o=()=>this.isIdle?!1:!this._config.stopAfter||this._config.stopAfter<0?!0:Date.now()<this._startedTime+this._config.stopAfter,a=async()=>{const s=av(),r=this._probes.filter(_=>_.isRunning);for(const _ of r){const d=await _.collectStats();d&&s.probes.push(d),Ue(bt,`got probe ${_.id}`),await Od(0)}return s.delta_time_to_measure_probes_ms=an(s.probes,"experimental","time_to_measure_ms"),s.delta_KBytes_in=an(s.probes,"data","delta_KBytes_in"),s.delta_KBytes_out=an(s.probes,"data","delta_KBytes_out"),s.delta_kbs_in=an(s.probes,"data","delta_kbs_in"),s.delta_kbs_out=an(s.probes,"data","delta_kbs_out"),s.total_time_decoded_in=an(s.probes,"video","total_time_decoded_in"),s.total_time_encoded_out=an(s.probes,"video","total_time_encoded_out"),s};for(Ue(bt,"starting to collect"),t(),Ue(bt,"generating reference reports..."),await n(),Ue(bt,"reference reports generated"),this._startedTime=Date.now();o();)if(Ue(bt,`wait ${this._config.refreshEvery}ms before collecting`),await Od(this._config.refreshEvery),o()){Ue(bt,"collecting...");const s=Date.now(),r=await a(),_=Date.now();r.delta_time_consumed_to_measure_ms=_-s,this.fireOnReports(r),Ue(bt,"collected")}Ue(bt,"reaching end of the collecting period..."),this.isRunning&&setTimeout(()=>{this.stop()},0)}stop(t){const n=o=>{this._probes.forEach(a=>{a.stop(o)})};on(bt,"stop collecting"),n(t)}registerCallback(t,n,o){t in this._callbacks?(this._callbacks[t]={callback:n,context:o},Ue(bt,`registered callback '${t}'`)):jn(bt,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):jn(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReports(t){this._callbacks.onresult&&t.probes.length>0&&Du(this._callbacks.onresult.callback,this._callbacks.onresult.context,t)}}const Vv="interface ";class jv{constructor(t){this._config=dv(t),on(Vv,`welcome to ${this._config.name} version ${this._config.version}`),ev(this._config.verbose||!1),this._engine=new Fv(this._config)}setupLogLevel(t){tv(t)}get version(){return this._config.version}get name(){return this._config.name}get probes(){return this._engine.probes}createProbe(t,n){return this._engine.addNewProbe(t,n)}startAllProbes(){this._engine.start()}stopAllProbes(){this._engine.stop()}get running(){return this._engine.isRunning}get idle(){return this._engine.isIdle}removeProbe(t){this._engine.removeExistingProbe(t)}set onresult(t){t?this._engine.registerCallback("onresult",t):this._engine.unregisterCallback("onresult")}}function qv(c,t){return Object.keys(c).filter(n=>t.includes(n)).reduce((n,o)=>{const a=o;return{...n,[a]:c[a]}},{})}const Bv=["mos_in","codec_in","delta_KBytes_in","delta_kbs_in","delta_jitter_ms_in","delta_packets_lost_in"],Gv={positiveSpeechThreshold:.6,negativeSpeechThreshold:.3,preSpeechPadMs:150,redemptionMs:1500,minSpeechMs:50};class Wv{constructor(t){this.intervals={},this.analysers={},this.emitInterval=t.emitInterval||200,this.onChangeFunction=t.onChangeFunction}async start(t,n,o){n&&n.getTracks().length&&await this.beginCalculation(t,n,o)}stop(t){this.clearVolumeInterval(t),this.analysers[t]&&typeof this.analysers[t].disconnect=="function"&&(this.analysers[t].disconnect(),delete this.analysers[t])}clearVolumeInterval(t){this.intervals[t]&&(clearInterval(this.intervals[t]),delete this.intervals[t])}clearAllIntervals(){Object.keys(this.intervals).forEach(t=>{this.stop(t)}),this.intervals={},this.analysers={}}async beginCalculation(t,n,o){this.clearVolumeInterval(o);const a=t.createAnalyser(),s=t.createMediaStreamSource(n);a.smoothingTimeConstant=.8,a.fftSize=1024,s.connect(a),this.analysers[o]=a,this.intervals[o]=setInterval(()=>{const r=new Uint8Array(a.frequencyBinCount);a.getByteFrequencyData(r);let _=0;const d=r.length;for(let m=0;m<d;m++)_+=r[m];const h=_/d;this.onChangeFunction(o,h)},this.emitInterval)}}class Kv{constructor(){this.resumePromise=null,this.context=new AudioContext,this.setupErrorHandling()}setupErrorHandling(){!this.context||typeof this.context.addEventListener!="function"||this.context.addEventListener("statechange",()=>{(this.context.state==="interrupted"||this.context.state==="closed")&&console.warn(`[ManagedAudioContext] AudioContext state changed to: ${this.context.state}`)})}createNewContext(){return console.log("[ManagedAudioContext] Creating new AudioContext instance"),this.context=new AudioContext,this.setupErrorHandling(),this.context}async getContext(){if(this.context.state==="closed")return console.warn("[ManagedAudioContext] AudioContext is closed, creating new instance"),this.createNewContext();if(this.context.state==="interrupted"){console.warn("[ManagedAudioContext] AudioContext is interrupted, attempting to resume");try{this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{console.error("[ManagedAudioContext] Failed to resume interrupted context:",t),this.resumePromise=null,this.createNewContext()})),await this.resumePromise}catch(t){return console.error("[ManagedAudioContext] Error resuming context, creating new one:",t),this.createNewContext()}}return this.context.state==="suspended"&&(this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{throw console.error("[ManagedAudioContext] Failed to resume suspended context:",t),this.resumePromise=null,t})),await this.resumePromise),this.context.state==="closed"?(console.warn("[ManagedAudioContext] Context closed after resume attempt, creating new instance"),this.createNewContext()):this.context}}const wo={SELECTED_INPUT_DEVICE:"OpensipsJSInputDevice",SELECTED_OUTPUT_DEVICE:"OpensipsJSOutputDevice"},Yv=0;function Nu(c,t){const n=new AudioContext,o=n.createMediaStreamSource(c),a=n.createMediaStreamSource(new MediaStream([t])),s=n.createMediaStreamDestination();return o.connect(s),a.connect(s),s.stream}class Jv{constructor(t){var n;this.isAutoAnswer=!1,this.muteWhenJoinEnabled=!1,this.isDNDEnabled=!1,this.isCallWaitingEnabled=!0,this.muted=!1,this.microphoneInputLevelValue=1,this.speakerVolumeValue=1,this.activeRooms={},this.activeCalls={},this.extendedCalls={},this.conferenceNodes={},this.availableMediaDevices=[],this.selectedMediaDevices={input:"default",output:"default"},this.callStatus={},this.callTime={},this.callMetrics={},this.timeIntervals={},this.metricConfig={refreshEvery:1e3},this.activeStreamValue=null,this.initialStreamValue=null,this.vadSession=null,this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.vadInterval=null,this.vadMrsInterval=null,this.ringbackTimers={},this.ringbackAudioContexts={},this.ringbackSessionProgressReceived={},this.hangupBeepContext=null,this.managedAudioContext=new Kv,this.context=t,this.context.on(this.context.newRTCSessionEventName,this.newRTCSessionCallback.bind(this)),this.VUMeter=new Wv({onChangeFunction:this.emitVolumeChange.bind(this)}),this.initializeMediaDevices(),this.processVADConfiguration(((n=this.context.options.configuration)==null?void 0:n.noiseReductionOptions)||{}),this.setupVADInstance()}setVADConfiguration(t){if(!this.MicVAD)throw new Error("VAD module is not provided in the initial configuration");const n=Object.keys(t);for(const o of n)this.noiseReduction[o]=t[o];this.hasActiveCalls&&this.roomReconfigure(this.currentActiveRoomId)}setupVADInstance(){var n,o;const t=(o=(n=this.context.options.configuration)==null?void 0:n.noiseReductionOptions)==null?void 0:o.vadModule;t&&t.MicVAD?(this.MicVAD=t.MicVAD,console.log("✅ VAD module loaded successfully")):this.noiseReduction.mode!=="disabled"&&(console.warn("⚠️ Noise reduction is enabled but VAD module is not provided. To use VAD features, please install @ricky0123/vad-web and pass it via configuration.noiseReductionOptions.vadModule option."),this.noiseReduction.mode="disabled")}processVADConfiguration(t){this.noiseReduction={mode:t.mode||"disabled",checkEveryMs:t.checkEveryMs||500,noiseCheckInterval:t.noiseCheckInterval||2e3,noiseThreshold:t.noiseThreshold||.004,vadConfig:t.vadConfig||{},baseAssetPath:t.baseAssetPath||"https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.28/dist/",onnxWASMBasePath:t.onnxWASMBasePath||"https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/"}}get sipOptions(){return{...this.context.options.sipOptions,mediaConstraints:this.getUserMediaConstraints}}get currentActiveRoomId(){return this.currentActiveRoomIdValue}set currentActiveRoomId(t){this.currentActiveRoomIdValue=t,this.context.emit("currentActiveRoomChanged",t)}get autoAnswer(){return this.isAutoAnswer}get callAddingInProgress(){return this.isCallAddingInProgress}set callAddingInProgress(t){this.isCallAddingInProgress=t,this.context.emit("callAddingInProgressChanged",t)}get muteWhenJoin(){return this.muteWhenJoinEnabled}get isDND(){return this.isDNDEnabled}get isCallWaiting(){return this.isCallWaitingEnabled}get speakerVolume(){return this.speakerVolumeValue}get microphoneInputLevel(){return this.microphoneInputLevelValue}get getActiveCalls(){return this.activeCalls}get hasActiveCalls(){return Object.values(this.extendedCalls).length>0}get hasActiveAnsweredCalls(){return Object.values(this.activeRooms).filter(o=>!o.incomingInProgress).length>0}get getActiveRooms(){return this.activeRooms}get isMuted(){return this.muted}get getInputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audioinput")}get getOutputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audiooutput")}get getUserMediaConstraints(){return Ed()?{video:!1,audio:!0}:{audio:{deviceId:{exact:this.selectedMediaDevices.input},echoCancellation:!0,echoCancellationType:"system",noiseSuppression:!0,autoGainControl:!0,sampleRate:48e3,latency:.01},video:!1}}get selectedInputDevice(){return this.selectedMediaDevices.input}get selectedOutputDevice(){return this.selectedMediaDevices.output}get activeStream(){return this.activeStreamValue}setAvailableMediaDevices(t){this.availableMediaDevices=t,this.context.emit("changeAvailableDeviceList",t)}async updateDeviceList(){await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);const t=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(t)}async initializeMediaDevices(){const t=localStorage.getItem(wo.SELECTED_INPUT_DEVICE)||"default",n=localStorage.getItem(wo.SELECTED_OUTPUT_DEVICE)||"default";try{const o=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints),a=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(a),await this.setMicrophone(t),await this.setSpeaker(n),navigator.mediaDevices.addEventListener("devicechange",async()=>{const s=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(s)}),o.getTracks().forEach(s=>s.stop())}catch(o){console.error(o)}}async cleanupConferenceNodes(t){const n=this.conferenceNodes[t];if(!n)return;let o=0;n.sources.forEach((r,_)=>{var d;try{r.disconnect(),o++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting source ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting source ${_}:`,h)}});let a=0;n.destinations.forEach((r,_)=>{var d;try{r.disconnect(),a++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting destination ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting destination ${_}:`,h)}});let s=0;n.gains.forEach((r,_)=>{var d;try{r.disconnect(),s++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting gain ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting gain ${_}:`,h)}}),delete this.conferenceNodes[t]}setCallTime(t){const n={...t};delete n.callId,this.callTime={...this.callTime,[t.callId]:n},this.context.emit("changeCallTime",this.callTime)}removeCallTime(t){const n={...this.callTime};delete n[t],this.callTime={...n},this.context.emit("changeCallTime",this.callTime)}setTimeInterval(t,n){this.timeIntervals={...this.timeIntervals,[t]:n}}removeTimeInterval(t){const n={...this.timeIntervals};n[t]&&(clearInterval(n[t]),delete n[t],this.timeIntervals={...n})}stopCallTimer(t){this.removeTimeInterval(t),this.removeCallTime(t)}emitVolumeChange(t,n){this.context.emit("changeCallVolume",{callId:t,volume:n})}getNoiseReductionMode(){return this.noiseReduction.mode}setMetricsConfig(t){this.metricConfig={...this.metricConfig,...t}}sendDTMF(t,n){if(!/^[A-D0-9*#]+$/g.test(n))throw new Error("Not allowed character used in the DTMF input");this.extendedCalls[t].sendDTMF(n)}setIsMuted(t){this.muted=t,this.context.emit("changeIsMuted",t)}processMute(t){const n=this.currentActiveRoomId;this.setIsMuted(t),this.initialStreamValue.getTracks().forEach(o=>o.enabled=!t),this.roomReconfigure(n)}mute(){this.processMute(!0)}unmute(){this.processMute(!1)}async processHold({callId:t,toHold:n,automatic:o}){const a=this.extendedCalls[t];if(!a)return;a._automaticHold=o??!1;const s=new Promise((r,_)=>{const d=setTimeout(()=>{_(new Error("Hold operation timeout"))},5e3),h=()=>{clearTimeout(d),a.putOnHoldTimestamp=n?Date.now():void 0,r()},m=T=>{clearTimeout(d),_(T)};try{n?(this.stopSessionVad(),a.hold({},h)):a.unhold({},h)}catch(T){m(T)}});try{await s,this.updateCall(a);const r=Object.values(this.extendedCalls).filter(_=>_.roomId===a.roomId&&(n?t!==_._id:!0));r.length>1&&await this.doConference(r)}catch(r){throw console.error("Hold operation failed:",r),r}}holdCall(t,n=!1){return this.processHold({callId:t,automatic:n,toHold:!0})}unholdCall(t){return this.processHold({callId:t,toHold:!1})}cancelAllOutgoingUnanswered(){Object.values(this.getActiveCalls).filter(t=>t.direction==="outgoing"&&t.status===Yv).forEach(t=>this.terminateCall(t._id))}answerCall(t){const n=this.extendedCalls[t];this.cancelAllOutgoingUnanswered(),n.answer(this.sipOptions),this.updateCall(n),this.setActiveRoom(n.roomId),n.connection.addEventListener("track",o=>{this.triggerAddStream(o,n)})}async moveCall(t,n){this.updateCallStatus({callId:t,isMoving:!0}),await this.processRoomChange({callId:t,roomId:n}),this.updateCallStatus({callId:t,isMoving:!1})}updateCall(t){this.activeCalls[t._id]=vd(t),this.context.emit("changeActiveCalls",this.activeCalls)}updateRoom(t){const o={...this.activeRooms[t.roomId],...t};this.activeRooms={...this.activeRooms,[t.roomId]:{...o}},this.context.emit("updateRoom",{room:o,roomList:this.activeRooms})}hasAutoAnswerHeaders(t){const n=/answer-after=0/,a=t.request.getHeader("Call-Info");return a&&n.test(a)}addCall(t,n=!0){this.activeCalls={...this.activeCalls,[t._id]:vd(t)},this.extendedCalls[t._id]=t,n&&this.context.emit("changeActiveCalls",this.activeCalls)}addCallStatus(t){this.callStatus={...this.callStatus,[t]:{isMoving:!1,isTransferring:!1,isMerging:!1,isTransferred:!1}},this.context.emit("changeCallStatus",this.callStatus)}updateCallStatus(t){const o={...{...this.callStatus[t.callId]}};t.isMoving!==void 0&&(o.isMoving=t.isMoving),t.isTransferring!==void 0&&(o.isTransferring=t.isTransferring),t.isMerging!==void 0&&(o.isMerging=t.isMerging),t.isTransferred!==void 0&&(o.isTransferred=t.isTransferred),this.callStatus={...this.callStatus,[t.callId]:{...o}},this.context.emit("changeCallStatus",this.callStatus)}removeCallStatus(t){const n={...this.callStatus};delete n[t],this.callStatus={...n},this.context.emit("changeCallStatus",this.callStatus)}addRoom(t){this.activeRooms={...this.activeRooms,[t.roomId]:t},this.context.emit("addRoom",{room:t,roomList:this.activeRooms})}async setupActiveStream(){const t=await Au(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);t.getTracks().forEach(n=>n.enabled=!this.isMuted),await this.setActiveStream(t)}async getActiveStream(){const t=await Au(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);return t.getTracks().forEach(n=>n.enabled=!this.isMuted),await this.setActiveStream(t),t}async setMicrophone(t){if(!this.getInputDeviceList.find(({deviceId:o})=>o===t)||(this.setSelectedInputDevice(t),Object.keys(this.getActiveCalls).length===0))return;await this.setupStream();const n=Object.values(this.extendedCalls).filter(o=>o.roomId===this.currentActiveRoomId);n.length===1?Object.values(n).forEach(async o=>{await this.setupActiveStream();const a=this.activeStream;o.connection.getSenders()[0].replaceTrack(a.getTracks()[0]),this.updateCall(o)}):await this.doConference(n)}async setActiveStream(t){this.activeStream&&this.stopVUMeter("origin"),await this.setupVUMeter(t,"origin"),this.activeStreamValue=t,this.context.emit("changeActiveStream",t)}async setSpeaker(t){if(!this.getOutputDeviceList.find(({deviceId:a})=>a===t))return;this.setSelectedOutputDevice(t);const n=Object.values(this.extendedCalls);if(n.length===0)return;const o=n.filter(a=>a.roomId===this.currentActiveRoomId);o.length===1?n.forEach(a=>{var s;(s=a.audioTag)==null||s.setSinkId(t),this.updateCall(a)}):await this.doConference(o)}removeRoom(t){const n={...this.activeRooms},o={...n[t]};delete n[t],this.activeRooms={...n},this.context.emit("removeRoom",{room:o,roomList:this.activeRooms})}deleteRoomIfEmpty(t){t!==void 0&&Object.values(this.extendedCalls).filter(n=>n.roomId===t).length===0&&(this.removeRoom(t),this.currentActiveRoomId===t&&(this.currentActiveRoomId=void 0))}checkInitialized(){if(!this.context.initialized)throw new Error("[OpenSIPSJS] You must call `start` method first!")}muteReconfigure(t){this.muted?t.mute({audio:!0}):t.unmute({audio:!0})}async startNoiseMonitor({stream:t,onNoiseDetected:n,onNoiseStop:o}){var h,m,T;let a;try{a=await this.managedAudioContext.getContext()}catch(S){console.error("[startNoiseMonitor] Failed to get AudioContext:",S),(h=this.context.logger)==null||h.error("[startNoiseMonitor] Failed to get AudioContext:",S);return}let s,r;try{s=a.createMediaStreamSource(t.clone()),r=a.createAnalyser()}catch(S){console.error("[startNoiseMonitor] Failed to create audio nodes:",S),console.error("[startNoiseMonitor] AudioContext state:",a.state),(m=this.context.logger)==null||m.error("[startNoiseMonitor] Failed to create audio nodes:",S),(T=this.context.logger)==null||T.error("[startNoiseMonitor] AudioContext state:",a.state);return}r.fftSize=1024;const _=new Float32Array(r.fftSize);s.connect(r);const d=[];this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadMrsInterval=setInterval(()=>{r.getFloatTimeDomainData(_);const S=zT(_);d.push(S);const E=Math.ceil(this.noiseReduction.noiseCheckInterval/this.noiseReduction.checkEveryMs);d.length>E&&d.shift()},this.noiseReduction.checkEveryMs),this.vadInterval=setInterval(()=>{var A;if(d.length===0)return;const S=d.reduce((R,L)=>R+L,0)/d.length,E=this.vadSessionState;if(!E){console.warn("[startNoiseMonitor] State not found, stopping interval"),(A=this.context.logger)==null||A.warn("[startNoiseMonitor] State not found, stopping interval"),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null);return}const C=S>this.noiseReduction.noiseThreshold;E.isSpeaking||(C&&E.currentMode==="clean"?(E.currentMode="noisy",console.log("Average noise high → enable VAD"),this.context.emit("changeNoiseReductionState",!0),n()):!C&&E.currentMode==="noisy"&&(E.currentMode="clean",console.log("Average noise low → disable VAD"),this.context.emit("changeNoiseReductionState",!1),o()))},this.noiseReduction.noiseCheckInterval)}async processVADForActiveStream(t={}){const n=this.activeStream;this.stopSessionVad(),this.vadSessionState={currentMode:"clean",isSpeaking:!1};const o=await this.managedAudioContext.getContext(),a=await XT(n,o,150);let s=!1;const r=Object.values(this.extendedCalls).filter(d=>d.roomId===this.currentActiveRoomId),_=await this.MicVAD.new({getStream:()=>new Promise(d=>d(n)),...Gv,...this.noiseReduction.vadConfig,baseAssetPath:this.noiseReduction.baseAssetPath,onnxWASMBasePath:this.noiseReduction.onnxWASMBasePath,onFrameProcessed:()=>{var d;if(!s){if(s=!0,console.log("✅ VAD initialized, starting background noise monitoring"),this.noiseReduction.mode==="enabled"){if(t&&Object.keys(t).length)Object.keys(t).forEach(h=>{const m=this.extendedCalls[h];if(m&&m.connection.getSenders()[0]){const T=Nu(a.stream,t[h]);m.connection.getSenders()[0].replaceTrack(T.getAudioTracks()[0])}});else{const h=r[0];h.connection.getSenders()[0]&&h.connection.getSenders()[0].replaceTrack(a.stream.getAudioTracks()[0])}return}if(!this.vadSessionState){console.error("[processVAD] CRITICAL: State not found"),(d=this.context.logger)==null||d.error("[processVAD] CRITICAL: State not found");return}this.startNoiseMonitor({stream:n,onNoiseDetected:async()=>{var h;if(console.log("[processVad] - Replace track with Vad Controlled"),(h=this.context.logger)==null||h.log("[processVad] - Replace track with Vad Controlled"),t&&Object.keys(t).length)Object.keys(t).forEach(m=>{const T=this.extendedCalls[m];if(T&&T.connection.getSenders()[0]){const S=Nu(a.stream,t[m]);T.connection.getSenders()[0].replaceTrack(S.getAudioTracks()[0])}});else{const m=r[0];m.connection.getSenders()[0]&&m.connection.getSenders()[0].replaceTrack(a.stream.getAudioTracks()[0])}},onNoiseStop:async()=>{if(console.log("Replace track with Original"),t&&Object.keys(t).length)Object.keys(t).forEach(h=>{const m=this.extendedCalls[h];if(!m)return;const T=m.connection.getSenders()[0];if(T&&T.track&&T.transport&&T.transport.state!=="closed"&&T.transport.state!=="failed"){const S=Nu(n,t[h]);T.replaceTrack(S.getAudioTracks()[0])}});else{const h=r[0].connection.getSenders()[0];h&&h.track&&h.transport&&h.transport.state!=="closed"&&h.transport.state!=="failed"&&h.replaceTrack(n.getAudioTracks()[0])}}})}},onSpeechStart:()=>{console.log("🎤 Speech started"),a.setSpeaking(!0),this.vadSessionState.isSpeaking=!0},onSpeechEnd:()=>{console.log("🛑 Speech end"),a.setSpeaking(!1),this.vadSessionState.isSpeaking=!1}});this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadSession=_,_.start()}stopSessionVad(){this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadSessionState&&(this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.context.emit("changeNoiseReductionState",!1))}async roomReconfigure(t){var a,s,r,_;if(t===void 0)return;const n=Object.values(this.extendedCalls).filter(d=>d.roomId===t),o=this.currentActiveRoomId===t;if(console.log("[roomReconfigure] - Calls In Room:",n),(a=this.context.logger)==null||a.log("[roomReconfigure] - Calls In Room:",n),n.forEach((d,h)=>{if(d.audioTag){d.connection.getReceivers().forEach(T=>{T.track.enabled=!d.localMuted}),o&&this.muteReconfigure(d);const m=!o;d.audioTag.muted=m,this.updateCall(d)}}),n.length===0){!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t),console.log("[roomReconfigure] - Delete empty room",t),(s=this.context.logger)==null||s.log("[roomReconfigure] - Delete empty room",t),this.deleteRoomIfEmpty(t);return}if(n.length===1&&!o){const d=n[0];d.isOnHold().local||await this.holdCall(d._id,!0),!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}if(n.length===1&&o){const d=n[0];d.isOnHold().local&&d._automaticHold&&await this.unholdCall(d._id);const T=(((r=d.connection)==null?void 0:r.getSenders())||[])[0];if(d.connection&&T)try{await this.setupActiveStream();const E=this.activeStream;["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[roomReconfigure] - Call processVAD from roomReconfigure"),(_=this.context.logger)==null||_.log("[roomReconfigure] - Call processVAD from roomReconfigure"),this.processVADForActiveStream());const C=E.getTracks();await T.replaceTrack(C[0]),this.muteReconfigure(d)}catch(E){console.error(E)}!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}n.length>1&&await this.doConference(n)}async doConference(t){var m,T,S,E,C,A,R,L;if(console.log("[doConference] - In doConference, sessions:",t),(m=this.context.logger)==null||m.log("[doConference] - In doConference, sessions:",t),t.length===0)return;const n=t[0].roomId,o=this.currentActiveRoomId===n;if(t.find(b=>b.roomId!==n))return;let s;try{s=await this.managedAudioContext.getContext()}catch(b){console.error("[doConference] Failed to get AudioContext:",b),(T=this.context.logger)==null||T.error("[doConference] Failed to get AudioContext:",b);return}const r=s.state;if(r!=="running")if(console.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),(S=this.context.logger)==null||S.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),r==="suspended"||r==="interrupted")try{await s.resume();const b=s.state;if(b!=="running"){console.error(`[doConference] Failed to resume AudioContext, state: ${b}`),(E=this.context.logger)==null||E.error(`[doConference] Failed to resume AudioContext, state: ${b}`);return}}catch(b){console.error("[doConference] Error resuming AudioContext:",b),(C=this.context.logger)==null||C.error("[doConference] Error resuming AudioContext:",b);return}else if(r==="closed"){console.error("[doConference] AudioContext is closed, cannot proceed"),(A=this.context.logger)==null||A.error("[doConference] AudioContext is closed, cannot proceed");return}else return;await this.cleanupConferenceNodes(n),this.conferenceNodes[n]={sources:new Map,destinations:new Map,gains:new Map};const _=this.conferenceNodes[n],d=new Map;console.log("[doConference] - Before sessions forEach, sessions:",t),(R=this.context.logger)==null||R.log("[doConference] - Before sessions forEach, sessions:",t),t.forEach((b,ie)=>{var N,F,me;if(console.log("[doConference] - In sessions forEach, iteration for",b._id),(N=this.context.logger)==null||N.log("[doConference] - In sessions forEach, iteration for",b._id),b&&b.connection){const _e=b.connection.getReceivers();console.log("[doConference] - Receivers list length for",b._id,_e.length),(F=this.context.logger)==null||F.log("[doConference] - Receivers list length for",b._id,_e.length),_e.forEach((U,x)=>{var Y,V,X,k,P,B;U.track.enabled=!b.localMuted;const q=(Y=U.track)==null?void 0:Y.id;(V=U.track)==null||V.readyState,(X=U.track)==null||X.kind;const j=`${b._id}-${q}`;console.log("[doConference] - Gathering receiver tracks",b._id),console.log("[doConference] - Receiver track readyState",U.track.readyState),(k=this.context.logger)==null||k.log("[doConference] - Gathering receiver tracks",b._id),(P=this.context.logger)==null||P.log("[doConference] - Receiver track readyState",U.track.readyState),U.track&&U.track.readyState==="live"&&(console.log("[doConference] - Gathered receiver track",b._id),(B=this.context.logger)==null||B.log("[doConference] - Gathered receiver track",b._id),d.set(j,U.track))})}else console.log("[doConference] - No session or RTC connection, session:",b),(me=this.context.logger)==null||me.log("[doConference] - No session or RTC connection, session:",b)}),await this.setupActiveStream();const h={};await QT.forEach(t,async(b,ie)=>{var Y,V,X,k,P;if(!b||!b.connection){console.log("[doConference] - Return because of no session or connection, session:",b),(Y=this.context.logger)==null||Y.log("[doConference] - Return because of no session or connection, session:",b);return}const N=s.createMediaStreamDestination(),F=s.createMediaStreamDestination();_.destinations.set(b._id,N),_.destinations.set(`${b._id}-others`,F);const me=b.connection.getReceivers(),_e=me.length>0;console.log(`[doConference] Session ${b._id} has ${me.length} receivers`),(V=this.context.logger)==null||V.log(`[doConference] Session ${b._id} has ${me.length} receivers`),_e||(console.warn(`[doConference] Session ${b._id} has no receivers yet. Will re-configure when track arrives.`),(X=this.context.logger)==null||X.warn(`[doConference] Session ${b._id} has no receivers yet. Will re-configure when track arrives.`)),d.forEach((B,je)=>{var Q,K,G;if(console.log("[doConference] - In forEach receiverTracks for",b._id),(Q=this.context.logger)==null||Q.log("[doConference] - In forEach receiverTracks for",b._id),!je.startsWith(b._id)){if(!B||B.readyState!=="live"){console.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${b._id}`),(K=this.context.logger)==null||K.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${b._id}`);return}try{const re=s.createMediaStreamSource(new MediaStream([B])),pe=s.createGain(),Ie=`${b._id}-${je}`;re.connect(pe),pe.connect(N),pe.connect(F),console.log("[doConference] - In forEach connect track for",b._id),(G=this.context.logger)==null||G.log("[doConference] - In forEach connect track for",b._id),_.sources.set(Ie,re),_.gains.set(Ie,pe)}catch(re){console.error(re)}}});const U=F.stream.getTracks();if(h[b._id]=U[0],o&&this.activeStreamValue)try{const B=this.activeStream,je=s.createMediaStreamSource(B),Q=s.createGain(),K=`${b._id}-local`;je.connect(Q),Q.connect(N),_.sources.set(K,je),_.gains.set(K,Q)}catch(B){console.error(B)}else o&&(console.error(`Host room but no activeStreamValue - skipping host microphone for session ${b._id}`),(k=this.context.logger)==null||k.error(`Host room but no activeStreamValue - skipping host microphone for session ${b._id}`));const q=b.connection.getSenders()[0],j=N.stream.getTracks();if(q&&j[0])try{console.log("[doConference] - Final replaceTrack for",b._id),(P=this.context.logger)==null||P.log("[doConference] - Final replaceTrack for",b._id),console.log("RIGHT 2 initial replace for ",b._id),await q.replaceTrack(j[0]),this.muteReconfigure(b)}catch(B){console.error(B)}}),["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[doConference] - Call processVAD from doConference"),(L=this.context.logger)==null||L.log("[doConference] - Call processVAD from doConference"),this.processVADForActiveStream(h))}processCallerMute(t,n){const o=this.extendedCalls[t];o&&o.connection.getReceivers().length&&(o.localMuted=n,o.connection.getReceivers().forEach(a=>{a.track.enabled=!n}),this.updateCall(o))}muteCaller(t){this.processCallerMute(t,!0)}unmuteCaller(t){this.processCallerMute(t,!1)}terminateCall(t){const n=this.extendedCalls[t];n._status===4?n.terminate({status_code:603,reason_phrase:"Decline"}):n._status!==8&&n.terminate()}handleSipResponseForRingback(t,n){var s,r,_,d,h,m;let o=null;if(this.extendedCalls[t])o=t;else{const T=Object.values(this.extendedCalls).find(S=>S.id===t||S._id===t||S.id&&S.id.includes(t)||S._id&&S._id.includes(t));T&&(o=T.id)}if(!o){(s=this.context.logger)==null||s.warn(`[handleSipResponseForRingback] Could not find session for identifier ${t}, status ${n}`);return}const a=this.extendedCalls[o];if(!a){(r=this.context.logger)==null||r.warn(`[handleSipResponseForRingback] Call not found in extendedCalls for ${o}`);return}if(a.direction==="outgoing"){if(a._is_confirmed){(_=this.context.logger)==null||_.log(`[handleSipResponseForRingback] Call ${o} is already confirmed, skipping ringback tone`);return}if(n===Ao.TRYING||n===Ao.RINGING){if(this.ringbackTimers[o])return;this.ringbackSessionProgressReceived[o]=!1,this.ringbackTimers[o]=setTimeout(()=>{var S,E;const T=this.extendedCalls[o];T&&!T._is_confirmed&&!this.ringbackSessionProgressReceived[o]?(this.startLocalRingbackTone(o),(S=this.context.logger)==null||S.log(`[handleSipResponseForRingback] Started local ringback tone for call ${o} after 2 seconds without 183`)):T&&T._is_confirmed&&((E=this.context.logger)==null||E.log(`[handleSipResponseForRingback] Call ${o} was confirmed during 2-second wait, skipping ringback tone`)),delete this.ringbackTimers[o]},2e3),(d=this.context.logger)==null||d.log(`[handleSipResponseForRingback] Started 2-second timer for call ${o} after receiving ${n}`)}n===Ao.SESSION_PROGRESS&&(this.ringbackSessionProgressReceived[o]=!0,this.ringbackTimers[o]&&(clearTimeout(this.ringbackTimers[o]),delete this.ringbackTimers[o],(h=this.context.logger)==null||h.log(`[handleSipResponseForRingback] Cancelled ringback timer for call ${o} - 183 received`)),this.stopLocalRingbackTone(o),(m=this.context.logger)==null||m.log(`[handleSipResponseForRingback] Stopped local ringback tone for call ${o} - 183 received with SDP`))}}async startLocalRingbackTone(t){var n,o;if(!this.ringbackAudioContexts[t])try{const a=await this.managedAudioContext.getContext(),s=a.createOscillator(),r=a.createOscillator(),_=a.createGain();s.frequency.value=440,r.frequency.value=480,s.type="sine",r.type="sine",_.gain.value=0,s.connect(_),r.connect(_),_.connect(a.destination),s.start(),r.start();const d={context:a,oscillator1:s,oscillator2:r,gainNode:_,intervalId:null};this.ringbackAudioContexts[t]=d;const h=()=>{if(!this.ringbackAudioContexts[t])return;const T=a.currentTime;_.gain.cancelScheduledValues(T),_.gain.setValueAtTime(0,T),_.gain.linearRampToValueAtTime(.3,T+.05),_.gain.linearRampToValueAtTime(0,T+1)};h();const m=setInterval(()=>{if(!this.ringbackAudioContexts[t]){clearInterval(m);return}h()},4e3);d.intervalId=m,this.ringbackAudioContexts[t]=d,(n=this.context.logger)==null||n.log(`[startLocalRingbackTone] Started ringback tone for session ${t}`)}catch(a){(o=this.context.logger)==null||o.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a),console.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a)}}stopLocalRingbackTone(t){var o,a;const n=this.ringbackAudioContexts[t];if(n)try{n.intervalId&&clearInterval(n.intervalId),n.oscillator1&&n.oscillator1.stop(),n.oscillator2&&n.oscillator2.stop(),n.gainNode&&n.gainNode.disconnect(),delete this.ringbackAudioContexts[t],(o=this.context.logger)==null||o.log(`[stopLocalRingbackTone] Stopped ringback tone for session ${t}`)}catch(s){(a=this.context.logger)==null||a.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,s),console.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,s),delete this.ringbackAudioContexts[t]}}cleanupRingbackTone(t){this.ringbackTimers[t]&&(clearTimeout(this.ringbackTimers[t]),delete this.ringbackTimers[t]),this.stopLocalRingbackTone(t),delete this.ringbackSessionProgressReceived[t]}async playHangupBeep(){var t,n;if(!this.hangupBeepContext)try{const o=await this.managedAudioContext.getContext(),a=o.createOscillator(),s=o.createGain();a.frequency.value=800,a.type="sine",s.gain.value=0,a.connect(s),s.connect(o.destination),this.hangupBeepContext={context:o,oscillator:a,gainNode:s},a.start();const r=o.currentTime;s.gain.setValueAtTime(0,r),s.gain.linearRampToValueAtTime(.3,r+.01),s.gain.setValueAtTime(.3,r+.15),s.gain.linearRampToValueAtTime(0,r+.2),a.stop(r+.2),setTimeout(()=>{if(this.hangupBeepContext){try{this.hangupBeepContext.oscillator&&this.hangupBeepContext.oscillator.disconnect(),this.hangupBeepContext.gainNode&&this.hangupBeepContext.gainNode.disconnect()}catch(_){console.error("[playHangupBeep] Cleanup playing hangup beep error:",_)}this.hangupBeepContext=null}},250),(t=this.context.logger)==null||t.log("[playHangupBeep] Played hangup beep")}catch(o){(n=this.context.logger)==null||n.error("[playHangupBeep] Error playing hangup beep:",o),console.error("[playHangupBeep] Error playing hangup beep:",o),this.hangupBeepContext=null}}transferCall(t,n){if(n.toString().length===0)return new Error("Target must be passed");const o=this.extendedCalls[t];if(!o._is_confirmed&&!o._is_canceled){const a=`sip:${n}@${this.context.sipDomain}`;o.terminate({status_code:302,reason_phrase:"Moved Temporarily",extraHeaders:[`Contact: ${a}`]});return}this.updateCallStatus({callId:t,isTransferring:!0,isTransferred:!1}),o.refer(`sip:${n}@${this.context.sipDomain}`,{eventHandlers:{requestSucceeded:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!0})},requestFailed:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!1})}}}),this.updateCall(o)}mergeCall(t){const n=Object.values(this.extendedCalls).filter(s=>s.roomId===t);if(n.length!==2)return;const o=n[0],a=n[1];!o||!a||(this.updateCallStatus({callId:o._id,isMerging:!0}),this.updateCallStatus({callId:a._id,isMerging:!0}),o.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(o))}mergeCallByIds(t,n){const o=Object.values(this.extendedCalls).find(s=>s._id===t),a=Object.values(this.extendedCalls).find(s=>s._id===n);if(!o||!a)throw new Error("Call ID is not provided");this.updateCallStatus({callId:t,isMerging:!0}),this.updateCallStatus({callId:n,isMerging:!0}),o.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(o)}setDND(t){this.isDNDEnabled=t,this.context.emit("changeIsDND",t)}setCallWaiting(t){this.isCallWaitingEnabled=t,this.context.emit("changeIsCallWaiting",t)}startCallTimer(t){this.removeTimeInterval(t);const n={callId:t,hours:0,minutes:0,seconds:0,formatted:""};this.setCallTime(n);const o=setInterval(()=>{const a={...this.callTime[t]},s=JT(a);this.setCallTime({callId:t,...s})},1e3);this.setTimeInterval(t,o)}async setActiveRoom(t){const n=this.currentActiveRoomId;t!==n&&(this.currentActiveRoomId=t,await this.roomReconfigure(n),await this.roomReconfigure(t))}getNewRoomId(){const t=Object.keys(this.activeRooms);return t.length===0?1:parseInt(t.sort()[t.length-1])+1}async setupCall(t){var h,m;const n=t.session;if(this.getActiveCalls[n.id]!==void 0)return;const a=this.getNewRoomId(),s={started:new Date,incomingInProgress:!1,roomId:a};if(n.direction==="incoming")this.context.logger.log("New incoming call from",(m=(h=n._remote_identity)==null?void 0:h._uri)==null?void 0:m._user),s.incomingInProgress=!0,this.context.subscribe(Xt.CALL_CONFIRMED,T=>{n.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.startCallTimer(n.id))}),this.context.subscribe(Xt.CALL_FAILED,T=>{n.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.deleteRoomIfEmpty(a))});else if(n.direction==="outgoing"){const T=S=>{var R,L,b,ie,N,F,me,_e,U;const E=!!((R=S==null?void 0:S.response)!=null&&R.body),C=(b=(L=S==null?void 0:S.response)==null?void 0:L.getHeader)==null?void 0:b.call(L,"Content-Type"),A=(N=(ie=S==null?void 0:S.response)==null?void 0:ie.getHeader)==null?void 0:N.call(ie,"Content-Length");console.log("PPP SDP Check:",{hasBody:E,contentType:C,contentLength:A,bodyLength:((me=(F=S==null?void 0:S.response)==null?void 0:F.body)==null?void 0:me.length)||0,bodyPreview:((U=(_e=S==null?void 0:S.response)==null?void 0:_e.body)==null?void 0:U.substring(0,100))||"N/A"}),S.response&&S.response.status_code===Ao.SESSION_PROGRESS&&(this.startCallTimer(n.id),n.off("progress",T))};n.on("progress",T),n.once("confirmed",()=>{this.startCallTimer(n.id)})}const r=n,_=this.hasAutoAnswerHeaders(t),d=r.direction==="incoming"&&!this.hasActiveCalls&&(_||this.autoAnswer);r.roomId=a,r.localMuted=!1,r.autoAnswer=d,d?this.addCall(r,!1):this.addCall(r),this.addCallStatus(n.id),this.addRoom(s),d&&this.answerCall(r._id)}removeCall(t){const n={...this.activeCalls};delete n[t],this.activeCalls={...n};const o={...this.extendedCalls};delete o[t],this.extendedCalls={...o},this.context.emit("changeActiveCalls",this.activeCalls)}activeCallListRemove(t){const n=this.extendedCalls[t._id];if(!n)return;this.stopVUMeter("origin"),this.stopVUMeter(t._id);const o=n.roomId;this.removeCall(t._id),this.roomReconfigure(o).then(()=>{}).catch(a=>{console.error("Error reconfiguring room after call removal:",a)})}shouldTerminateNewSession(t){if(t.session.direction==="outgoing")return!1;const o=!this.isCallWaiting&&this.hasActiveCalls;return this.isDND||o}async newRTCSessionCallback(t){const n=t.session;if(this.shouldTerminateNewSession(t)){n.terminate({status_code:486,reason_phrase:"Do Not Disturb"});return}this.context.triggerListener({listenerType:Xt.NEW_CALL,session:n,event:t}),n.on("ended",a=>{var r,_,d;if(this.stopVUMeter(n.id),this.context.logger.log("Session ended for",(_=(r=n._remote_identity)==null?void 0:r._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_ENDED,session:n,event:a}),n._is_confirmed&&this.playHangupBeep(),n.connection){const h=n.connection.connectionState;(h==="closed"||h==="disconnected")&&this.context.emit("connectionStateChange",{session:n,connectionState:h})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(n.id);const s=this.getActiveCalls[n.id];s&&this.activeCallListRemove(s),this.stopCallTimer(n.id),this.removeCallStatus(n.id),this.removeCallMetrics(n.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(d=this.initialStreamValue)==null||d.getTracks().forEach(h=>h.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),n.on("progress",a=>{var s,r;this.context.logger.log("Session in progress for",(r=(s=n._remote_identity)==null?void 0:s._uri)==null?void 0:r._user),this.context.triggerListener({listenerType:Xt.CALL_PROGRESS,session:n,event:a})}),n.on("failed",a=>{var r,_,d;if(this.stopVUMeter(n.id),this.context.logger.log("Session failed for",(_=(r=n._remote_identity)==null?void 0:r._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_FAILED,session:n,event:a}),n.connection){const h=n.connection.connectionState;(h==="closed"||h==="disconnected")&&this.context.emit("connectionStateChange",{session:n,connectionState:h})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(n.id),n.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0);const s=this.getActiveCalls[n.id];s&&this.activeCallListRemove(s),this.stopCallTimer(n.id),this.removeCallStatus(n.id),this.removeCallMetrics(n.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(d=this.initialStreamValue)==null||d.getTracks().forEach(h=>h.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),n.on("confirmed",a=>{var s,r;this.context.logger.log("Session confirmed for",(r=(s=n._remote_identity)==null?void 0:s._uri)==null?void 0:r._user),this.context.triggerListener({listenerType:Xt.CALL_CONFIRMED,session:n,event:a}),this.updateCall(n),this.cleanupRingbackTone(n.id),n.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0)});const o=a=>{a&&a.addEventListener("connectionstatechange",s=>{this.context.emit("connectionStateChange",{session:n,connectionState:a.connectionState})})};if(n.connection&&o(n.connection),n.on("peerconnection",({peerconnection:a})=>{o(a)}),await this.setupCall(t),n.direction==="outgoing"){const a=this.getActiveCalls[n.id].roomId;await this.setActiveRoom(a)}}setMuteWhenJoin(t){this.muteWhenJoinEnabled=t,this.context.emit("changeMuteWhenJoin",t)}setMicrophoneSensitivity(t){if(t<0||t>1)throw new Error("Value should be in range from 0 to 1!");this.microphoneInputLevelValue=t,this.roomReconfigure(this.currentActiveRoomId)}setSpeakerVolume(t){this.speakerVolumeValue=t,Object.values(this.extendedCalls).forEach(n=>{n.audioTag&&(n.audioTag.volume=t,this.updateCall(n))})}setAutoAnswer(t){this.isAutoAnswer=t}setSelectedInputDevice(t){localStorage.setItem(wo.SELECTED_INPUT_DEVICE,t),this.selectedMediaDevices.input=t,this.context.emit("changeActiveInputMediaDevice",t)}setSelectedOutputDevice(t){localStorage.setItem(wo.SELECTED_OUTPUT_DEVICE,t),this.selectedMediaDevices.output=t,this.context.emit("changeActiveOutputMediaDevice",t)}setCallMetrics(t){const n={...t};delete n.callId,this.callMetrics={...this.callMetrics,[t.callId]:n},this.context.emit("changeCallMetrics",this.callMetrics)}removeCallMetrics(t){const n={...this.callMetrics};delete n[t],this.callMetrics={...n},this.context.emit("changeCallMetrics",this.callMetrics)}getCallQuality(t){const n=new jv(this.metricConfig),o=n.createProbe(t.connection,{cid:t._id}),a=[];let s;o.onreport=r=>{Object.entries(r.audio).forEach(([h,m])=>{m.direction==="inbound"&&!a.includes(h)&&(a.push(h),s=h)});const _=r.audio[s];if(!_)return;const d=qv(_,Bv);d.callId=t._id,this.setCallMetrics(d)},this.context.subscribe(Xt.CALL_ENDED,r=>{r._id===t._id&&n.stopAllProbes()}),n.startAllProbes()}async setupVUMeter(t,n){await this.VUMeter.start(await this.managedAudioContext.getContext(),t,n)}stopVUMeter(t){this.VUMeter.stop(t)}async setupStream(){try{const t=Date.now(),n=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);this.initialStreamValue&&(this.initialStreamValue.getTracks().forEach((a,s)=>{a.stop()}),this.initialStreamValue=null),this.initialStreamValue=n}catch(t){throw t}}async triggerAddStream(t,n){var S,E;console.log(`[triggerAddStream] - For ${n._id}`),(S=this.context.logger)==null||S.log(`[triggerAddStream] - For ${n._id}`);const o=this.muteWhenJoin||this.isMuted;this.setIsMuted(o),this.initialStreamValue||await this.setupStream();const a=await this.managedAudioContext.getContext(),s=await Au(a,this.initialStreamValue,this.microphoneInputLevel*2),r=this.isMuted||this.muteWhenJoin;s.getTracks().forEach(C=>{C.enabled=!r}),await this.setActiveStream(s),await n.connection.getSenders()[0].replaceTrack(s.getTracks()[0]);const h=new MediaStream([t.track]);!Object.values(this.extendedCalls).find(C=>C.audioTag&&C.audioTag.id===n._id)&&kT(h,n,this.selectedOutputDevice,this.speakerVolume);const T=n.roomId===this.currentActiveRoomId;n.audioTag&&(n.audioTag.muted=!T),await this.setupVUMeter(h,n._id),this.getCallQuality(n),this.updateCall(n),n.roomId!==void 0&&Object.values(this.extendedCalls).filter(A=>A.roomId===n.roomId).length>1&&(console.log(`[triggerAddStream] Re-configuring conference for room ${n.roomId} - track received for call ${n._id}`),(E=this.context.logger)==null||E.log(`[triggerAddStream] Re-configuring conference for room ${n.roomId} - track received for call ${n._id}`),setTimeout(()=>{this.roomReconfigure(n.roomId)},100)),["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.processVADForActiveStream()}initCall(t,n,o=!1){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`);const a=this.context.call(`sip:${t}@${this.context.sipDomain}`,this.sipOptions);if(this.callAddingInProgress=a.id,n&&this.currentActiveRoomId!==void 0&&(this.processRoomChange({callId:a.id,roomId:this.currentActiveRoomId}),o)){const s=Object.values(this.extendedCalls).filter(r=>r.roomId===this.currentActiveRoomId&&r._id!==a.id);for(const r of s)this.holdCall(r._id,!0)}a.connection.addEventListener("track",s=>{this.triggerAddStream(s,a)})}async processRoomChange({callId:t,roomId:n}){const o=this.extendedCalls[t];if(!o)return;const a=o.roomId;o.roomId=n,this.updateCall(o),await this.roomReconfigure(a),await this.roomReconfigure(n)}}class zv{constructor(t){this.context=t}get sipOptions(){return{...this.context.options.sipOptions}}initCall(t,n){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`),this.context.joinVideoCall(`sip:${t}@${this.context.sipDomain}`,n,this.sipOptions)}stop(t={}){this.context.terminateJanusSessions(t)}startAudio(){this.context.enableJanusAudio(!0)}stopAudio(){this.context.enableJanusAudio(!1)}startVideo(){this.context.enableJanusVideo(!0)}stopVideo(){this.context.enableJanusVideo(!1)}changeMediaConstraints(t){this.context.changeMediaConstraints(t)}startScreenShare(){this.context.startScreenShare()}startBlur(){this.context.startBlur()}stopBlur(){this.context.stopBlur()}}class Xv{constructor(t){this.activeMessages={},this.extendedMessages={},this.msrpHistory={},this.context=t,this.context.on(this.context.newMSRPSessionEventName,this.newMSRPSessionCallback.bind(this))}get isMSRPInitializing(){return this.isMSRPInitializingValue}get getActiveMessages(){return this.activeMessages}msrpAnswer(t){const n=this.extendedMessages[t];this.updateMSRPSession(n)}updateMSRPSession(t){this.activeMessages[t._id]=Sd(t),this.context.emit("changeActiveMessages",this.activeMessages)}addMMSRPSession(t){this.activeMessages={...this.activeMessages,[t._id]:Sd(t)},this.extendedMessages[t._id]=t,this.context.emit("changeActiveMessages",this.activeMessages)}addMSRPMessage(t,n){const o=this.msrpHistory[n.id]||[];o.push(t),this.msrpHistory={...this.msrpHistory,[n.id]:[...o]},this.context.emit("newMSRPMessage",{message:t,session:n})}messageTerminate(t){const n=this.extendedMessages[t];n._status!==8&&n.terminate()}addMessageSession(t){if(!t._id||this.getActiveMessages[t._id]!==void 0)return;const o=t;this.addMMSRPSession(o)}triggerMSRPListener({listenerType:t,session:n,event:o}){const a=this.context.listenersList[t];!a||!a.length||a.forEach(s=>{s(n,o)})}removeMMSRPSession(t){const n={...this.activeMessages};delete n[t],this.activeMessages={...n};const o={...this.extendedMessages};delete o[t],this.extendedMessages={...o},this.context.emit("changeActiveMessages",this.activeMessages)}activeMessageListRemove(t){this.removeMMSRPSession(t._id)}newMSRPSessionCallback(t){t.session._id||(t.session._id=t.request.call_id+t.request.from._parameters.tag);const n=t.session;n.on("ended",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_ENDED,session:n,event:o});const a=this.getActiveMessages[n.id];this.activeMessageListRemove(a)}),n.on("failed",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_FAILED,session:n,event:o});const a=this.getActiveMessages[n.id];this.activeMessageListRemove(a)}),n.on("confirmed",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_CONFIRMED,session:n,event:o}),this.updateMSRPSession(n)}),n.on("newMessage",o=>{this.addMSRPMessage(o,n)}),this.addMessageSession(n)}setIsMSRPInitializing(t){this.isMSRPInitializingValue=t,this.context.emit("isMSRPInitializingChanged",t)}initMSRP(t,n,o){if(t.length===0)return console.error("Target must be a valid string");const a=this.context.startMSRP(t,o);a.on("active",()=>{this.addMessageSession(a),a.sendMSRP(n),this.setIsMSRPInitializing(!1)}),this.setIsMSRPInitializing(!0)}sendMSRP(t,n){const o=this.extendedMessages[t];if(!o)throw new Error(`MSRP session with id ${t} doesn't exist!`);o.sendMSRP(n)}}const Oo={AUDIO:"audio",VIDEO:"video",MSRP:"msrp"};class Md{constructor(t){this.opensips=null,this.session=null,this.name=null,this.name=t}setOpensips(t){this.opensips=t}setSession(t){this.session=t}kill(){this.opensips.kill(this.name)}}class Ld extends Md{constructor(t,n){super(t),this._candidates=[],this._subscribeSent=!1,this._configureSent=!1,this._lastTrickleReceived=!1,this.type=n}connect(t={}){this.opaqueId=this.session.generateOpaqueId();const n=ke.cloneArray(t.extraHeaders),o={from_tag:this.session._from_tag};t.fromUserName&&(o.from_uri=new ln("sip",t.fromUserName,this.session._ua.configuration.uri.host),n.push(`P-Preferred-Identity: ${this.session._ua.configuration.uri.toString()}`)),t.fromDisplayName&&(o.from_display_name=t.fromDisplayName),n.push(`Contact: ${this.session._contact}`),n.push("Content-Type: application/json"),this.session._sessionTimers.enabled&&n.push(`Session-Expires: ${this.session._sessionTimers.defaultExpires}${this.session._ua.configuration.session_timers_force_refresher?";refresher=uac":""}`),this._request=new Tt.InitialOutgoingInviteRequest(this.session.target,this.session._ua,o,n),this._createRTCConnection(),this._sendInitialRequest()}getStream(){return this.stream}getConnection(){return this._connection}_createRTCConnection(){this._connection=new RTCPeerConnection({iceServers:[{urls:"stun:turn.voicenter.co",credential:"kxsjahnsdjns3eds23esd",username:"turn2es21e"}]});let t;this._connection.onicecandidate=n=>{this._connection.signalingState!=="stable"&&this._connection.signalingState!=="have-local-offer"||n.candidate&&(this._candidates.push(n.candidate),clearTimeout(t),t=setTimeout(()=>{this._lastTrickleReceived=!0,this._subscribeSent&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})},500))}}addTracks(t){t.forEach(n=>{this._connection.addTrack(n)})}async _sendInitialRequest(){const t=new Wr(this.session._ua,this._request,{onRequestTimeout:()=>{this.session.onRequestTimeout()},onTransportError:()=>{this.session.onTransportError()},onAuthenticated:s=>{this._request=s},onReceiveResponse:s=>{this._receiveInviteResponse(s)}});if(await this.generateStream(),!this.stream||!this.stream.getTracks().length)return;this.addTracks(this.stream.getTracks());const n={audio:!1,video:!0};this.jsep_offer=await this._connection.createOffer(n),await this._connection.setLocalDescription(this.jsep_offer);const o={janus:"attach",plugin:"janus.plugin.videoroom",opaque_id:this.opaqueId},a=JSON.stringify(o);this._request.body=a,t.send()}_receiveInviteResponse(t){if(this._publisherSubscribeSent||!t.body)return;const n=JSON.parse(t.body);this.handleId=n.data.id;const o={janus:"message",body:{request:"join",room:this.session.room_id,ptype:"publisher",display:this.session.display_name+" (Screen Share)",opaque_id:this.opaqueId},handle_id:this.handleId},a=[this.session.getPTypeHeader(kt.PUBLISHER)];this.session.sendRequest(H.SUBSCRIBE,{extraHeaders:a,body:JSON.stringify(o),eventHandlers:{onSuccessResponse:async s=>{var r,_,d,h;if(s.status_code===200){if(this._subscribeSent=!0,s.body)try{const m=JSON.parse(s.body)||{};((_=(r=m.plugindata)==null?void 0:r.data)==null?void 0:_.videoroom)==="joined"&&this.session.myFeedList.push(m.plugindata.data.id),(h=(d=m.plugindata)==null?void 0:d.data)!=null&&h.publishers&&this.session.receivePublishers(m)}catch(m){console.error(m)}this._lastTrickleReceived&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})}}}}),this._publisherSubscribeSent=!0}async _sendConfigureMessage(t){const n=this._candidates.map(r=>({janus:"trickle",candidate:r,handle_id:this.handleId,session_id:this.session.session_id})),a={configure:{janus:"message",body:{request:"configure",record:!0,filename:this.session.getRecordFileName(),...t},jsep:this.jsep_offer,handle_id:this.handleId,session_id:this.session.session_id},trickles:[...n]},s=["Content-Type: application/json",this.session.getPTypeHeader(kt.ICE)];this.session.sendRequest(H.INFO,{extraHeaders:s,body:JSON.stringify(a),eventHandlers:{onSuccessResponse:async r=>{this._configureSent=!0;const d=r.data.split(`\r
158
+ `,n),a===-1)return a;!c.substring(a+2,a+4).match(/(^\r\n)/)&&c.charAt(a+2).match(/(^\s+)/)?n=a+2:o=a}return o}function CT(c,t,n,o){let a;const s=t.indexOf(":",n),r=t.substring(n,s).trim(),_=t.substring(s+1,o).trim();switch(r.toLowerCase()){case"via":case"v":c.addHeader("via",_),c.getHeaders("via").length===1?(a=c.parseHeader("Via"),a&&(c.via=a,c.via_branch=a.branch)):a=0;break;case"from":case"f":c.setHeader("from",_),a=c.parseHeader("from"),a&&(c.from=a,c.from_tag=a.getParam("tag"));break;case"to":case"t":c.setHeader("to",_),a=c.parseHeader("to"),a&&(c.to=a,c.to_tag=a.getParam("tag"));break;case"record-route":if(a=Cu.parse(_,"Record_Route"),a===-1)a=void 0;else for(const d of a)c.addHeader("record-route",_.substring(d.possition,d.offset)),c.headers["Record-Route"][c.getHeaders("record-route").length-1].parsed=d.parsed;break;case"call-id":case"i":c.setHeader("call-id",_),a=c.parseHeader("call-id"),a&&(c.call_id=_);break;case"contact":case"m":if(a=Cu.parse(_,"Contact"),a===-1)a=void 0;else for(const d of a)c.addHeader("contact",_.substring(d.possition,d.offset)),c.headers.Contact[c.getHeaders("contact").length-1].parsed=d.parsed;break;case"content-length":case"l":c.setHeader("content-length",_),a=c.parseHeader("content-length");break;case"content-type":case"c":c.setHeader("content-type",_),a=c.parseHeader("content-type");break;case"cseq":c.setHeader("cseq",_),a=c.parseHeader("cseq"),a&&(c.cseq=a.value),c instanceof Ln.IncomingResponse&&(c.method=a.method);break;case"max-forwards":c.setHeader("max-forwards",_),a=c.parseHeader("max-forwards");break;case"www-authenticate":c.setHeader("www-authenticate",_),a=c.parseHeader("www-authenticate");break;case"proxy-authenticate":c.setHeader("proxy-authenticate",_),a=c.parseHeader("proxy-authenticate");break;case"session-expires":case"x":c.setHeader("session-expires",_),a=c.parseHeader("session-expires"),a&&(c.session_expires=a.expires,c.session_expires_refresher=a.refresher);break;case"refer-to":case"r":c.setHeader("refer-to",_),a=c.parseHeader("refer-to"),a&&(c.refer_to=a);break;case"replaces":c.setHeader("replaces",_),a=c.parseHeader("replaces"),a&&(c.replaces=a);break;case"event":case"o":c.setHeader("event",_),a=c.parseHeader("event"),a&&(c.event=a);break;default:c.addHeader(r,_),a=0}return a===void 0?{error:`error parsing header "${r}"`}:!0}const AT={parseMessage:ET},si=new no("Registrator"),Co=10;class RT{constructor(t,n){this._reg_id=1,this._ua=t,this._transport=n,this._registrar=t.configuration.registrar_server,this._expires=t.configuration.register_expires,this._call_id=vs.createRandomToken(22),this._cseq=0,this._to_uri=t.configuration.uri,this._registrationTimer=null,this._registering=!1,this._registered=!1,this._contact=this._ua.contact.toString();const o=this._contact.indexOf(">");if(o!==-1){const a=this._contact.slice(0,o)+this._contact.slice(o+1,this._contact.length);this._contact=a}this._extra_contact="",this._extraContactParams="",this._extra_contact+=";+sip.ice",this._extraHeaders=[],this._sipInstance=`"<urn:uuid:${this._ua.configuration.instance_id}>"`,this._extra_contact+=`;reg-id=${this._reg_id}`,this._extra_contact+=`;+sip.instance=${this._sipInstance}`}get registered(){return this._registered}setExtraHeaders(t){Array.isArray(t)||(t=[]),this._extraHeaders=t.slice()}setExtraContactParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)){const o=t[n];this._extraContactParams+=`;${n}`,o&&(this._extraContactParams+=`=${o}`)}}setExtraContactUriParams(t){t instanceof Object||(t={}),this._extraContactParams="";for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)){const o=t[n];this._extraContactParams+=`;${n}`,o&&(this._extraContactParams+=`=${o}`)}}register(){if(this._registering){si.debug("Register request in progress...");return}const t=this._extraHeaders.slice();t.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=${this._expires}`),t.push(`Expires: ${this._expires}`);const n=new Tt.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},t),o=new Wr(this._ua,n,{onRequestTimeout:()=>{this._registrationFailure(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._registrationFailure(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:a=>{if(a.cseq===this._cseq)switch(this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),!0){case/^1[0-9]{2}$/.test(a.status_code):break;case/^2[0-9]{2}$/.test(a.status_code):{if(this._registering=!1,!a.hasHeader("Contact")){si.debug("no Contact header in response to REGISTER, response ignored");break}const s=a.headers.Contact.reduce((h,m)=>h.concat(m.parsed),[]);let r=s.find(h=>this._sipInstance===h.getParam("+sip.instance")&&this._reg_id===parseInt(h.getParam("reg-id")));if(r||(r=s.find(h=>h.uri.user===this._ua.contact.uri.user)),!r){si.debug("no Contact header pointing to us, response ignored");break}this._ua.clearKeepAliveInterval(),this._ua.setLastRegisterTimestamp();let _=r.getParam("expires");!_&&a.hasHeader("expires")&&(_=a.getHeader("expires")),_||(_=this._expires),_=Number(_),_<Co&&(_=Co);const d=_>64?_*1e3/2+Math.floor((_/2-32)*1e3*Math.random()):Math.floor(_*1e3/2);this._registrationTimer=setTimeout(()=>{this._registrationTimer=null,this._ua.listeners("registrationExpiring").length===0?this.register():this._ua.emit("registrationExpiring")},d),r.hasParam("temp-gruu")&&(this._ua.contact.temp_gruu=r.getParam("temp-gruu").replace(/"/g,"")),r.hasParam("pub-gruu")&&(this._ua.contact.pub_gruu=r.getParam("pub-gruu").replace(/"/g,"")),this._registered||(this._registered=!0,this._ua.registered({response:a}));break}case/^423$/.test(a.status_code):{a.hasHeader("min-expires")?(this._expires=Number(a.getHeader("min-expires")),this._expires<Co&&(this._expires=Co),this.register()):(si.debug("423 response received for REGISTER without Min-Expires"),this._registrationFailure(a,H.causes.SIP_FAILURE_CODE));break}default:{const s=vs.sipErrorCause(a.status_code);this._registrationFailure(a,s)}}}});this._registering=!0,o.send()}unregister(t={}){if(!this._registered){si.debug("already unregistered");return}this._registered=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null);const n=this._extraHeaders.slice();t.all?n.push(`Contact: *${this._extraContactParams}`):n.push(`Contact: ${this._contact}${this._extraContactParams}>${this._extra_contact};expires=0`),n.push("Expires: 0");const o=new Tt.OutgoingRequest(H.REGISTER,this._registrar,this._ua,{to_uri:this._to_uri,call_id:this._call_id,cseq:this._cseq+=1},n);new Wr(this._ua,o,{onRequestTimeout:()=>{this._unregistered(null,H.causes.REQUEST_TIMEOUT)},onTransportError:()=>{this._unregistered(null,H.causes.CONNECTION_ERROR)},onAuthenticated:()=>{this._cseq+=1},onReceiveResponse:s=>{switch(!0){case/^1[0-9]{2}$/.test(s.status_code):break;case/^2[0-9]{2}$/.test(s.status_code):this._unregistered(s);break;default:{const r=vs.sipErrorCause(s.status_code);this._unregistered(s,r)}}}}).send()}close(){this._registered&&this.unregister()}onTransportClosed(){this._registering=!1,this._registrationTimer!==null&&(clearTimeout(this._registrationTimer),this._registrationTimer=null),this._registered&&(this._registered=!1,this._ua.unregistered({}))}_registrationFailure(t,n){this._registering=!1,this._ua.registrationFailed({response:t||null,cause:n}),this._registered&&(this._registered=!1,this._ua.unregistered({response:t||null,cause:n}))}_unregistered(t,n){this._registering=!1,this._registered=!1,this._ua.unregistered({response:t||null,cause:n||null})}}const tt=console,Ps={STATUS_INIT:0,STATUS_READY:1,STATUS_USER_CLOSED:2,STATUS_NOT_READY:3,CONFIGURATION_ERROR:1,NETWORK_ERROR:2},IT=dT;class bT extends IT{constructor(t){super(t),this._msrp_sessions=[],this._transactions={nist:{},nict:{},ist:{},ict:{}},this._janus_sessions=[],this.newStreamPlugins=[],this.processStreamPlugins=[],this.optionsInterval=null,this.lastOptionsTimestamp=null,this.lastRegisterTimestamp=null,this._registrator=new RT(this)}setLastRegisterTimestamp(){this.lastRegisterTimestamp=Date.now()}call(t,n){return super.call(t,n)}joinVideoCall(t,n,o){tt.debug("call()");const a=new Eo(this);return a.configureMedia({audio:!0,video:!0}),a.connect(t,n,o),a}startScreenShare(){tt.debug("startScreenShare()");for(const t in this._janus_sessions)this._janus_sessions[t].connectScreenShare()}changeMediaConstraints(t){for(const n in this._janus_sessions)this._janus_sessions[n].changeMediaConstraints(t)}startBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].connectBlur()}stopBlur(){for(const t in this._janus_sessions)this._janus_sessions[t].stopBlur()}_loadConfig(t){try{ti.load(this._configuration,t)}catch(s){throw s}this._configuration.display_name===0&&(this._configuration.display_name="0"),this._configuration.instance_id||(this._configuration.instance_id=vs.newUUID());let n;typeof window<"u"&&typeof window.document<"u"?n=window==null?void 0:window.navigator.userAgent:typeof self<"u"&&self.navigator&&(n=self.navigator.userAgent),n+=" "+De.USER_AGENT,this._configuration.user_agent=t.overrideUserAgent&&typeof t.overrideUserAgent=="function"?t.overrideUserAgent(n):n,t.onTransportCallback&&typeof t.onTransportCallback=="function"&&(this.onTransportCallback=t.onTransportCallback),this._configuration.jssip_id=vs.createRandomToken(5);const o=this._configuration.uri.clone();o.user=null,this._configuration.hostport_params=o.toString().replace(/^sip:/i,"");try{this._transport=new $m(this._configuration.sockets,{max_interval:this._configuration.connection_recovery_max_interval,min_interval:this._configuration.connection_recovery_min_interval}),this._transport.onconnecting=wT.bind(this),this._transport.onconnect=OT.bind(this),this._transport.ondisconnect=DT.bind(this),this._transport.ondata=NT.bind(this)}catch(s){throw tt.warn(s),new Ns.ConfigurationError("sockets",this._configuration.sockets)}if(delete this._configuration.sockets,this._configuration.authorization_user||(this._configuration.authorization_user=this._configuration.uri.user),!this._configuration.registrar_server){const s=this._configuration.uri.clone();s.user=null,s.clearParams(),s.clearHeaders(),this._configuration.registrar_server=s}this._configuration.no_answer_timeout*=1e3,this._configuration.contact_uri?this._configuration.via_host=this._configuration.contact_uri.host:this._configuration.contact_uri=new ln("sip",vs.createRandomToken(8),this._configuration.via_host,null,{transport:"ws"}),this._contact={pub_gruu:null,temp_gruu:null,uri:this._configuration.contact_uri,toString(s={}){const r=s.anonymous||null,_=s.outbound||null;let d="<";return r?d+=this.temp_gruu||"sip:anonymous@anonymous.invalid;transport=ws":d+=this.pub_gruu||this.uri.toString(),_&&(r?!this.temp_gruu:!this.pub_gruu)&&(d+=";ob"),d+=">",d}};const a=["authorization_user","password","realm","ha1","authorization_jwt","display_name","register"];for(const s in this._configuration)Object.prototype.hasOwnProperty.call(this._configuration,s)&&(a.indexOf(s)!==-1?Object.defineProperty(this._configuration,s,{writable:!0,configurable:!1}):Object.defineProperty(this._configuration,s,{writable:!1,configurable:!1}));tt.debug("configuration parameters after validation:");for(const s in this._configuration)if(Object.prototype.hasOwnProperty.call(ti.settings,s))switch(s){case"uri":case"registrar_server":tt.debug(`- ${s}: ${this._configuration[s]}`);break;case"password":case"ha1":case"authorization_jwt":tt.debug(`- ${s}: NOT SHOWN`);break;default:tt.debug(`- ${s}: ${JSON.stringify(this._configuration[s])}`)}}newMSRPSession(t,n){t.on("msgHistoryUpdate",o=>{console.log(o)}),this._msrp_sessions[t.id]=t,this.emit("newMSRPSession",n)}newJanusSession(t,n){this._janus_sessions[t.id]=t,this.newStreamPlugins.forEach(o=>{o.setSession(t)}),this.processStreamPlugins.forEach(o=>{o.setSession(t)}),this.emit("newJanusSession",n)}kill(){}destroyMSRPSession(t){delete this._msrp_sessions[t.id]}destroyJanusSession(t){delete this._janus_sessions[t.id]}clearKeepAliveInterval(){clearInterval(this.optionsInterval),this.optionsInterval=null}receiveRequest(t){var s,r,_,d;const n=t.method;if(t.ruri.user!==this._configuration.uri.user&&t.ruri.user!==this._contact.uri.user){tt.debug("Request-URI does not point to us"),t.method!==De.ACK&&t.reply_sl(404);return}if(t.ruri.scheme===De.SIPS){t.reply_sl(416);return}if(Ht.checkTransaction(this,t))return;if(n===De.INVITE?new Ht.InviteServerTransaction(this,this._transport,t):n!==De.ACK&&n!==De.CANCEL&&new Ht.NonInviteServerTransaction(this,this._transport,t),n===De.OPTIONS){if(this.lastOptionsTimestamp=Date.now(),this.optionsInterval||(this.emit("initKeepAliveInterval"),this.optionsInterval=setInterval(()=>{const m=Date.now(),T=this.lastOptionsTimestamp>m-35e3,S=this.lastRegisterTimestamp+this._configuration.register_expires*1e3>m;T&&S&&this.emit("keepAliveInterval")},35e3)),this.listeners("newOptions").length===0){t.reply(200);return}new Af.Options(this).init_incoming(t)}else if(n===De.MESSAGE){if(this.listeners("newMessage").length===0){t.reply(405);return}new Af.Message(this).init_incoming(t)}else if(n===De.INVITE&&!t.to_tag&&this.listeners("newRTCSession").length===0){t.reply(405);return}let o,a;if(t.to_tag)if(o=this._findDialog(t.call_id,t.from_tag,t.to_tag),o)o.receiveRequest(t);else if(n===De.NOTIFY)if(a=this._findSession(t),a)a.receiveRequest(t);else{if(t.body)try{const h=JSON.parse(t.body)||{};(r=(s=h.plugindata)==null?void 0:s.data)!=null&&r.publishers&&Object.values(this._janus_sessions)[0].receivePublishers(h),(d=(_=h.plugindata)==null?void 0:_.data)!=null&&d.unpublished&&Object.values(this._janus_sessions)[0].receiveUnpublished(h.plugindata.data.unpublished)}catch(h){console.error(h)}t.reply(200)}else n!==De.ACK&&t.reply(481);else switch(n){case De.INVITE:if(window.RTCPeerConnection)if(t.hasHeader("replaces")){const h=t.replaces;o=this._findDialog(h.call_id,h.from_tag,h.to_tag),o?(a=o.owner,a.isEnded()?t.reply(603):a.receiveRequest(t)):t.reply(481)}else t.body.search(/MSRP/ig)>-1?(a=new yu(this),a.init_incoming(t)):t.body.search(/JANUS/ig)>-1||(a=new ym(this),a.init_incoming(t));else tt.warn("INVITE received but WebRTC is not supported"),t.reply(488);break;case De.BYE:t.reply(481);break;case De.CANCEL:a=this._findSession(t),a?a.receiveRequest(t):tt.debug("received CANCEL request for a non existent session");break;case De.ACK:break;case De.NOTIFY:this.emit("sipEvent",{event:t.event,request:t}),t.reply(200);break;default:t.reply(405);break}}startMSRP(t,n){tt.debug("startMSRP()",n);const o=new yu(this);return o.connect(t),o}startJanus(t,n){tt.debug("startJanus()",n);const o=new yu(this);return o.connect(t),o}terminateMSRPSessions(t){tt.debug("terminateSessions()");for(const n in this._msrp_sessions)this._msrp_sessions[n].isEnded()||this._msrp_sessions[n].terminate(t)}terminateJanusSessions(t){tt.debug("terminateSessions()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||this._janus_sessions[n].terminate(t)}enableJanusAudio(t){tt.debug("enableJanusAudio()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||(t?this._janus_sessions[n].startAudio():this._janus_sessions[n].stopAudio())}enableJanusVideo(t){tt.debug("enableJanusVideo()");for(const n in this._janus_sessions)this._janus_sessions[n].isEnded()||(t?this._janus_sessions[n].startVideo():this._janus_sessions[n].stopVideo())}terminateAllSessions(){for(const t in this._sessions)if(Object.prototype.hasOwnProperty.call(this._sessions,t)){tt.debug(`closing session ${t}`);try{this._sessions[t].terminate()}catch(n){console.error(n)}}}stop(t=!0){if(tt.debug("stop()"),this._dynConfiguration={},this._status===Ps.STATUS_USER_CLOSED){tt.debug("UA already closed");return}this._registrator.close();const n=Object.keys(this._sessions).length;t&&this.terminateAllSessions();for(const a in this._msrp_sessions)if(Object.prototype.hasOwnProperty.call(this._msrp_sessions,a)){tt.debug(`closing session ${a}`);try{this._msrp_sessions[a].terminate()}catch(s){console.error(s)}}for(const a in this._janus_sessions)if(Object.prototype.hasOwnProperty.call(this._janus_sessions,a)){tt.debug(`closing session ${a}`);try{this._janus_sessions[a].terminate()}catch(s){console.error(s)}}for(const a in this._applicants)if(Object.prototype.hasOwnProperty.call(this._applicants,a))try{this._applicants[a].close()}catch(s){console.error(s)}this._status=Ps.STATUS_USER_CLOSED,Object.keys(this._transactions.nict).length+Object.keys(this._transactions.nist).length+Object.keys(this._transactions.ict).length+Object.keys(this._transactions.ist).length===0&&n===0?this._transport.disconnect():this._closeTimer=setTimeout(()=>{this._closeTimer=null,this._transport.disconnect()},2e3)}}function wT(c){this.emit("connecting",c)}function OT(c){this._status!==Ps.STATUS_USER_CLOSED&&(this._status=Ps.STATUS_READY,this._error=null,this.emit("connected",c),this._dynConfiguration.register&&this._registrator.register())}function DT(c){const t=["nict","ict","nist","ist"];for(const n of t)for(const o in this._transactions[n])Object.prototype.hasOwnProperty.call(this._transactions[n],o)&&this._transactions[n][o].onTransportError();this.emit("disconnected",c),this._registrator.onTransportClosed(),this._status!==Ps.STATUS_USER_CLOSED&&(this._status=Ps.STATUS_NOT_READY,this._error=Ps.NETWORK_ERROR)}function NT(c){const t=c.transport;let n=c.message;const o=n;if(n=AT.parseMessage(n,this),this.onTransportCallback&&typeof this.onTransportCallback=="function"&&this.onTransportCallback(n,o),!!n&&!(this._status===Ps.STATUS_USER_CLOSED&&n instanceof Ln.IncomingRequest)&&Zm(n,this,t)){if(n instanceof Ln.IncomingRequest)n.transport=t,this.receiveRequest(n);else if(n instanceof Ln.IncomingResponse){let a;switch(n.method){case De.INVITE:if(a=this._transactions.ict[n.via_branch],a){const s=n.status_code;if((s===100||s===180||s===183)&&this.audio&&typeof this.audio.handleSipResponseForRingback=="function"){let r=null;if(a._session&&a._session.id)r=a._session.id;else if(n.call_id&&this._sessions){const d=Object.values(this._sessions).find(h=>h._id&&h._id.includes(n.call_id)||h.id&&h.id.includes(n.call_id)||h.call_id===n.call_id);d&&(d.id||d._id)&&(r=d.id||d._id)}else n.call_id&&(r=n.call_id);r&&this.audio.handleSipResponseForRingback(r,s)}a.receiveResponse(n)}break;case De.ACK:break;default:a=this._transactions.nict[n.via_branch],a&&a.receiveResponse(n);break}}}}const xT=["roomId","_audioMuted","_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","_localHold","_videoMuted","status","start_time","_remote_identity","audioTag","isOnHold","localMuted","autoAnswer","putOnHoldTimestamp"],UT=["_cancel_reason","_contact","direction","_end_time","_eventsCount","_from_tag","_id","_is_canceled","_is_confirmed","_late_sdp","status","start_time","_remote_identity","target_addr"];function vd(c){const t={};return xT.forEach(n=>{c[n]!==void 0&&(t[n]=c[n])}),t.localHold=c._localHold,t}function Sd(c){const t={};return UT.forEach(n=>{c[n]!==void 0&&(t[n]=c[n])}),t}async function Au(c,t,n){const o=c.createMediaStreamSource(t),a=c.createMediaStreamDestination(),s=c.createGain();return o.connect(s),s.connect(a),s.gain.value=n,a.stream}function kT(c,t,n,o){if(Ed())return;const a=document.createElement("audio");a.id=t._id,a.className="audioTag",a.srcObject=c,a.setSinkId(n),a.volume=o,a.play(),t.audioTag=a}function PT(c){if(c&&typeof c.log=="function"&&typeof c.warn=="function"&&typeof c.error=="function")return!0}function Ed(){return/Mobi|react-native|Android|iPhone/i.test(navigator.userAgent)}const MT=ot,LT=Yt(),Ot=new MT("WebSocketInterface");var $T=class{constructor(t){Ot.debug('new() [url:"%s"]',t),this._url=t,this._sip_uri=null,this._via_transport=null,this._ws=null;const n=LT.parse(t,"absoluteURI");if(n===-1)throw Ot.warn(`invalid WebSocket URI: ${t}`),new TypeError(`Invalid argument: ${t}`);if(n.scheme!=="wss"&&n.scheme!=="ws")throw Ot.warn(`invalid WebSocket URI scheme: ${n.scheme}`),new TypeError(`Invalid argument: ${t}`);this._sip_uri=`sip:${n.host}${n.port?`:${n.port}`:""};transport=ws`,this._via_transport=n.scheme.toUpperCase()}get via_transport(){return this._via_transport}set via_transport(t){this._via_transport=t.toUpperCase()}get sip_uri(){return this._sip_uri}get url(){return this._url}connect(){if(Ot.debug("connect()"),this.isConnected()){Ot.debug(`WebSocket ${this._url} is already connected`);return}else if(this.isConnecting()){Ot.debug(`WebSocket ${this._url} is connecting`);return}this._ws&&this.disconnect(),Ot.debug(`connecting to WebSocket ${this._url}`);try{this._ws=new WebSocket(this._url,"sip"),this._ws.binaryType="arraybuffer",this._ws.onopen=this._onOpen.bind(this),this._ws.onclose=this._onClose.bind(this),this._ws.onmessage=this._onMessage.bind(this),this._ws.onerror=this._onError.bind(this)}catch(t){this._onError(t)}}disconnect(){Ot.debug("disconnect()"),this._ws&&(this._ws.onopen=()=>{},this._ws.onclose=()=>{},this._ws.onmessage=()=>{},this._ws.onerror=()=>{},this._ws.close(),this._ws=null)}send(t){return Ot.debug("send()"),this.isConnected()?(this._ws.send(t),!0):(Ot.warn("unable to send message, WebSocket is not open"),!1)}isConnected(){return this._ws&&this._ws.readyState===this._ws.OPEN}isConnecting(){return this._ws&&this._ws.readyState===this._ws.CONNECTING}_onOpen(){Ot.debug(`WebSocket ${this._url} connected`),this.onconnect()}_onClose({wasClean:t,code:n,reason:o}){Ot.debug(`WebSocket ${this._url} closed`),t===!1&&Ot.debug("WebSocket abrupt disconnection"),this.ondisconnect(!t,n,o)}_onMessage({data:t}){Ot.debug("received WebSocket message"),this.ondata(t)}_onError(t){Ot.warn(`WebSocket ${this._url} error: `,t)}};const Ru=Tl,HT=De,FT=Ts,VT=gt(),jT=gd,qT=ps(),BT=Ba(),GT=Yt(),WT=$T;Nn("JsSIP")("version %s",Ru.version);var KT={C:HT,Exceptions:FT,Utils:VT,UA:jT,URI:qT,NameAddrHeader:BT,WebSocketInterface:WT,Grammar:GT,debug:Nn,get name(){return Ru.title},get version(){return Ru.version}};const YT=Me(KT);function Iu(c){return c<10?`0${c}`:`${c}`}function JT(c){let t=c.hours||0,n=c.minutes||0,o=c.seconds||0;o++,o===60&&(o=0,n++,n===60&&(n=0,t++));const a=`${Iu(t)}:${Iu(n)}:${Iu(o)}`;return{seconds:o,minutes:n,hours:t,formatted:a}}function zT(c){let t=0;for(let n=0;n<c.length;n++)t+=c[n]*c[n];return Math.sqrt(t/c.length)}async function XT(c,t,n=150){const o=t.createMediaStreamSource(c),a=t.createDelay();a.delayTime.value=n/1e3;const s=t.createGain();s.gain.value=0;const r=t.createMediaStreamDestination();return o.connect(a).connect(s).connect(r),{stream:r.stream,setSpeaking:_=>{s.gain.value=_?1:0}}}var yt={};yt.forEach=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)if(a in c){const s=Promise.resolve(c[a]).then(r=>t.call(n||globalThis,r,a,c));o.push(s)}await Promise.all(o)},yt.forEachSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)o in c&&await t.call(n||globalThis,await c[o],o,c)},yt.map=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&(o[a]=Promise.resolve(c[a]).then(s=>t.call(n||globalThis,s,a,c)));return Promise.all(o)},yt.mapSeries=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&(o[a]=await t.call(n||globalThis,await c[a],a,c));return o},yt.find=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o();let s=1;for(let r=0;r<c.length;r++){const _=d=>{d?o(c[r]):s===c.length&&o(),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.findSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(await t.call(n||globalThis,await c[o],o,c))return c[o]},yt.findIndex=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(-1);let s=1;for(let r=0;r<c.length;r++){const _=d=>{d?o(r):s===c.length&&o(-1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.findIndexSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(await t.call(n||globalThis,await c[o],o,c))return o},yt.some=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(!1);let s=1;for(let r=0;r<c.length;r++){if(!(r in c)){s++;continue}const _=d=>{d?o(!0):s===c.length&&o(!1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.someSeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(o in c&&await t.call(n||globalThis,await c[o],o,c))return!0;return!1},yt.every=(c,t,n)=>new Promise((o,a)=>{if(c.length===0)return o(!0);let s=1;for(let r=0;r<c.length;r++){if(!(r in c)){s++;continue}const _=d=>{d?s===c.length&&o(!0):o(!1),s++};Promise.resolve(c[r]).then(d=>t.call(n||globalThis,d,r,c)).then(_).catch(a)}}),yt.everySeries=async(c,t,n)=>{for(let o=0;o<c.length;o++)if(o in c&&!await t.call(n||globalThis,await c[o],o,c))return!1;return!0},yt.filter=(c,t,n)=>new Promise(async(o,a)=>{const s=[];for(let _=0;_<c.length;_++)_ in c&&(s[_]=Promise.resolve(c[_]).then(d=>t.call(n||globalThis,d,_,c)).catch(a));const r=[];for(let _=0;_<s.length;_++)await s[_]&&r.push(await c[_]);o(r)}),yt.filterSeries=async(c,t,n)=>{const o=[];for(let a=0;a<c.length;a++)a in c&&await t.call(n||globalThis,await c[a],a,c)&&o.push(await c[a]);return o},yt.reduce=async(c,t,n)=>{if(c.length===0&&n===void 0)throw TypeError("Reduce of empty array with no initial value");let o,a;for(n!==void 0?(a=n,o=0):(a=c[0],o=1),o;o<c.length;o++)o in c&&(a=await t(await a,await c[o],o,c));return a};var yd={};(function(c){const t=yt;Object.keys(t).forEach(n=>{const o=n.charAt(0).toUpperCase()+n.slice(1);c[`async${o}`]=async function(...a){return t[n](this,...a)}})})(yd);var QT=Object.assign(yt,{instanceMethods:yd});const Xt={NEW_CALL:"new_call",CALL_CONFIRMED:"confirmed",CALL_FAILED:"failed",CALL_PROGRESS:"progress",CALL_ENDED:"ended"},Ao={TRYING:100,RINGING:180,SESSION_PROGRESS:183,OK:200,MOVED_TEMPORARILY:302,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,REQUEST_TIMEOUT:408,BUSY_HERE:486,REQUEST_TERMINATED:487,INTERNAL_SERVER_ERROR:500,SERVICE_UNAVAILABLE:503,BUSY_EVERYWHERE:600,DECLINE:603};var ZT={exports:{}};(function(c){var t=function(n){var o=Object.prototype,a=o.hasOwnProperty,s=Object.defineProperty||function(Q,K,G){Q[K]=G.value},r,_=typeof Symbol=="function"?Symbol:{},d=_.iterator||"@@iterator",h=_.asyncIterator||"@@asyncIterator",m=_.toStringTag||"@@toStringTag";function T(Q,K,G){return Object.defineProperty(Q,K,{value:G,enumerable:!0,configurable:!0,writable:!0}),Q[K]}try{T({},"")}catch{T=function(K,G,re){return K[G]=re}}function S(Q,K,G,re){var pe=K&&K.prototype instanceof ie?K:ie,Ie=Object.create(pe.prototype),Pe=new P(re||[]);return s(Ie,"_invoke",{value:Y(Q,G,Pe)}),Ie}n.wrap=S;function E(Q,K,G){try{return{type:"normal",arg:Q.call(K,G)}}catch(re){return{type:"throw",arg:re}}}var C="suspendedStart",A="suspendedYield",R="executing",L="completed",b={};function ie(){}function N(){}function F(){}var me={};T(me,d,function(){return this});var _e=Object.getPrototypeOf,U=_e&&_e(_e(B([])));U&&U!==o&&a.call(U,d)&&(me=U);var x=F.prototype=ie.prototype=Object.create(me);N.prototype=F,s(x,"constructor",{value:F,configurable:!0}),s(F,"constructor",{value:N,configurable:!0}),N.displayName=T(F,m,"GeneratorFunction");function q(Q){["next","throw","return"].forEach(function(K){T(Q,K,function(G){return this._invoke(K,G)})})}n.isGeneratorFunction=function(Q){var K=typeof Q=="function"&&Q.constructor;return K?K===N||(K.displayName||K.name)==="GeneratorFunction":!1},n.mark=function(Q){return Object.setPrototypeOf?Object.setPrototypeOf(Q,F):(Q.__proto__=F,T(Q,m,"GeneratorFunction")),Q.prototype=Object.create(x),Q},n.awrap=function(Q){return{__await:Q}};function j(Q,K){function G(Ie,Pe,Re,oe){var ye=E(Q[Ie],Q,Pe);if(ye.type==="throw")oe(ye.arg);else{var lt=ye.arg,at=lt.value;return at&&typeof at=="object"&&a.call(at,"__await")?K.resolve(at.__await).then(function(Ee){G("next",Ee,Re,oe)},function(Ee){G("throw",Ee,Re,oe)}):K.resolve(at).then(function(Ee){lt.value=Ee,Re(lt)},function(Ee){return G("throw",Ee,Re,oe)})}}var re;function pe(Ie,Pe){function Re(){return new K(function(oe,ye){G(Ie,Pe,oe,ye)})}return re=re?re.then(Re,Re):Re()}s(this,"_invoke",{value:pe})}q(j.prototype),T(j.prototype,h,function(){return this}),n.AsyncIterator=j,n.async=function(Q,K,G,re,pe){pe===void 0&&(pe=Promise);var Ie=new j(S(Q,K,G,re),pe);return n.isGeneratorFunction(K)?Ie:Ie.next().then(function(Pe){return Pe.done?Pe.value:Ie.next()})};function Y(Q,K,G){var re=C;return function(Ie,Pe){if(re===R)throw new Error("Generator is already running");if(re===L){if(Ie==="throw")throw Pe;return je()}for(G.method=Ie,G.arg=Pe;;){var Re=G.delegate;if(Re){var oe=V(Re,G);if(oe){if(oe===b)continue;return oe}}if(G.method==="next")G.sent=G._sent=G.arg;else if(G.method==="throw"){if(re===C)throw re=L,G.arg;G.dispatchException(G.arg)}else G.method==="return"&&G.abrupt("return",G.arg);re=R;var ye=E(Q,K,G);if(ye.type==="normal"){if(re=G.done?L:A,ye.arg===b)continue;return{value:ye.arg,done:G.done}}else ye.type==="throw"&&(re=L,G.method="throw",G.arg=ye.arg)}}}function V(Q,K){var G=K.method,re=Q.iterator[G];if(re===r)return K.delegate=null,G==="throw"&&Q.iterator.return&&(K.method="return",K.arg=r,V(Q,K),K.method==="throw")||G!=="return"&&(K.method="throw",K.arg=new TypeError("The iterator does not provide a '"+G+"' method")),b;var pe=E(re,Q.iterator,K.arg);if(pe.type==="throw")return K.method="throw",K.arg=pe.arg,K.delegate=null,b;var Ie=pe.arg;if(!Ie)return K.method="throw",K.arg=new TypeError("iterator result is not an object"),K.delegate=null,b;if(Ie.done)K[Q.resultName]=Ie.value,K.next=Q.nextLoc,K.method!=="return"&&(K.method="next",K.arg=r);else return Ie;return K.delegate=null,b}q(x),T(x,m,"Generator"),T(x,d,function(){return this}),T(x,"toString",function(){return"[object Generator]"});function X(Q){var K={tryLoc:Q[0]};1 in Q&&(K.catchLoc=Q[1]),2 in Q&&(K.finallyLoc=Q[2],K.afterLoc=Q[3]),this.tryEntries.push(K)}function k(Q){var K=Q.completion||{};K.type="normal",delete K.arg,Q.completion=K}function P(Q){this.tryEntries=[{tryLoc:"root"}],Q.forEach(X,this),this.reset(!0)}n.keys=function(Q){var K=Object(Q),G=[];for(var re in K)G.push(re);return G.reverse(),function pe(){for(;G.length;){var Ie=G.pop();if(Ie in K)return pe.value=Ie,pe.done=!1,pe}return pe.done=!0,pe}};function B(Q){if(Q){var K=Q[d];if(K)return K.call(Q);if(typeof Q.next=="function")return Q;if(!isNaN(Q.length)){var G=-1,re=function pe(){for(;++G<Q.length;)if(a.call(Q,G))return pe.value=Q[G],pe.done=!1,pe;return pe.value=r,pe.done=!0,pe};return re.next=re}}return{next:je}}n.values=B;function je(){return{value:r,done:!0}}return P.prototype={constructor:P,reset:function(Q){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(k),!Q)for(var K in this)K.charAt(0)==="t"&&a.call(this,K)&&!isNaN(+K.slice(1))&&(this[K]=r)},stop:function(){this.done=!0;var Q=this.tryEntries[0],K=Q.completion;if(K.type==="throw")throw K.arg;return this.rval},dispatchException:function(Q){if(this.done)throw Q;var K=this;function G(oe,ye){return Ie.type="throw",Ie.arg=Q,K.next=oe,ye&&(K.method="next",K.arg=r),!!ye}for(var re=this.tryEntries.length-1;re>=0;--re){var pe=this.tryEntries[re],Ie=pe.completion;if(pe.tryLoc==="root")return G("end");if(pe.tryLoc<=this.prev){var Pe=a.call(pe,"catchLoc"),Re=a.call(pe,"finallyLoc");if(Pe&&Re){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0);if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else if(Pe){if(this.prev<pe.catchLoc)return G(pe.catchLoc,!0)}else if(Re){if(this.prev<pe.finallyLoc)return G(pe.finallyLoc)}else throw new Error("try statement without catch or finally")}}},abrupt:function(Q,K){for(var G=this.tryEntries.length-1;G>=0;--G){var re=this.tryEntries[G];if(re.tryLoc<=this.prev&&a.call(re,"finallyLoc")&&this.prev<re.finallyLoc){var pe=re;break}}pe&&(Q==="break"||Q==="continue")&&pe.tryLoc<=K&&K<=pe.finallyLoc&&(pe=null);var Ie=pe?pe.completion:{};return Ie.type=Q,Ie.arg=K,pe?(this.method="next",this.next=pe.finallyLoc,b):this.complete(Ie)},complete:function(Q,K){if(Q.type==="throw")throw Q.arg;return Q.type==="break"||Q.type==="continue"?this.next=Q.arg:Q.type==="return"?(this.rval=this.arg=Q.arg,this.method="return",this.next="end"):Q.type==="normal"&&K&&(this.next=K),b},finish:function(Q){for(var K=this.tryEntries.length-1;K>=0;--K){var G=this.tryEntries[K];if(G.finallyLoc===Q)return this.complete(G.completion,G.afterLoc),k(G),b}},catch:function(Q){for(var K=this.tryEntries.length-1;K>=0;--K){var G=this.tryEntries[K];if(G.tryLoc===Q){var re=G.completion;if(re.type==="throw"){var pe=re.arg;k(G)}return pe}}throw new Error("illegal catch attempt")},delegateYield:function(Q,K,G){return this.delegate={iterator:B(Q),resultName:K,nextLoc:G},this.method==="next"&&(this.arg=r),b}},n}(c.exports);try{regeneratorRuntime=t}catch{typeof globalThis=="object"?globalThis.regeneratorRuntime=t:Function("r","regeneratorRuntime = r")(t)}})(ZT);var Cd={exports:{}};(function(c){(function(t,n){c.exports?c.exports=n():t.log=n()})(cs,function(){var t=function(){},n="undefined",o=typeof window!==n&&typeof window.navigator!==n&&/Trident\/|MSIE /.test(window.navigator.userAgent),a=["trace","debug","info","warn","error"];function s(A,R){var L=A[R];if(typeof L.bind=="function")return L.bind(A);try{return Function.prototype.bind.call(L,A)}catch{return function(){return Function.prototype.apply.apply(L,[A,arguments])}}}function r(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function _(A){return A==="debug"&&(A="log"),typeof console===n?!1:A==="trace"&&o?r:console[A]!==void 0?s(console,A):console.log!==void 0?s(console,"log"):t}function d(A,R){for(var L=0;L<a.length;L++){var b=a[L];this[b]=L<A?t:this.methodFactory(b,A,R)}this.log=this.debug}function h(A,R,L){return function(){typeof console!==n&&(d.call(this,R,L),this[A].apply(this,arguments))}}function m(A,R,L){return _(A)||h.apply(this,arguments)}function T(A,R,L){var b=this,ie;R=R??"WARN";var N="loglevel";typeof A=="string"?N+=":"+A:typeof A=="symbol"&&(N=void 0);function F(x){var q=(a[x]||"silent").toUpperCase();if(!(typeof window===n||!N)){try{window.localStorage[N]=q;return}catch{}try{window.document.cookie=encodeURIComponent(N)+"="+q+";"}catch{}}}function me(){var x;if(!(typeof window===n||!N)){try{x=window.localStorage[N]}catch{}if(typeof x===n)try{var q=window.document.cookie,j=q.indexOf(encodeURIComponent(N)+"=");j!==-1&&(x=/^([^;]+)/.exec(q.slice(j))[1])}catch{}return b.levels[x]===void 0&&(x=void 0),x}}function _e(){if(!(typeof window===n||!N)){try{window.localStorage.removeItem(N);return}catch{}try{window.document.cookie=encodeURIComponent(N)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch{}}}b.name=A,b.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},b.methodFactory=L||m,b.getLevel=function(){return ie},b.setLevel=function(x,q){if(typeof x=="string"&&b.levels[x.toUpperCase()]!==void 0&&(x=b.levels[x.toUpperCase()]),typeof x=="number"&&x>=0&&x<=b.levels.SILENT){if(ie=x,q!==!1&&F(x),d.call(b,x,A),typeof console===n&&x<b.levels.SILENT)return"No console available for logging"}else throw"log.setLevel() called with invalid level: "+x},b.setDefaultLevel=function(x){R=x,me()||b.setLevel(x,!1)},b.resetLevel=function(){b.setLevel(R,!1),_e()},b.enableAll=function(x){b.setLevel(b.levels.TRACE,x)},b.disableAll=function(x){b.setLevel(b.levels.SILENT,x)};var U=me();U==null&&(U=R),b.setLevel(U,!1)}var S=new T,E={};S.getLogger=function(R){if(typeof R!="symbol"&&typeof R!="string"||R==="")throw new TypeError("You must supply a name when creating a logger.");var L=E[R];return L||(L=E[R]=new T(R,S.getLevel(),S.methodFactory)),L};var C=typeof window!==n?window.log:void 0;return S.noConflict=function(){return typeof window!==n&&window.log===S&&(window.log=C),S},S.getLoggers=function(){return E},S.default=S,S})})(Cd);var It=Cd.exports;const Ss=()=>`${new Date().toISOString()} | metrics`,Es=(c,t,n)=>`${c} | ${t} | ${n}`;It.setDefaultLevel(It.levels.TRACE);const ev=c=>{It.info(Es(Ss(),"log ",`set log level to ${c?"verbose":"info"}`)),It.setLevel(c?It.levels.TRACE:It.levels.INFO)},tv=c=>{const t=[...Object.keys(It.levels)];t.includes(c)?(It.info(Es(Ss(),"log ",`update log level to ${c.toLowerCase()}`)),It.setLevel(c)):It.warn(Es(Ss(),"log ","Incorrect log level please choose one of "),t)},Ue=(c,t,n)=>{n?It.debug(Es(Ss(),c,t),n):It.debug(Es(Ss(),c,t))},bu=(c,t)=>{It.info(Es(Ss(),c,t))},on=(c,t)=>{It.info(Es(Ss(),c,t))},Ro=(c,t)=>{It.warn(Es(Ss(),c,t))},jn=(c,t)=>{It.error(Es(Ss(),c,t))};function sv(c){return Math.floor(Math.random()*c).toString()}function Ad(c,t){let n=t;return c.forEach(o=>{n=n.replace(o,"")}),n}function nv(c,t){let n="";for(let o=0;o<t;o+=1)n+=c[sv(c.length)];return n}function rv({length:c=20,useLetters:t=!0,useNumbers:n=!0,includeSymbols:o=[],excludeSymbols:a=[]}={}){let s="abcdefghijklmnopqrstuvwxyz",r="0123456789",_=[],d=[],h=[];return t&&(a.length&&(s=Ad(a,s)),d=s.split("")),n&&(a.length&&(r=Ad(a,r)),h=r.split("")),_=[...d,...h,...o],nv(_,c)}var iv=rv;const ni=Me(iv),lv=()=>"WebRTCMetrics",ov=()=>"5.0.3",$e={INBOUND:"inbound",OUTBOUND:"outbound"},ys={IDLE:"idle",RUNNING:"running",MUTED:"muted"},ri={NEW:"new",CHECKING:"checking",CONNECTED:"connected",COMPLETED:"completed",DISCONNECTED:"disconnected",FAILED:"failed",CLOSED:"closed"},av=()=>({...{delta_time_to_measure_probes_ms:0,delta_time_consumed_to_measure_ms:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,total_time_decoded_in:0,total_time_encoded_out:0,probes:[]}}),Rd={level_in:0,codec_id_in:"",codec_in:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,mos_in:0,mos_emodel_in:0,ssrc:"",direction:$e.INBOUND},Id={level_out:0,codec_id_out:"",codec_out:{mime_type:null,clock_rate:null,sdp_fmtp_line:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,timestamp_out:null,mos_out:0,mos_emodel_out:0,ssrc:"",direction:$e.OUTBOUND},bd={codec_id_in:"",size_in:{width:null,height:null,framerate:null},codec_in:{mime_type:null,clock_rate:null},delta_jitter_ms_in:0,percent_packets_lost_in:0,delta_packets_in:0,delta_packets_lost_in:0,total_packets_in:0,total_packets_lost_in:0,total_KBytes_in:0,delta_KBytes_in:0,delta_kbs_in:0,decoder_in:null,delta_ms_decode_frame_in:0,total_frames_decoded_in:0,total_time_decoded_in:0,delta_nack_sent_in:0,delta_pli_sent_in:0,total_nack_sent_in:0,total_pli_sent_in:0,ssrc:"",direction:$e.INBOUND},wd={codec_id_out:"",size_out:{width:null,height:null,framerate:null},codec_out:{mime_type:null,clock_rate:null},delta_jitter_ms_out:0,delta_rtt_ms_out:null,total_rtt_ms_out:0,total_rtt_measure_out:0,percent_packets_lost_out:0,delta_packets_out:0,delta_packets_lost_out:0,total_packets_out:0,total_packets_lost_out:0,total_KBytes_out:0,delta_KBytes_out:0,delta_kbs_out:0,encoder_out:null,delta_ms_encode_frame_out:0,total_time_encoded_out:0,total_frames_encoded_out:0,delta_nack_received_out:0,delta_pli_received_out:0,total_nack_received_out:0,total_pli_received_out:0,limitation_out:{reason:null,durations:null,resolutionChanges:0},timestamp_out:null,ssrc:"",direction:$e.OUTBOUND},uv=c=>{const t={pname:"",call_id:"",user_id:"",timestamp:null,count:0,audio:{},video:{},network:{infrastructure:3,local_candidate_id:"",local_candidate_type:"",local_candidate_protocol:"",local_candidate_relay_protocol:"",remote_candidate_id:"",remote_candidate_type:"",remote_candidate_protocol:""},data:{total_KBytes_in:0,total_KBytes_out:0,delta_KBytes_in:0,delta_KBytes_out:0,delta_kbs_in:0,delta_kbs_out:0,delta_kbs_bandwidth_in:0,delta_kbs_bandwidth_out:0,delta_rtt_connectivity_ms:null,total_rtt_connectivity_ms:0,total_rtt_connectivity_measure:0},experimental:{time_to_measure_ms:0}};if(c){const n={...c,audio:{},video:{},data:{...c.data},network:{...c.network},experimental:{...c.experimental}};return Object.keys(c.audio).forEach(o=>{n.audio[o]={...c.audio[o]}}),Object.keys(c.video).forEach(o=>{n.video[o]={...c.video[o]}}),n}return{...t,audio:{},video:{},data:{...t.data},network:{...t.network},experimental:{...t.experimental}}},cv={refreshEvery:2e3,startAfter:0,stopAfter:-1,verbose:!1,pname:`p-${ni()}`,cid:`c-${ni()}`,uid:`u-${ni()}`,record:!1,ticket:!0},Qt={CANDIDATE_PAIR:"candidate-pair",CODEC:"codec",INBOUND_RTP:"inbound-rtp",LOCAL_CANDIDATE:"local-candidate",MEDIA_SOURCE:"media-source",OUTBOUND_RTP:"outbound-rtp",REMOTE_CANDIDATE:"remote-candidate",REMOTE_INBOUND_RTP:"remote-inbound-rtp",TRACK:"track"},W={AUDIO_LEVEL:"audioLevel",AVAILABLE_OUTGOING_BITRATE:"availableOutgoingBitrate",AVAILABLE_INCOMING_BITRATE:"availableIncomingBitrate",BYTES_RECEIVED:"bytesReceived",BYTES_SENT:"bytesSent",CANDIDATE_TYPE:"candidateType",CHANNELS:"channels",CLOCK_RATE:"clockRate",CODEC_ID:"codecId",CURRENT_ROUND_TRIP_TIME:"currentRoundTripTime",ROUND_TRIP_TIME:"roundTripTime",FRACTION_LOST:"fractionLost",FRAME_HEIGHT:"frameHeight",FRAME_WIDTH:"frameWidth",QUALITY_LIMITATION_REASON:"qualityLimitationReason",QUALITY_LIMITATION_DURATIONS:"qualityLimitationDurations",QUALITY_LIMITATION_RESOLUTION_CHANGES:"qualityLimitationResolutionChanges",ID:"id",JITTER:"jitter",KIND:"kind",MEDIA_TYPE:"mediaType",MIME_TYPE:"mimeType",LOCAL_CANDIDATE_ID:"localCandidateId",NETWORK_TYPE:"networkType",RELAY_PROTOCOL:"relayProtocol",NOMINATED:"nominated",PACKETS_LOST:"packetsLost",PACKETS_RECEIVED:"packetsReceived",PACKETS_SENT:"packetsSent",PROTOCOL:"protocol",PORT:"port",REMOTE_CANDIDATE_ID:"remoteCandidateId",REMOTE_SOURCE:"remoteSource",RESPONSES_RECEIVED:"responsesReceived",SDP_FMTP_LINE:"sdpFmtpLine",SSRC:"ssrc",SELECTED:"selected",STATE:"state",TIMESTAMP:"timestamp",TOTAL_ROUND_TRIP_TIME:"totalRoundTripTime",TOTAL_ROUND_TRIP_TIME_MEASUREMENTS:"roundTripTimeMeasurements",TYPE:"type",DECODER_IMPLEMENTATION:"decoderImplementation",ENCODER_IMPLEMENTATION:"encoderImplementation",FRAMES_DECODED:"framesDecoded",FRAMES_ENCODED:"framesEncoded",FRAMES_PER_SECOND:"framesPerSecond",TOTAL_DECODE_TIME:"totalDecodeTime",TOTAL_ENCODE_TIME:"totalEncodeTime",PLI:"pliCount",NACK:"nackCount"},M={SUCCEEDED:"succeeded",AUDIO:"audio",VIDEO:"video"},ii={ETHERNET:0,CELLULAR_5G:2,WIFI:3,CELLULAR_4G:5,CELLULAR:10},wu={ETHERNET:"ethernet",CELLULAR_4G:"cellular",WIFI:"wifi"},ne={AUDIO:"audio",VIDEO:"video",NETWORK:"network",DATA:"data"},Ou="config ",fv=(c,t={},n)=>{const o={...n,...t};return t.pname||Ro(Ou,`Argument [String] 'cfg.pname' for the peerConnection name or id is missing - use generated '${n.pname}'`),t.cid||Ro(Ou,`Argument [String] 'cfg.cid' for the call name or id is missing - use generated '${n.cid}'`),t.uid||Ro(Ou,`Argument [String] 'cfg.uid' for the user name or id is missing - use generated '${n.uid}'`),o.pc=c,o},dv=(c={})=>{const t={...cv,...c};return t.name=lv(),t.version=ov(),t},li=(c,t,n,o=!1,a)=>{let s=c.map(r=>{if(!n)return r[t];if(!a)return r[t][n];const _=r[t][a];return _?_[n]:null});return s=s.filter(r=>o?Number.isFinite(r)&&r>0:Number.isFinite(r)),s.length===0?[]:s},Ms=c=>c.reduce((t,n)=>t+n,0)/c.length,hv=()=>`probe-${ni()}`,_v=()=>`coltr-${ni()}`,Od=c=>new Promise(t=>setTimeout(t,c)),Du=(c,t,n)=>{t?c.call(t,n):c(n)},Ke=(c,t,n,o)=>{const a=li(c,t,n,!0,o);if(a.length===0)return null;const s=a.reduce((h,m)=>h+m,0)/a.length;return s===0?null:a.map(h=>Math.abs(s-h)).reduce((h,m)=>h+m,0)/a.length*100/s},Qe=(c,t,n,o=!1,a)=>{const s=li(c,t,n,o,a);return s.length===0?null:s.reduce((r,_)=>r+_,0)/s.length},an=(c,t,n)=>li(c,t,n).reduce((a,s)=>a+s,0),Ye=(c,t,n,o)=>{const a=li(c,t,n,!0,o);return a.length===0?null:Math.min(...a)},Je=(c,t,n,o)=>{const a=li(c,t,n,!1,o);return a.length===0?null:Math.max(...a)},Ct=(c,t,n,o)=>{const a=c.slice().pop();if(!a)return null;if(!n)return a[t];if(!o)return a[t][n];const s=a[t][o];return s?s[n]:null},pv=c=>c.slice().pop(),dt=(c,t,n)=>{if(!t)return null;const o={};let a=t[M.AUDIO][c];a||(a=n===$e.INBOUND?{...Rd}:{...Id}),o[M.AUDIO]=a;let s=t[M.VIDEO][c];return s||(s=n===$e.INBOUND?{...bd}:{...wd}),o[M.VIDEO]=s,o},oi="exporter ",gv="2.0",Dd=(c,t,n)=>{if(!c||c.length===0)return 0;const o=c[c.length-1];if(!o)return 0;const a=o[t][n];if(a){const s=a.total_rtt_ms_out,r=a.total_rtt_measure_out;return!r||!s?Qe(c,t,"delta_rtt_ms_out",!1,n):Number(s/r)}return null},mv=(c,t)=>{if(!c||c.length===0)return 0;const n=c[c.length-1];if(!n)return 0;const o=n[t].total_rtt_connectivity_ms,a=n[t].total_rtt_connectivity_measure;return!a||!o?Qe(c,t,"delta_rtt_connectivity_ms"):Number(o/a)},Tv=c=>Ct(c,"network","local_candidate_type")!=="relay"?`direct/${Ct(c,"network","local_candidate_protocol")}`:`turn/${Ct(c,"network","local_candidate_relay_protocol")}`,vv=c=>{const t=Ct(c,"network","remote_candidate_type"),n=Ct(c,"network","remote_candidate_protocol");return t!=="relay"?`direct/${n}`:`turn/${n}`};class Sv{constructor(t){this._start=null,this._end=null,this._cfg=t,this._referenceReport=null,this._reports=[],this._events=[]}start(){bu(oi,"start() - start exporter...");const t=new Date;return this._start=t.toJSON(),t}stop(){bu(oi,"stop() - stop exporter...");const t=new Date;return this._end=t.toJSON(),t}saveReferenceReport(t){this._referenceReport=t}getReferenceReport(){return this._referenceReport}addReport(t){this._cfg.ticket&&(Ue(oi,`addReport() - add report to exporter at ${t.timestamp}`),this._reports.push(t))}addCustomEvent(t){this._events.push(t)}reset(){bu(oi,"resetReports() - reset reports"),this._reports=[],this._referenceReport=null,this._start=null,this._end=null}get ticket(){Ue(oi,"ticket() - generate ticket");const t=Ct(this._reports,"audio","total_packets_lost_in"),n=Ct(this._reports,"audio","total_packets_in"),o=Ct(this._reports,"video","total_packets_lost_in"),a=Ct(this._reports,"video","total_packets_in"),s={},r=pv(this._reports);return r&&(Object.keys(r[M.AUDIO]).forEach(_=>{const d=r[M.AUDIO][_];if(s[d.ssrc]={type:M.AUDIO,direction:d.direction},d.direction===$e.INBOUND){const h={avg:Qe(this._reports,M.AUDIO,"delta_jitter_ms_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_jitter_ms_in",_),max:Je(this._reports,M.AUDIO,"delta_jitter_ms_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_jitter_ms_in",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.AUDIO,"delta_kbs_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_kbs_in",_),max:Je(this._reports,M.AUDIO,"delta_kbs_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_kbs_in",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.AUDIO,"delta_KBytes_in",!1,_),min:Ye(this._reports,M.AUDIO,"delta_KBytes_in",_),max:Je(this._reports,M.AUDIO,"delta_KBytes_in",_),volatility:Ke(this._reports,M.AUDIO,"delta_KBytes_in",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={emodel:{avg:Qe(this._reports,M.AUDIO,"mos_emodel_in",!1,_),min:Ye(this._reports,M.AUDIO,"mos_emodel_in",_),max:Je(this._reports,M.AUDIO,"mos_emodel_in",_),volatility:Ke(this._reports,M.AUDIO,"mos_emodel_in",_)},effective:{avg:Qe(this._reports,M.AUDIO,"mos_in",!1,_),min:Ye(this._reports,M.AUDIO,"mos_in",_),max:Je(this._reports,M.AUDIO,"mos_in",_),volatility:Ke(this._reports,M.AUDIO,"mos_in",_)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}},E=Ct(this._reports,M.AUDIO,"total_packets_lost_in",_),C=Ct(this._reports,M.AUDIO,"total_packets_in",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].mos=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A}else{const h={avg:Qe(this._reports,M.AUDIO,"delta_jitter_ms_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_jitter_ms_out",_),max:Je(this._reports,M.AUDIO,"delta_jitter_ms_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_jitter_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.AUDIO,"delta_kbs_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_kbs_out",_),max:Je(this._reports,M.AUDIO,"delta_kbs_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_kbs_out",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.AUDIO,"delta_KBytes_out",!1,_),min:Ye(this._reports,M.AUDIO,"delta_KBytes_out",_),max:Je(this._reports,M.AUDIO,"delta_KBytes_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_KBytes_out",_),_unit:{avg:"KB",min:"KB",max:"KB",bitrate:"kbs",volatility:"percent"}},S={avg:Dd(this._reports,M.AUDIO,_),min:Ye(this._reports,M.AUDIO,"delta_rtt_ms_out",_),max:Je(this._reports,M.AUDIO,"delta_rtt_ms_out",_),volatility:Ke(this._reports,M.AUDIO,"delta_rtt_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Ct(this._reports,M.AUDIO,"total_packets_lost_out",_),C=Ct(this._reports,M.AUDIO,"total_packets_out",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}},R={emodel:{avg:Qe(this._reports,M.AUDIO,"mos_emodel_out",!1,_),min:Ye(this._reports,M.AUDIO,"mos_emodel_out",_),max:Je(this._reports,M.AUDIO,"mos_emodel_out",_),volatility:Ke(this._reports,M.AUDIO,"mos_emodel_out",_)},effective:{avg:Qe(this._reports,M.AUDIO,"mos_out",!1,_),min:Ye(this._reports,M.AUDIO,"mos_out",_),max:Je(this._reports,M.AUDIO,"mos_out",_),volatility:Ke(this._reports,M.AUDIO,"mos_out",_)},_unit:{avg:"number (1-5)",min:"number (1-5)",max:"number (1-5)",volatility:"percent"}};s[_].jitter=h,s[_].rtt=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A,s[_].mos=R}}),Object.keys(r[M.VIDEO]).forEach(_=>{const d=r[M.VIDEO][_];if(s[_]={type:M.VIDEO,direction:d.direction},d.direction===$e.INBOUND){const h={avg:Qe(this._reports,M.VIDEO,"delta_jitter_ms_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_jitter_ms_in",_),max:Je(this._reports,M.VIDEO,"delta_jitter_ms_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_jitter_ms_in",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.VIDEO,"delta_kbs_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_kbs_in",_),max:Je(this._reports,M.VIDEO,"delta_kbs_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_kbs_in",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.VIDEO,"delta_KBytes_in",!1,_),min:Ye(this._reports,M.VIDEO,"delta_KBytes_in",_),max:Je(this._reports,M.VIDEO,"delta_KBytes_in",_),volatility:Ke(this._reports,M.VIDEO,"delta_KBytes_in",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S=Ct(this._reports,M.VIDEO,"total_packets_lost_in",_),E=Ct(this._reports,M.VIDEO,"total_packets_in",_),C={lost:S,avg:Math.round((S/(S+E)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].traffic=T,s[_].bitrate=m,s[_].loss=C}else{const h={avg:Qe(this._reports,M.VIDEO,"delta_jitter_ms_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_jitter_ms_out",_),max:Je(this._reports,M.VIDEO,"delta_jitter_ms_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_jitter_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},m={avg:Qe(this._reports,M.VIDEO,"delta_kbs_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_kbs_out",_),max:Je(this._reports,M.VIDEO,"delta_kbs_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_kbs_out",_),_unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},T={avg:Qe(this._reports,M.VIDEO,"delta_KBytes_out",!1,_),min:Ye(this._reports,M.VIDEO,"delta_KBytes_out",_),max:Je(this._reports,M.VIDEO,"delta_KBytes_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_KBytes_out",_),_unit:{avg:"KB",min:"KB",max:"KB",volatility:"percent"}},S={avg:Dd(this._reports,M.VIDEO,_),min:Ye(this._reports,M.VIDEO,"delta_rtt_ms_out",_),max:Je(this._reports,M.VIDEO,"delta_rtt_ms_out",_),volatility:Ke(this._reports,M.VIDEO,"delta_rtt_ms_out",_),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},E=Ct(this._reports,M.VIDEO,"total_packets_lost_out",_),C=Ct(this._reports,M.VIDEO,"total_packets_out",_),A={lost:E,avg:Math.round((E/(E+C)*100||0)*100)/100,_unit:{avg:"percent",lost:"number"}};s[_].jitter=h,s[_].rtt=S,s[_].traffic=T,s[_].bitrate=m,s[_].loss=A}})),{version:gv,configuration:{frequency:this._cfg.refreshEvery},started:this._start,ended:this._end,ua:{agent:navigator.userAgent,pname:this._cfg.pname,user_id:this._cfg.uid},call:{call_id:this._cfg.cid,events:this._events},details:{count:this._reports.length,reports:this._cfg.record?this._reports:[],reference:this._referenceReport||null},ssrc:s,data:{rtt:{avg:mv(this._reports,"data"),min:Ye(this._reports,"data","delta_rtt_connectivity_ms"),max:Je(this._reports,"data","delta_rtt_connectivity_ms"),volatility:Ke(this._reports,"data","delta_rtt_connectivity_ms"),_unit:{avg:"ms",min:"ms",max:"ms",volatility:"percent"}},packetsLost:{audio:{in:{avg:Math.round((t/(t+n)*100||0)*100)/100}},video:{in:{avg:Math.round((o/(o+a)*100||0)*100)/100}},unit:{avg:"percent"}},bitrate:{in:{avg:Qe(this._reports,"data","delta_kbs_in"),min:Ye(this._reports,"data","delta_kbs_in"),max:Je(this._reports,"data","delta_kbs_in"),volatility:Ke(this._reports,"data","delta_kbs_in")},out:{avg:Qe(this._reports,"data","delta_kbs_out"),min:Ye(this._reports,"data","delta_kbs_out"),max:Je(this._reports,"data","delta_kbs_out"),volatility:Ke(this._reports,"data","delta_kbs_out")},unit:{avg:"kbs",min:"kbs",max:"kbs",volatility:"percent"}},traffic:{in:{avg:Qe(this._reports,"data","delta_KBytes_in"),min:Ye(this._reports,"data","delta_KBytes_in"),max:Je(this._reports,"data","delta_KBytes_in"),volatility:Ke(this._reports,"data","delta_KBytes_in")},out:{avg:Qe(this._reports,"data","delta_KBytes_out"),min:Ye(this._reports,"data","delta_KBytes_out"),max:Je(this._reports,"data","delta_KBytes_out"),volatility:Ke(this._reports,"data","delta_KBytes_out")},unit:{avg:"KBytes",min:"KBytes",max:"KBytes",volatility:"percent"}},network:{localConnection:Tv(this._reports),remoteConnection:vv(this._reports)}}}}updateConfig(t){this._cfg=t}getLastReport(){return this._reports.slice().pop()||null}getBeforeLastReport(){const t=this._reports.slice();return t.pop(),t.pop()||null}getReportsNumber(){return this._reports.length}}const Ls="extractor ",Nd=(c,t,n,o)=>{let a=!1;const s=o[t].total_rtt_ms_out,r=o[t].total_rtt_measure_out,_=n?n[t].total_rtt_ms_out:0,d=n?n[t].total_rtt_measure_out:0,h={rtt:null,totalRTT:s,totalRTTMeasurements:r};if(c[W.TIMESTAMP]===o[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,W.ROUND_TRIP_TIME)||Object.prototype.hasOwnProperty.call(c,W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS)&&(a=!0,Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])===0||Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d===r))return h;const m=1e3*Number(c[W.ROUND_TRIP_TIME]);let T=s+m,S=r+1;return a&&(T=1e3*Number(c[W.TOTAL_ROUND_TRIP_TIME])-_,S=Number(c[W.TOTAL_ROUND_TRIP_TIME_MEASUREMENTS])-d),{rtt:m,totalRTT:T,totalRTTMeasurements:S}},Ev=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.CURRENT_ROUND_TRIP_TIME))return{rtt:null,totalRTT:o[t].total_rtt_connectivity_ms,totalRTTMeasurements:o[t].total_rtt_connectivity_measure};const a=1e3*Number(c[W.CURRENT_ROUND_TRIP_TIME]);let s=o[t].total_rtt_connectivity_ms+a,r=o[t].total_rtt_connectivity_measure+1;return Object.prototype.hasOwnProperty.call(c,W.TOTAL_ROUND_TRIP_TIME)&&(s=1e3*Number(c[W.TOTAL_ROUND_TRIP_TIME])-(n?n[t].total_rtt_connectivity_ms:0)),Object.prototype.hasOwnProperty.call(c,W.RESPONSES_RECEIVED)&&(r=Number(c[W.RESPONSES_RECEIVED])-(n?n[t].total_rtt_connectivity_measure:0)),{rtt:a,totalRTT:s,totalRTTMeasurements:r}},Io=(c,t,n)=>c[W.TIMESTAMP]===n[t].timestamp_out||!Object.prototype.hasOwnProperty.call(c,W.JITTER)?null:1e3*(Number(c[W.JITTER])||0),yv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,W.FRAMES_DECODED)||!Object.prototype.hasOwnProperty.call(c,W.TOTAL_DECODE_TIME))return{delta_ms_decode_frame:t[M.VIDEO].delta_ms_decode_frame_in,frames_decoded:t[M.VIDEO].total_frames_decoded_in,total_decode_time:t[M.VIDEO].total_time_decoded_in};const n=c[W.FRAMES_DECODED],o=c[W.TOTAL_DECODE_TIME],a=o-t[M.VIDEO].total_time_decoded_in,s=n-t[M.VIDEO].total_frames_decoded_in;return{delta_ms_decode_frame:s>0?a*1e3/s:0,frames_decoded:n,total_decode_time:o}},Cv=(c,t)=>{if(!Object.prototype.hasOwnProperty.call(c,W.FRAMES_ENCODED)||!Object.prototype.hasOwnProperty.call(c,W.TOTAL_ENCODE_TIME))return{delta_ms_encode_frame:t[M.VIDEO].delta_ms_encode_frame_out,frames_encoded:t[M.VIDEO].total_frames_encoded_out,total_encode_time:t[M.VIDEO].total_time_encoded_out};const n=c[W.FRAMES_ENCODED],o=c[W.TOTAL_ENCODE_TIME],a=o-t[M.VIDEO].total_time_encoded_out,s=n-t[M.VIDEO].total_frames_encoded_out;return{delta_ms_encode_frame:s>0&&a?a*1e3/s:0,frames_encoded:n,total_encode_time:o}},xd=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PACKETS_SENT)||!Object.prototype.hasOwnProperty.call(c,W.BYTES_SENT))return{packetsSent:n[t].total_packets_out,packetsLost:n[t].total_packets_lost_out,bytesSent:n[t].total_KBytes_out};const a=Number(c[W.PACKETS_SENT])||0-(o?o[t].total_packets_out:0),s=a-n[t].total_packets_out,r=Number(c[W.BYTES_SENT])/1024-(o?o[t].total_KBytes_out:0),_=r-n[t].total_KBytes_out,d=c[W.TIMESTAMP]||Date.now(),h=o?o.timestamp:null;let m=n.timestamp;!m&&h&&(m=h);const T=m?d-m:0,S=T>0?_*.008*1024/T*1e3:0;return{packetsSent:a,deltaPacketsSent:s,KBytesSent:r,deltaKBytesSent:_,kbsSent:S}},Ud=(c,t,n,o)=>{let a=n[t].total_packets_lost_out,s=0,r=0;return Object.prototype.hasOwnProperty.call(c,W.PACKETS_LOST)&&(a=Number(c[W.PACKETS_LOST])||0-(o?o[t].total_packets_lost_out:0),s=a-n[t].total_packets_lost_out),Object.prototype.hasOwnProperty.call(c,W.FRACTION_LOST)&&(r=Number(100*c[W.FRACTION_LOST])),{packetsLost:a,deltaPacketsLost:s,fractionLost:r}},kd=(c,t,n,o)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PACKETS_RECEIVED)||!Object.prototype.hasOwnProperty.call(c,W.PACKETS_LOST)||!Object.prototype.hasOwnProperty.call(c,W.BYTES_RECEIVED))return{percent_packets_lost:n[t].percent_packets_lost_in,packetsReceived:n[t].total_packets_in,packetsLost:n[t].total_packets_lost_in,bytesReceived:n[t].total_KBytes_in};const a=Number(c[W.PACKETS_RECEIVED])||0-(o?o[t].total_packets_in:0),s=Number(c[W.PACKETS_LOST])||0-(o?o[t].total_packets_lost_in:0),r=s-n[t].total_packets_lost_in,_=a-n[t].total_packets_in,d=a!==n[t].total_packets_in?r*100/(r+_):0,h=Number(c[W.BYTES_RECEIVED])/1024-(o?o[t].total_KBytes_in:0),m=h-n[t].total_KBytes_in,T=c[W.TIMESTAMP]||Date.now(),S=o?o.timestamp:null;let E=n.timestamp;!E&&S&&(E=S);const C=E?T-E:0,A=C>0?m*.008*1024/C*1e3:0;return{percentPacketsLost:d,packetsReceived:a,deltaPacketsReceived:_,packetsLost:s,deltaPacketsLost:r,KBytesReceived:h,deltaKBytesReceived:m,kbsReceived:A}},Av=c=>c[W.CANDIDATE_TYPE]!=="relay"?"":c[W.RELAY_PROTOCOL]||"",Rv=c=>{if(!Object.prototype.hasOwnProperty.call(c,W.NETWORK_TYPE))return ii.WIFI;switch(c[W.NETWORK_TYPE]){case wu.ETHERNET:return ii.ETHERNET;case wu.CELLULAR_4G:return ii.CELLULAR_4G;case wu.WIFI:return ii.WIFI;default:return ii.CELLULAR}},Pd=c=>!Object.prototype.hasOwnProperty.call(c,W.FRAME_HEIGHT)||!Object.prototype.hasOwnProperty.call(c,W.FRAME_WIDTH)?{width:null,height:null,framerate:null}:{width:c[W.FRAME_WIDTH]||null,height:c[W.FRAME_HEIGHT]||null,framerate:c[W.FRAMES_PER_SECOND]},Iv=c=>{const t=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_REASON)?c[W.QUALITY_LIMITATION_REASON]:null,n=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_RESOLUTION_CHANGES)?c[W.QUALITY_LIMITATION_RESOLUTION_CHANGES]:null,o=Object.prototype.hasOwnProperty.call(c,W.QUALITY_LIMITATION_DURATIONS)?c[W.QUALITY_LIMITATION_DURATIONS]:null;return o&&Object.keys(o).forEach(a=>{o[a]>1e3&&(o[a]=Number(o[a]/1e3))}),{reason:t,durations:o,resolutionChanges:n}},bv=(c,t,n)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PLI)||!Object.prototype.hasOwnProperty.call(c,W.NACK))return{pliCount:t.total_pli_sent_in,nackCount:t.total_nack_sent_in,deltaPliCount:0,deltaNackCount:0};const o=(c[W.PLI]||0)-(n?n[M.VIDEO].total_pli_sent_in:0),a=(c[W.NACK]||0)-(n?n[M.VIDEO].total_nack_sent_in:0);return{pliCount:o,nackCount:a,deltaPliCount:o-t[M.VIDEO].total_pli_sent_in,deltaNackCount:a-t[M.VIDEO].total_nack_sent_in}},wv=(c,t,n)=>{if(!Object.prototype.hasOwnProperty.call(c,W.PLI)||!Object.prototype.hasOwnProperty.call(c,W.NACK))return{pliCount:t.total_pli_received_out,nackCount:t.total_nack_received_out,deltaPliCount:0,deltaNackCount:0};const o=(c[W.PLI]||0)-(n?n[M.VIDEO].total_pli_received_out:0),a=(c[W.NACK]||0)-(n?n[M.VIDEO].total_nack_received_out:0);return{pliCount:o,nackCount:a,deltaPliCount:o-t[M.VIDEO].total_pli_received_out,deltaNackCount:a-t[M.VIDEO].total_nack_received_out}},Ov=c=>({channels:c[W.CHANNELS]||null,clock_rate:c[W.CLOCK_RATE]||null,mime_type:c[W.MIME_TYPE]||null,sdp_fmtp_line:c[W.SDP_FMTP_LINE]||null}),Dv=c=>({clock_rate:c[W.CLOCK_RATE]||null,mime_type:c[W.MIME_TYPE]||null}),Nv=(c,t,n)=>{const o=(c[W.BYTES_RECEIVED]||0)/1024-(n?n.data.total_KBytes_in:0),a=(c[W.BYTES_SENT]||0)/1024-(n?n.data.total_KBytes_out:0),s=c[W.TIMESTAMP]||Date.now(),r=o-t.data.total_KBytes_in,_=a-t.data.total_KBytes_out,d=n?n.timestamp:null;let h=t.timestamp;!h&&d&&(h=d);const m=h?s-h:0,T=m>0?r*.008*1024/m*1e3:0,S=m>0?_*.008*1024/m*1e3:0;return{total_KBytes_received:o,total_KBytes_sent:a,delta_KBytes_received:r,delta_KBytes_sent:_,kbs_speed_received:T,kbs_speed_sent:S}},xv=c=>{const t=c[W.AVAILABLE_INCOMING_BITRATE]/1024||0,n=c[W.AVAILABLE_OUTGOING_BITRATE]/1024||0;return{kbs_incoming_bandwidth:t,kbs_outgoing_bandwidth:n}},Uv=(c,t,n,o)=>{if(!c)return[];switch(c[W.TYPE]){case Qt.CANDIDATE_PAIR:let a=!1;if(c[W.NOMINATED]&&c[W.STATE]===M.SUCCEEDED&&(a=!0,Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c),W.SELECTED in c&&!c[W.SELECTED]&&(a=!1)),a){const r=c[W.LOCAL_CANDIDATE_ID],_=c[W.REMOTE_CANDIDATE_ID],d=Nv(c,t,o),h=xv(c),m=Ev(c,"data",o,t);return[{type:ne.NETWORK,value:{local_candidate_id:r}},{type:ne.NETWORK,value:{remote_candidate_id:_}},{type:ne.DATA,value:{total_KBytes_in:d.total_KBytes_received}},{type:ne.DATA,value:{total_KBytes_out:d.total_KBytes_sent}},{type:ne.DATA,value:{delta_KBytes_in:d.delta_KBytes_received}},{type:ne.DATA,value:{delta_KBytes_out:d.delta_KBytes_sent}},{type:ne.DATA,value:{delta_kbs_in:d.kbs_speed_received}},{type:ne.DATA,value:{delta_kbs_out:d.kbs_speed_sent}},{type:ne.DATA,value:{delta_kbs_bandwidth_in:h.kbs_incoming_bandwidth}},{type:ne.DATA,value:{delta_kbs_bandwidth_out:h.kbs_outgoing_bandwidth}},{type:ne.DATA,value:{delta_rtt_connectivity_ms:m.rtt}},{type:ne.DATA,value:{total_rtt_connectivity_ms:m.totalRTT}},{type:ne.DATA,value:{total_rtt_connectivity_measure:m.totalRTTMeasurements}}]}break;case Qt.LOCAL_CANDIDATE:if(c[W.ID]===t.network.local_candidate_id)return[{type:ne.NETWORK,value:{infrastructure:Rv(c)}},{type:ne.NETWORK,value:{local_candidate_type:c[W.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{local_candidate_protocol:c[W.PROTOCOL]||""}},{type:ne.NETWORK,value:{local_candidate_relay_protocol:Av(c)}}];break;case Qt.REMOTE_CANDIDATE:if(c[W.ID]===t.network.remote_candidate_id)return[{type:ne.NETWORK,value:{remote_candidate_type:c[W.CANDIDATE_TYPE]||""}},{type:ne.NETWORK,value:{remote_candidate_protocol:c[W.PROTOCOL]||""}}];break;case Qt.INBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.INBOUND);_&&(_.timestamp=t.timestamp);const d=dt(r,o,$e.INBOUND);if(d&&(d.timestamp=o.timestamp),c[W.MEDIA_TYPE]===M.AUDIO){const h=kd(c,M.AUDIO,_,d),m=Io(c,M.AUDIO,_),T=c[W.CODEC_ID]||"";return[{ssrc:r,type:ne.AUDIO,value:{codec_id_in:T}},{ssrc:r,type:ne.AUDIO,value:{total_packets_in:h.packetsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_in:h.deltaPacketsReceived}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_in:h.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_in:h.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_in:h.percentPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_in:h.KBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_in:h.deltaKBytesReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_in:h.kbsReceived}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_in:m}}]}if(c[W.MEDIA_TYPE]===M.VIDEO){const h=yv(c,_),m=kd(c,M.VIDEO,_,d),T=Io(c,M.VIDEO,_),S=c[W.DECODER_IMPLEMENTATION]||null,E=c[W.CODEC_ID]||null,C=Pd(c),A=bv(c,_,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_in:E}},{ssrc:r,type:ne.VIDEO,value:{total_packets_in:m.packetsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_in:m.deltaPacketsReceived}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_in:m.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_in:m.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_in:m.percentPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_in:m.KBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_in:m.deltaKBytesReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_in:m.kbsReceived}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_in:T}},{ssrc:r,type:ne.VIDEO,value:{decoder_in:S}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_decode_frame_in:h.delta_ms_decode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_decoded_in:h.frames_decoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_decoded_in:h.total_decode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_sent_in:A.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_sent_in:A.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_sent_in:A.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_sent_in:A.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_in:C}}]}break}case Qt.OUTBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.OUTBOUND);_&&(_.timestamp=t.timestamp);const d=dt(r,o,$e.OUTBOUND);if(d&&(d.timestamp=o.timestamp),c[W.MEDIA_TYPE]===M.AUDIO){const h=c[W.CODEC_ID]||null,m=xd(c,M.AUDIO,_,d);return[{ssrc:r,type:ne.AUDIO,value:{codec_id_out:h}},{ssrc:r,type:ne.AUDIO,value:{total_packets_out:m.packetsSent}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_out:m.deltaPacketsSent}},{ssrc:r,type:ne.AUDIO,value:{total_KBytes_out:m.KBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_KBytes_out:m.deltaKBytesSent}},{ssrc:r,type:ne.AUDIO,value:{delta_kbs_out:m.kbsSent}}]}if(c[W.MEDIA_TYPE]===M.VIDEO){const h=c[W.ENCODER_IMPLEMENTATION]||null,m=c[W.CODEC_ID]||null,T=Cv(c,_),S=Pd(c),E=Iv(c),C=wv(c,_,d),A=xd(c,M.VIDEO,_,d);return[{ssrc:r,type:ne.VIDEO,value:{codec_id_out:m}},{ssrc:r,type:ne.VIDEO,value:{total_packets_out:A.packetsSent}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_out:A.deltaPacketsSent}},{ssrc:r,type:ne.VIDEO,value:{total_KBytes_out:A.KBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_KBytes_out:A.deltaKBytesSent}},{ssrc:r,type:ne.VIDEO,value:{delta_kbs_out:A.kbsSent}},{ssrc:r,type:ne.VIDEO,value:{encoder_out:h}},{ssrc:r,type:ne.VIDEO,value:{delta_ms_encode_frame_out:T.delta_ms_encode_frame}},{ssrc:r,type:ne.VIDEO,value:{total_frames_encoded_out:T.frames_encoded}},{ssrc:r,type:ne.VIDEO,value:{total_time_encoded_out:T.total_encode_time}},{ssrc:r,type:ne.VIDEO,value:{total_nack_received_out:C.nackCount}},{ssrc:r,type:ne.VIDEO,value:{delta_nack_received_out:C.deltaNackCount}},{ssrc:r,type:ne.VIDEO,value:{total_pli_received_out:C.pliCount}},{ssrc:r,type:ne.VIDEO,value:{delta_pli_received_out:C.deltaPliCount}},{ssrc:r,type:ne.VIDEO,value:{size_out:S}},{ssrc:r,type:ne.VIDEO,value:{limitation_out:E}}]}break}case Qt.MEDIA_SOURCE:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);break}case Qt.TRACK:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);break}case Qt.CODEC:const s=[];return Object.keys(t[M.AUDIO]).forEach(r=>{const _=t[M.AUDIO][r];if(_.codec_id_in===c[W.ID]||_.codec_id_out===c[W.ID]){Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const d=Ov(c);c[W.ID]===_.codec_id_in?s.push({ssrc:_.ssrc,type:ne.AUDIO,value:{codec_in:d}}):s.push({ssrc:_.ssrc,type:ne.AUDIO,value:{codec_out:d}})}}),Object.keys(t[M.VIDEO]).forEach(r=>{const _=t[M.VIDEO][r];if(_.codec_id_in===c[W.ID]||_.codec_id_out===c[W.ID]){Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const d=Dv(c);c[W.ID]===_.codec_id_in?s.push({ssrc:_.ssrc,type:ne.VIDEO,value:{codec_in:d}}):s.push({ssrc:_.ssrc,type:ne.VIDEO,value:{codec_out:d}})}}),s;case Qt.REMOTE_INBOUND_RTP:{Ue(Ls,`analyze() - got stats ${c[W.TYPE]} for ${n}`,c);const r=c[W.SSRC],_=dt(r,t,$e.OUTBOUND),d=dt(r,o,$e.OUTBOUND);if(c[W.KIND]===M.AUDIO){const h=Nd(c,M.AUDIO,d,_),m=Io(c,M.AUDIO,_),T=Ud(c,M.AUDIO,_,d);return[{ssrc:r,type:ne.AUDIO,value:{delta_rtt_ms_out:h.rtt}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_ms_out:h.totalRTT}},{ssrc:r,type:ne.AUDIO,value:{total_rtt_measure_out:h.totalRTTMeasurements}},{ssrc:r,type:ne.AUDIO,value:{delta_jitter_ms_out:m}},{ssrc:r,type:ne.AUDIO,value:{timestamp_out:c[W.TIMESTAMP]}},{ssrc:r,type:ne.AUDIO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.AUDIO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.AUDIO,value:{percent_packets_lost_out:T.fractionLost}}]}if(c[W.KIND]===M.VIDEO){const h=Nd(c,M.VIDEO,d,_),m=Io(c,M.VIDEO,_),T=Ud(c,M.VIDEO,_,d);return[{ssrc:r,type:ne.VIDEO,value:{delta_rtt_ms_out:h.rtt}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_ms_out:h.totalRTT}},{ssrc:r,type:ne.VIDEO,value:{total_rtt_measure_out:h.totalRTTMeasurements}},{ssrc:r,type:ne.VIDEO,value:{delta_jitter_ms_out:m}},{ssrc:r,type:ne.VIDEO,value:{timestamp_out:c[W.TIMESTAMP]}},{ssrc:r,type:ne.VIDEO,value:{total_packets_lost_out:T.packetsLost}},{ssrc:r,type:ne.VIDEO,value:{delta_packets_lost_out:T.deltaPacketsLost}},{ssrc:r,type:ne.VIDEO,value:{percent_packets_lost_out:T.fractionLost}}]}break}}return[]},bo=c=>c<0?1:c>100?4.5:1+.035*c+7/1e6*c*(c-60)*(100-c),kv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.INBOUND),r=dt(a,n,$e.INBOUND),_=dt(a,o,$e.INBOUND),d=[],h=[],m=s[t].percent_packets_lost_in,T=s[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=_&&_[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=n&&n.data.delta_rtt_connectivity_ms||null,R=o&&o.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&h.push(T),n&&S&&h.push(S),o&&E&&h.push(E);const L=d.length>0?Ms(d):100,b=h.length>0?Ms(h):10,ie=93.2-m,N=.18*ie*ie-27.9*ie+1126.62,F=(L+b)/2,me=F-177.3<0?0:1,_e=.024*F+.11*(F-177.3)*me,U=N-_e;return bo(U)},Pv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.OUTBOUND),r=dt(a,n,$e.OUTBOUND),_=dt(a,o,$e.OUTBOUND),d=[],h=[],m=s[t].percent_packets_lost_out,T=s[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=_&&_[t].delta_rtt_ms_out||null,C=s[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=_&&_[t].delta_jitter_ms_out||null,L=c.data.delta_rtt_connectivity_ms,b=n&&n.data.delta_rtt_connectivity_ms||null,ie=o&&o.data.delta_rtt_connectivity_ms||null;T?d.push(T):L&&d.push(L),S?d.push(S):b&&d.push(b),E?d.push(E):ie&&d.push(ie),C&&h.push(C),n&&A&&h.push(A),o&&R&&h.push(R);const N=d.length>0?Ms(d):100,F=h.length>0?Ms(h):10,me=93.2-m,_e=.18*me*me-27.9*me+1126.62,U=(N+F)/2,x=U-177.3<0?0:1,q=.024*U+.11*(U-177.3)*x,j=_e-q;return bo(j)},Mv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.INBOUND),r=dt(a,n,$e.INBOUND),_=dt(a,o,$e.INBOUND),d=[],h=[],m=s[t].percent_packets_lost_in/100,T=s[t].delta_jitter_ms_in,S=r&&r[t].delta_jitter_ms_in||null,E=_&&_[t].delta_jitter_ms_in||null,C=c.data.delta_rtt_connectivity_ms,A=n&&n.data.delta_rtt_connectivity_ms||null,R=o&&o.data.delta_rtt_connectivity_ms||null;C&&d.push(C),A&&d.push(A),R&&d.push(R),T&&h.push(T),r&&S&&h.push(S),_&&E&&h.push(E);const L=d.length>0?Ms(d):100,b=h.length>0?Ms(h):10,ie=0,N=19.8,F=29.7,me=30,_e=(L+b)/2+me,U=_e-177.3<0?0:1,x=.024*_e+.11*(_e-177.3)*U,j=93.2-(ie+N*Math.log(1+F*m)+x);return bo(j)},Lv=(c,t=M.AUDIO,n,o,a)=>{const s=dt(a,c,$e.OUTBOUND),r=dt(a,n,$e.OUTBOUND),_=dt(a,o,$e.OUTBOUND),d=[],h=[],m=s[t].percent_packets_lost_out/100,T=s[t].delta_rtt_ms_out,S=r&&r[t].delta_rtt_ms_out||null,E=_&&_[t].delta_rtt_ms_out||null,C=s[t].delta_jitter_ms_out,A=r&&r[t].delta_jitter_ms_out||null,R=_&&_[t].delta_jitter_ms_out||null,L=c.data.delta_rtt_connectivity_ms,b=n&&n.data.delta_rtt_connectivity_ms||null,ie=o&&o.data.delta_rtt_connectivity_ms||null;T?d.push(T):L&&d.push(L),S?d.push(S):b&&d.push(b),E?d.push(E):ie&&d.push(ie),C&&h.push(C),r&&A&&h.push(A),_&&R&&h.push(R);const N=d.length>0?Ms(d):100,F=h.length>0?Ms(h):10,me=0,_e=19.8,U=29.7,x=30,q=(N+F)/2+x,j=q-177.3<0?0:1,Y=.024*q+.11*(q-177.3)*j,X=93.2-(me+_e*Math.log(1+U*m)+Y);return bo(X)};class $v{constructor(t,n){this._callbacks={onreport:null,onticket:null},this._id=_v(),this._moduleName=this._id,this._probeId=n,this._config=t,this._exporter=new Sv(t),this._state=ys.IDLE,this.registerToPCEvents(),on(this._moduleName,`new collector created for probe ${this._probeId}`)}analyze(t,n,o,a){const s=(d,h)=>d===M.AUDIO?h===Qt.INBOUND_RTP?{...Rd}:{...Id}:h===Qt.INBOUND_RTP?{...bd}:{...wd},r=uv(n);r.pname=this._config.pname,r.call_id=this._config.cid,r.user_id=this._config.uid,r.count=n?n.count+1:1;let _=null;return t.forEach(d=>{!_&&d.timestamp&&(_=d.timestamp),Uv(d,r,r.pname,a).forEach(m=>{if(m.value&&m.type)if(m.ssrc){let T=r[m.type][m.ssrc];T||(T=s(m.type,d.type),T.ssrc=m.ssrc,r[m.type][m.ssrc]=T),Object.keys(m.value).forEach(S=>{T[S]=m.value[S]})}else Object.keys(m.value).forEach(T=>{r[m.type][T]=m.value[T]})})}),r.timestamp=_,Object.keys(r[M.AUDIO]).forEach(d=>{const h=r[M.AUDIO][d];h.direction===$e.INBOUND?(h.mos_emodel_in=kv(r,M.AUDIO,n,o,h.ssrc),h.mos_in=Mv(r,M.AUDIO,n,o,h.ssrc)):(h.mos_emodel_out=Pv(r,M.AUDIO,n,o,h.ssrc),h.mos_out=Lv(r,M.AUDIO,n,o,h.ssrc))}),r}async takeReferenceStats(){return new Promise((t,n)=>{const o=Date.now();setTimeout(async()=>{try{const a=Date.now()-o,s=Date.now(),r=await this._config.pc.getStats(),_=this.analyze(r,null,null,null),d=Date.now();_.experimental.time_to_measure_ms=d-s,_.experimental.time_to_wait_ms=a,this._exporter.saveReferenceReport(_),Ue(this._moduleName,`got reference report for probe ${this._probeId}`),t()}catch(a){n(a)}},this._config.startAfter)})}async collectStats(){try{if(this._state!==ys.RUNNING||!this._config.pc)return Ue(this._moduleName,`report discarded (too late) for probe ${this._probeId}`),null;const t=Date.now(),n=await this._config.pc.getStats(),o=this.analyze(n,this._exporter.getLastReport(),this._exporter.getBeforeLastReport(),this._exporter.getReferenceReport()),a=Date.now();return o.experimental.time_to_measure_ms=a-t,this._exporter.addReport(o),Ue(this._moduleName,`got report for probe ${this._probeId}#${this._exporter.getReportsNumber()+1}`),this.fireOnReport(o),o}catch(t){return jn(this._moduleName,`got error ${t}`),null}}async start(){Ue(this._moduleName,"starting"),this.state=ys.RUNNING,this._startedTime=this._exporter.start(),Ue(this._moduleName,"started")}async mute(){this.state=ys.MUTED,Ue(this._moduleName,"muted")}async unmute(){this.state=ys.RUNNING,Ue(this._moduleName,"unmuted")}async stop(t){if(Ue(this._moduleName,`stopping${t?" by watchdog":""}...`),this._stoppedTime=this._exporter.stop(),this.state=ys.IDLE,this._config.ticket){const{ticket:n}=this._exporter;this.fireOnTicket(n)}this._exporter.reset(),Ue(this._moduleName,"stopped")}registerCallback(t,n,o){t in this._callbacks?(this._callbacks[t]={callback:n,context:o},Ue(this._moduleName,`registered callback '${t}'`)):jn(this._moduleName,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):jn(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReport(t){this._callbacks.onreport&&Du(this._callbacks.onreport.callback,this._callbacks.onreport.context,t)}fireOnTicket(t){this._callbacks.onticket&&Du(this._callbacks.onticket.callback,this._callbacks.onticket.context,t)}updateConfig(t){this._config=t,this._exporter.updateConfig(t)}get state(){return this._state}set state(t){this._state=t,Ue(this._moduleName,`state changed to ${t}`)}addCustomEvent(t,n,o,a){this._exporter.addCustomEvent({at:typeof t=="object"?t.toJSON():t,category:n,name:o,description:a})}async registerToPCEvents(){const{pc:t}=this._config;if(navigator.mediaDevices.ondevicechange=async()=>{try{const n=await navigator.mediaDevices.enumerateDevices();this.addCustomEvent(new Date().toJSON(),"device",`${n.length} devices found`,"Media Devices state")}catch{jn(this._moduleName,"can't get devices")}},t){t.oniceconnectionstatechange=()=>{const o=t.iceConnectionState;o===ri.CONNECTED||o===ri.COMPLETED?this.addCustomEvent(new Date().toJSON(),"call",o,"ICE connection state"):o===ri.DISCONNECTED||o===ri.FAILED?this.addCustomEvent(new Date().toJSON(),"call",o,"ICE connection state"):o===ri.CLOSED&&this.addCustomEvent(new Date().toJSON(),"call","ended","ICE connection state")},t.onicegatheringstatechange=()=>{const o=t.iceGatheringState;this.addCustomEvent(new Date().toJSON(),"call",o,"ICE gathering state")},t.ontrack=o=>{this.addCustomEvent(new Date().toJSON(),"call",`${o.track.kind}track`,"MediaStreamTrack received")},t.onnegotiationneeded=()=>{this.addCustomEvent(new Date().toJSON(),"call","negotiation","Media changed")};const n=t.getReceivers();if(n&&n.length>0){const o=n[0],{transport:a}=o;if(a){const{iceTransport:s}=a;s&&(s.onselectedcandidatepairchange=()=>{this.addCustomEvent(new Date().toJSON(),"call","transport","Candidates Pair changed")})}}}}}class Hv{constructor(t){this._id=t.pname&&t.pname.substr(0,12).padEnd(12," ")||hv(),this._moduleName=this._id,on(this._moduleName,"probe created"),this._config=t,this._collector=new $v(this._config,this._id)}set onreport(t){t?this._collector.registerCallback("onreport",t):this._collector.unregisterCallback("onreport")}set onticket(t){t?this._collector.registerCallback("onticket",t):this._collector.unregisterCallback("onticket")}get id(){return this._id}get pname(){return this._config.pname}get cid(){return this._config.cid}get uid(){return this._config.uid}get state(){return this._collector.state}set state(t){this._collector.state=t}addCustomEvent(t,n,o,a=new Date().toJSON()){this._collector.addCustomEvent(a,n,t,o)}get isRunning(){return this._collector.state===ys.RUNNING}get isIdle(){return this._collector.state===ys.IDLE}updateUserId(t){this._config.uid=t,this._collector.updateConfig(this._config)}updateCallId(t){this._config.cid=t,this._collector.updateConfig(this._config)}start(){if(!this.isIdle){Ro(this._moduleName,"probe is already running");return}this._collector.start()}stop(t=!1){this.isRunning&&this._collector.stop(t)}async takeReferenceStats(){return this._collector.takeReferenceStats()}async collectStats(){return this._collector.collectStats()}}const bt="engine ";class Fv{constructor(t){this._config=t,this._probes=[],this._startedTime=null,this._callbacks={onresult:null},on(bt,`configured for probing every ${this._config.refreshEvery}ms`),on(bt,`configured for starting after ${this._config.startAfter}ms`),on(bt,`${!this._config.stopAfter||this._config.stopAfter!==-1?`configured for stopped after ${this._config.stopAfter}ms`:"configured for never stopped"}`),Ue(bt,"engine initialized")}get probes(){return this._probes}get isRunning(){return this._probes.some(t=>t.isRunning)}get isIdle(){return this._probes.every(t=>t.isIdle)}addNewProbe(t,n){if(!t)throw new Error("undefined peer connection");const o=fv(t,n,this._config),a=new Hv(o);return this._probes.push(a),Ue(bt,`${this._probes.length} probes registered`),a}removeExistingProbe(t){if(!t)throw new Error("undefined probe");t.state===ys.RUNNING&&t.stop(),this._probes=this._probes.filter(n=>t.id!==n.id)}async start(){const t=()=>{this._probes.forEach(s=>s.start())},n=async()=>Promise.all(this._probes.map(s=>s.takeReferenceStats())),o=()=>this.isIdle?!1:!this._config.stopAfter||this._config.stopAfter<0?!0:Date.now()<this._startedTime+this._config.stopAfter,a=async()=>{const s=av(),r=this._probes.filter(_=>_.isRunning);for(const _ of r){const d=await _.collectStats();d&&s.probes.push(d),Ue(bt,`got probe ${_.id}`),await Od(0)}return s.delta_time_to_measure_probes_ms=an(s.probes,"experimental","time_to_measure_ms"),s.delta_KBytes_in=an(s.probes,"data","delta_KBytes_in"),s.delta_KBytes_out=an(s.probes,"data","delta_KBytes_out"),s.delta_kbs_in=an(s.probes,"data","delta_kbs_in"),s.delta_kbs_out=an(s.probes,"data","delta_kbs_out"),s.total_time_decoded_in=an(s.probes,"video","total_time_decoded_in"),s.total_time_encoded_out=an(s.probes,"video","total_time_encoded_out"),s};for(Ue(bt,"starting to collect"),t(),Ue(bt,"generating reference reports..."),await n(),Ue(bt,"reference reports generated"),this._startedTime=Date.now();o();)if(Ue(bt,`wait ${this._config.refreshEvery}ms before collecting`),await Od(this._config.refreshEvery),o()){Ue(bt,"collecting...");const s=Date.now(),r=await a(),_=Date.now();r.delta_time_consumed_to_measure_ms=_-s,this.fireOnReports(r),Ue(bt,"collected")}Ue(bt,"reaching end of the collecting period..."),this.isRunning&&setTimeout(()=>{this.stop()},0)}stop(t){const n=o=>{this._probes.forEach(a=>{a.stop(o)})};on(bt,"stop collecting"),n(t)}registerCallback(t,n,o){t in this._callbacks?(this._callbacks[t]={callback:n,context:o},Ue(bt,`registered callback '${t}'`)):jn(bt,`can't register callback for '${t}' - not found`)}unregisterCallback(t){t in this._callbacks?(this._callbacks[t]=null,delete this._callbacks[t],Ue(this._moduleName,`unregistered callback '${t}'`)):jn(this._moduleName,`can't unregister callback for '${t}' - not found`)}fireOnReports(t){this._callbacks.onresult&&t.probes.length>0&&Du(this._callbacks.onresult.callback,this._callbacks.onresult.context,t)}}const Vv="interface ";class jv{constructor(t){this._config=dv(t),on(Vv,`welcome to ${this._config.name} version ${this._config.version}`),ev(this._config.verbose||!1),this._engine=new Fv(this._config)}setupLogLevel(t){tv(t)}get version(){return this._config.version}get name(){return this._config.name}get probes(){return this._engine.probes}createProbe(t,n){return this._engine.addNewProbe(t,n)}startAllProbes(){this._engine.start()}stopAllProbes(){this._engine.stop()}get running(){return this._engine.isRunning}get idle(){return this._engine.isIdle}removeProbe(t){this._engine.removeExistingProbe(t)}set onresult(t){t?this._engine.registerCallback("onresult",t):this._engine.unregisterCallback("onresult")}}function qv(c,t){return Object.keys(c).filter(n=>t.includes(n)).reduce((n,o)=>{const a=o;return{...n,[a]:c[a]}},{})}const Bv=["mos_in","codec_in","delta_KBytes_in","delta_kbs_in","delta_jitter_ms_in","delta_packets_lost_in"],Gv={positiveSpeechThreshold:.6,negativeSpeechThreshold:.3,preSpeechPadMs:150,redemptionMs:1500,minSpeechMs:50};class Wv{constructor(t){this.intervals={},this.analysers={},this.emitInterval=t.emitInterval||200,this.onChangeFunction=t.onChangeFunction}async start(t,n,o){n&&n.getTracks().length&&await this.beginCalculation(t,n,o)}stop(t){this.clearVolumeInterval(t),this.analysers[t]&&typeof this.analysers[t].disconnect=="function"&&(this.analysers[t].disconnect(),delete this.analysers[t])}clearVolumeInterval(t){this.intervals[t]&&(clearInterval(this.intervals[t]),delete this.intervals[t])}clearAllIntervals(){Object.keys(this.intervals).forEach(t=>{this.stop(t)}),this.intervals={},this.analysers={}}async beginCalculation(t,n,o){this.clearVolumeInterval(o);const a=t.createAnalyser(),s=t.createMediaStreamSource(n);a.smoothingTimeConstant=.8,a.fftSize=1024,s.connect(a),this.analysers[o]=a,this.intervals[o]=setInterval(()=>{const r=new Uint8Array(a.frequencyBinCount);a.getByteFrequencyData(r);let _=0;const d=r.length;for(let m=0;m<d;m++)_+=r[m];const h=_/d;this.onChangeFunction(o,h)},this.emitInterval)}}class Kv{constructor(){this.resumePromise=null,this.context=new AudioContext,this.setupErrorHandling()}setupErrorHandling(){!this.context||typeof this.context.addEventListener!="function"||this.context.addEventListener("statechange",()=>{(this.context.state==="interrupted"||this.context.state==="closed")&&console.warn(`[ManagedAudioContext] AudioContext state changed to: ${this.context.state}`)})}createNewContext(){return console.log("[ManagedAudioContext] Creating new AudioContext instance"),this.context=new AudioContext,this.setupErrorHandling(),this.context}async getContext(){if(this.context.state==="closed")return console.warn("[ManagedAudioContext] AudioContext is closed, creating new instance"),this.createNewContext();if(this.context.state==="interrupted"){console.warn("[ManagedAudioContext] AudioContext is interrupted, attempting to resume");try{this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{console.error("[ManagedAudioContext] Failed to resume interrupted context:",t),this.resumePromise=null,this.createNewContext()})),await this.resumePromise}catch(t){return console.error("[ManagedAudioContext] Error resuming context, creating new one:",t),this.createNewContext()}}return this.context.state==="suspended"&&(this.resumePromise||(this.resumePromise=this.context.resume().then(()=>{this.resumePromise=null}).catch(t=>{throw console.error("[ManagedAudioContext] Failed to resume suspended context:",t),this.resumePromise=null,t})),await this.resumePromise),this.context.state==="closed"?(console.warn("[ManagedAudioContext] Context closed after resume attempt, creating new instance"),this.createNewContext()):this.context}}const wo={SELECTED_INPUT_DEVICE:"OpensipsJSInputDevice",SELECTED_OUTPUT_DEVICE:"OpensipsJSOutputDevice"},Yv=0;function Nu(c,t){const n=new AudioContext,o=n.createMediaStreamSource(c),a=n.createMediaStreamSource(new MediaStream([t])),s=n.createMediaStreamDestination();return o.connect(s),a.connect(s),s.stream}class Jv{constructor(t){var n;this.isAutoAnswer=!0,this.muteWhenJoinEnabled=!1,this.isDNDEnabled=!1,this.isCallWaitingEnabled=!0,this.muted=!1,this.microphoneInputLevelValue=1,this.speakerVolumeValue=1,this.activeRooms={},this.activeCalls={},this.extendedCalls={},this.conferenceNodes={},this.availableMediaDevices=[],this.selectedMediaDevices={input:"default",output:"default"},this.callStatus={},this.callTime={},this.callMetrics={},this.timeIntervals={},this.metricConfig={refreshEvery:1e3},this.activeStreamValue=null,this.initialStreamValue=null,this.vadSession=null,this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.vadInterval=null,this.vadMrsInterval=null,this.ringbackTimers={},this.ringbackAudioContexts={},this.ringbackSessionProgressReceived={},this.hangupBeepContext=null,this.managedAudioContext=new Kv,this.context=t,this.context.on(this.context.newRTCSessionEventName,this.newRTCSessionCallback.bind(this)),this.VUMeter=new Wv({onChangeFunction:this.emitVolumeChange.bind(this)}),this.initializeMediaDevices(),this.processVADConfiguration(((n=this.context.options.configuration)==null?void 0:n.noiseReductionOptions)||{}),this.setupVADInstance()}setVADConfiguration(t){if(!this.MicVAD)throw new Error("VAD module is not provided in the initial configuration");const n=Object.keys(t);for(const o of n)this.noiseReduction[o]=t[o];this.hasActiveCalls&&this.roomReconfigure(this.currentActiveRoomId)}setupVADInstance(){var n,o;const t=(o=(n=this.context.options.configuration)==null?void 0:n.noiseReductionOptions)==null?void 0:o.vadModule;t&&t.MicVAD?(this.MicVAD=t.MicVAD,console.log("✅ VAD module loaded successfully")):this.noiseReduction.mode!=="disabled"&&(console.warn("⚠️ Noise reduction is enabled but VAD module is not provided. To use VAD features, please install @ricky0123/vad-web and pass it via configuration.noiseReductionOptions.vadModule option."),this.noiseReduction.mode="disabled")}processVADConfiguration(t){this.noiseReduction={mode:t.mode||"disabled",checkEveryMs:t.checkEveryMs||500,noiseCheckInterval:t.noiseCheckInterval||2e3,noiseThreshold:t.noiseThreshold||.004,vadConfig:t.vadConfig||{},baseAssetPath:t.baseAssetPath||"https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.28/dist/",onnxWASMBasePath:t.onnxWASMBasePath||"https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/"}}get sipOptions(){return{...this.context.options.sipOptions,mediaConstraints:this.getUserMediaConstraints}}get currentActiveRoomId(){return this.currentActiveRoomIdValue}set currentActiveRoomId(t){this.currentActiveRoomIdValue=t,this.context.emit("currentActiveRoomChanged",t)}get autoAnswer(){return this.isAutoAnswer}get callAddingInProgress(){return this.isCallAddingInProgress}set callAddingInProgress(t){this.isCallAddingInProgress=t,this.context.emit("callAddingInProgressChanged",t)}get muteWhenJoin(){return this.muteWhenJoinEnabled}get isDND(){return this.isDNDEnabled}get isCallWaiting(){return this.isCallWaitingEnabled}get speakerVolume(){return this.speakerVolumeValue}get microphoneInputLevel(){return this.microphoneInputLevelValue}get getActiveCalls(){return this.activeCalls}get hasActiveCalls(){return Object.values(this.extendedCalls).length>0}get hasActiveAnsweredCalls(){return Object.values(this.activeRooms).filter(o=>!o.incomingInProgress).length>0}get getActiveRooms(){return this.activeRooms}get isMuted(){return this.muted}get getInputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audioinput")}get getOutputDeviceList(){return this.availableMediaDevices.filter(t=>t.kind==="audiooutput")}get getUserMediaConstraints(){return Ed()?{video:!1,audio:!0}:{audio:{deviceId:{exact:this.selectedMediaDevices.input},echoCancellation:!0,echoCancellationType:"system",noiseSuppression:!0,autoGainControl:!0,sampleRate:48e3,latency:.01},video:!1}}get selectedInputDevice(){return this.selectedMediaDevices.input}get selectedOutputDevice(){return this.selectedMediaDevices.output}get activeStream(){return this.activeStreamValue}setAvailableMediaDevices(t){this.availableMediaDevices=t,this.context.emit("changeAvailableDeviceList",t)}async updateDeviceList(){await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);const t=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(t)}async initializeMediaDevices(){const t=localStorage.getItem(wo.SELECTED_INPUT_DEVICE)||"default",n=localStorage.getItem(wo.SELECTED_OUTPUT_DEVICE)||"default";try{const o=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints),a=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(a),await this.setMicrophone(t),await this.setSpeaker(n),navigator.mediaDevices.addEventListener("devicechange",async()=>{const s=await navigator.mediaDevices.enumerateDevices();this.setAvailableMediaDevices(s)}),o.getTracks().forEach(s=>s.stop())}catch(o){console.error(o)}}async cleanupConferenceNodes(t){const n=this.conferenceNodes[t];if(!n)return;let o=0;n.sources.forEach((r,_)=>{var d;try{r.disconnect(),o++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting source ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting source ${_}:`,h)}});let a=0;n.destinations.forEach((r,_)=>{var d;try{r.disconnect(),a++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting destination ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting destination ${_}:`,h)}});let s=0;n.gains.forEach((r,_)=>{var d;try{r.disconnect(),s++}catch(h){console.error(`[cleanupConferenceNodes] Error disconnecting gain ${_}:`,h),(d=this.context.logger)==null||d.error(`[cleanupConferenceNodes] Error disconnecting gain ${_}:`,h)}}),delete this.conferenceNodes[t]}setCallTime(t){const n={...t};delete n.callId,this.callTime={...this.callTime,[t.callId]:n},this.context.emit("changeCallTime",this.callTime)}removeCallTime(t){const n={...this.callTime};delete n[t],this.callTime={...n},this.context.emit("changeCallTime",this.callTime)}setTimeInterval(t,n){this.timeIntervals={...this.timeIntervals,[t]:n}}removeTimeInterval(t){const n={...this.timeIntervals};n[t]&&(clearInterval(n[t]),delete n[t],this.timeIntervals={...n})}stopCallTimer(t){this.removeTimeInterval(t),this.removeCallTime(t)}emitVolumeChange(t,n){this.context.emit("changeCallVolume",{callId:t,volume:n})}getNoiseReductionMode(){return this.noiseReduction.mode}setMetricsConfig(t){this.metricConfig={...this.metricConfig,...t}}sendDTMF(t,n){if(!/^[A-D0-9*#]+$/g.test(n))throw new Error("Not allowed character used in the DTMF input");this.extendedCalls[t].sendDTMF(n)}setIsMuted(t){this.muted=t,this.context.emit("changeIsMuted",t)}processMute(t){const n=this.currentActiveRoomId;this.setIsMuted(t),this.initialStreamValue.getTracks().forEach(o=>o.enabled=!t),this.roomReconfigure(n)}mute(){this.processMute(!0)}unmute(){this.processMute(!1)}async processHold({callId:t,toHold:n,automatic:o}){const a=this.extendedCalls[t];if(!a)return;a._automaticHold=o??!1;const s=new Promise((r,_)=>{const d=setTimeout(()=>{_(new Error("Hold operation timeout"))},5e3),h=()=>{clearTimeout(d),a.putOnHoldTimestamp=n?Date.now():void 0,r()},m=T=>{clearTimeout(d),_(T)};try{n?(this.stopSessionVad(),a.hold({},h)):a.unhold({},h)}catch(T){m(T)}});try{await s,this.updateCall(a);const r=Object.values(this.extendedCalls).filter(_=>_.roomId===a.roomId&&(n?t!==_._id:!0));r.length>1&&await this.doConference(r)}catch(r){throw console.error("Hold operation failed:",r),r}}holdCall(t,n=!1){return this.processHold({callId:t,automatic:n,toHold:!0})}unholdCall(t){return this.processHold({callId:t,toHold:!1})}cancelAllOutgoingUnanswered(){Object.values(this.getActiveCalls).filter(t=>t.direction==="outgoing"&&t.status===Yv).forEach(t=>this.terminateCall(t._id))}answerCall(t){const n=this.extendedCalls[t];this.cancelAllOutgoingUnanswered(),n.answer(this.sipOptions),this.updateCall(n),this.setActiveRoom(n.roomId),n.connection.addEventListener("track",o=>{this.triggerAddStream(o,n)})}async moveCall(t,n){this.updateCallStatus({callId:t,isMoving:!0}),await this.processRoomChange({callId:t,roomId:n}),this.updateCallStatus({callId:t,isMoving:!1})}updateCall(t){this.activeCalls[t._id]=vd(t),this.context.emit("changeActiveCalls",this.activeCalls)}updateRoom(t){const o={...this.activeRooms[t.roomId],...t};this.activeRooms={...this.activeRooms,[t.roomId]:{...o}},this.context.emit("updateRoom",{room:o,roomList:this.activeRooms})}hasAutoAnswerHeaders(t){const n=/answer-after=0/,a=t.request.getHeader("Call-Info");return a&&n.test(a)}addCall(t,n=!0){this.activeCalls={...this.activeCalls,[t._id]:vd(t)},this.extendedCalls[t._id]=t,n&&this.context.emit("changeActiveCalls",this.activeCalls)}addCallStatus(t){this.callStatus={...this.callStatus,[t]:{isMoving:!1,isTransferring:!1,isMerging:!1,isTransferred:!1}},this.context.emit("changeCallStatus",this.callStatus)}updateCallStatus(t){const o={...{...this.callStatus[t.callId]}};t.isMoving!==void 0&&(o.isMoving=t.isMoving),t.isTransferring!==void 0&&(o.isTransferring=t.isTransferring),t.isMerging!==void 0&&(o.isMerging=t.isMerging),t.isTransferred!==void 0&&(o.isTransferred=t.isTransferred),this.callStatus={...this.callStatus,[t.callId]:{...o}},this.context.emit("changeCallStatus",this.callStatus)}removeCallStatus(t){const n={...this.callStatus};delete n[t],this.callStatus={...n},this.context.emit("changeCallStatus",this.callStatus)}addRoom(t){this.activeRooms={...this.activeRooms,[t.roomId]:t},this.context.emit("addRoom",{room:t,roomList:this.activeRooms})}async setupActiveStream(){const t=await Au(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);t.getTracks().forEach(n=>n.enabled=!this.isMuted),await this.setActiveStream(t)}async getActiveStream(){const t=await Au(await this.managedAudioContext.getContext(),this.initialStreamValue,this.microphoneInputLevel*2);return t.getTracks().forEach(n=>n.enabled=!this.isMuted),await this.setActiveStream(t),t}async setMicrophone(t){if(!this.getInputDeviceList.find(({deviceId:o})=>o===t)||(this.setSelectedInputDevice(t),Object.keys(this.getActiveCalls).length===0))return;await this.setupStream();const n=Object.values(this.extendedCalls).filter(o=>o.roomId===this.currentActiveRoomId);n.length===1?Object.values(n).forEach(async o=>{await this.setupActiveStream();const a=this.activeStream;o.connection.getSenders()[0].replaceTrack(a.getTracks()[0]),this.updateCall(o)}):await this.doConference(n)}async setActiveStream(t){this.activeStream&&this.stopVUMeter("origin"),await this.setupVUMeter(t,"origin"),this.activeStreamValue=t,this.context.emit("changeActiveStream",t)}async setSpeaker(t){if(!this.getOutputDeviceList.find(({deviceId:a})=>a===t))return;this.setSelectedOutputDevice(t);const n=Object.values(this.extendedCalls);if(n.length===0)return;const o=n.filter(a=>a.roomId===this.currentActiveRoomId);o.length===1?n.forEach(a=>{var s;(s=a.audioTag)==null||s.setSinkId(t),this.updateCall(a)}):await this.doConference(o)}removeRoom(t){const n={...this.activeRooms},o={...n[t]};delete n[t],this.activeRooms={...n},this.context.emit("removeRoom",{room:o,roomList:this.activeRooms})}deleteRoomIfEmpty(t){t!==void 0&&Object.values(this.extendedCalls).filter(n=>n.roomId===t).length===0&&(this.removeRoom(t),this.currentActiveRoomId===t&&(this.currentActiveRoomId=void 0))}checkInitialized(){if(!this.context.initialized)throw new Error("[OpenSIPSJS] You must call `start` method first!")}muteReconfigure(t){this.muted?t.mute({audio:!0}):t.unmute({audio:!0})}async startNoiseMonitor({stream:t,onNoiseDetected:n,onNoiseStop:o}){var h,m,T;let a;try{a=await this.managedAudioContext.getContext()}catch(S){console.error("[startNoiseMonitor] Failed to get AudioContext:",S),(h=this.context.logger)==null||h.error("[startNoiseMonitor] Failed to get AudioContext:",S);return}let s,r;try{s=a.createMediaStreamSource(t.clone()),r=a.createAnalyser()}catch(S){console.error("[startNoiseMonitor] Failed to create audio nodes:",S),console.error("[startNoiseMonitor] AudioContext state:",a.state),(m=this.context.logger)==null||m.error("[startNoiseMonitor] Failed to create audio nodes:",S),(T=this.context.logger)==null||T.error("[startNoiseMonitor] AudioContext state:",a.state);return}r.fftSize=1024;const _=new Float32Array(r.fftSize);s.connect(r);const d=[];this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadMrsInterval=setInterval(()=>{r.getFloatTimeDomainData(_);const S=zT(_);d.push(S);const E=Math.ceil(this.noiseReduction.noiseCheckInterval/this.noiseReduction.checkEveryMs);d.length>E&&d.shift()},this.noiseReduction.checkEveryMs),this.vadInterval=setInterval(()=>{var A;if(d.length===0)return;const S=d.reduce((R,L)=>R+L,0)/d.length,E=this.vadSessionState;if(!E){console.warn("[startNoiseMonitor] State not found, stopping interval"),(A=this.context.logger)==null||A.warn("[startNoiseMonitor] State not found, stopping interval"),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null);return}const C=S>this.noiseReduction.noiseThreshold;E.isSpeaking||(C&&E.currentMode==="clean"?(E.currentMode="noisy",console.log("Average noise high → enable VAD"),this.context.emit("changeNoiseReductionState",!0),n()):!C&&E.currentMode==="noisy"&&(E.currentMode="clean",console.log("Average noise low → disable VAD"),this.context.emit("changeNoiseReductionState",!1),o()))},this.noiseReduction.noiseCheckInterval)}async processVADForActiveStream(t={}){const n=this.activeStream;this.stopSessionVad(),this.vadSessionState={currentMode:"clean",isSpeaking:!1};const o=await this.managedAudioContext.getContext(),a=await XT(n,o,150);let s=!1;const r=Object.values(this.extendedCalls).filter(d=>d.roomId===this.currentActiveRoomId),_=await this.MicVAD.new({getStream:()=>new Promise(d=>d(n)),...Gv,...this.noiseReduction.vadConfig,baseAssetPath:this.noiseReduction.baseAssetPath,onnxWASMBasePath:this.noiseReduction.onnxWASMBasePath,onFrameProcessed:()=>{var d;if(!s){if(s=!0,console.log("✅ VAD initialized, starting background noise monitoring"),this.noiseReduction.mode==="enabled"){if(t&&Object.keys(t).length)Object.keys(t).forEach(h=>{const m=this.extendedCalls[h];if(m&&m.connection.getSenders()[0]){const T=Nu(a.stream,t[h]);m.connection.getSenders()[0].replaceTrack(T.getAudioTracks()[0])}});else{const h=r[0];h.connection.getSenders()[0]&&h.connection.getSenders()[0].replaceTrack(a.stream.getAudioTracks()[0])}return}if(!this.vadSessionState){console.error("[processVAD] CRITICAL: State not found"),(d=this.context.logger)==null||d.error("[processVAD] CRITICAL: State not found");return}this.startNoiseMonitor({stream:n,onNoiseDetected:async()=>{var h;if(console.log("[processVad] - Replace track with Vad Controlled"),(h=this.context.logger)==null||h.log("[processVad] - Replace track with Vad Controlled"),t&&Object.keys(t).length)Object.keys(t).forEach(m=>{const T=this.extendedCalls[m];if(T&&T.connection.getSenders()[0]){const S=Nu(a.stream,t[m]);T.connection.getSenders()[0].replaceTrack(S.getAudioTracks()[0])}});else{const m=r[0];m.connection.getSenders()[0]&&m.connection.getSenders()[0].replaceTrack(a.stream.getAudioTracks()[0])}},onNoiseStop:async()=>{if(console.log("Replace track with Original"),t&&Object.keys(t).length)Object.keys(t).forEach(h=>{const m=this.extendedCalls[h];if(!m)return;const T=m.connection.getSenders()[0];if(T&&T.track&&T.transport&&T.transport.state!=="closed"&&T.transport.state!=="failed"){const S=Nu(n,t[h]);T.replaceTrack(S.getAudioTracks()[0])}});else{const h=r[0].connection.getSenders()[0];h&&h.track&&h.transport&&h.transport.state!=="closed"&&h.transport.state!=="failed"&&h.replaceTrack(n.getAudioTracks()[0])}}})}},onSpeechStart:()=>{console.log("🎤 Speech started"),a.setSpeaking(!0),this.vadSessionState.isSpeaking=!0},onSpeechEnd:()=>{console.log("🛑 Speech end"),a.setSpeaking(!1),this.vadSessionState.isSpeaking=!1}});this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadSession=_,_.start()}stopSessionVad(){this.vadSession&&(this.vadSession.pause(),this.vadSession=null),this.vadInterval&&(clearInterval(this.vadInterval),this.vadInterval=null),this.vadMrsInterval&&(clearInterval(this.vadMrsInterval),this.vadMrsInterval=null),this.vadSessionState&&(this.vadSessionState={currentMode:"clean",isSpeaking:!1},this.context.emit("changeNoiseReductionState",!1))}async roomReconfigure(t){var a,s,r,_;if(t===void 0)return;const n=Object.values(this.extendedCalls).filter(d=>d.roomId===t),o=this.currentActiveRoomId===t;if(console.log("[roomReconfigure] - Calls In Room:",n),(a=this.context.logger)==null||a.log("[roomReconfigure] - Calls In Room:",n),n.forEach((d,h)=>{if(d.audioTag){d.connection.getReceivers().forEach(T=>{T.track.enabled=!d.localMuted}),o&&this.muteReconfigure(d);const m=!o;d.audioTag.muted=m,this.updateCall(d)}}),n.length===0){!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t),console.log("[roomReconfigure] - Delete empty room",t),(s=this.context.logger)==null||s.log("[roomReconfigure] - Delete empty room",t),this.deleteRoomIfEmpty(t);return}if(n.length===1&&!o){const d=n[0];d.isOnHold().local||await this.holdCall(d._id,!0),!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}if(n.length===1&&o){const d=n[0];d.isOnHold().local&&d._automaticHold&&await this.unholdCall(d._id);const T=(((r=d.connection)==null?void 0:r.getSenders())||[])[0];if(d.connection&&T)try{await this.setupActiveStream();const E=this.activeStream;["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[roomReconfigure] - Call processVAD from roomReconfigure"),(_=this.context.logger)==null||_.log("[roomReconfigure] - Call processVAD from roomReconfigure"),this.processVADForActiveStream());const C=E.getTracks();await T.replaceTrack(C[0]),this.muteReconfigure(d)}catch(E){console.error(E)}!!this.conferenceNodes[t]&&await this.cleanupConferenceNodes(t);return}n.length>1&&await this.doConference(n)}async doConference(t){var m,T,S,E,C,A,R,L;if(console.log("[doConference] - In doConference, sessions:",t),(m=this.context.logger)==null||m.log("[doConference] - In doConference, sessions:",t),t.length===0)return;const n=t[0].roomId,o=this.currentActiveRoomId===n;if(t.find(b=>b.roomId!==n))return;let s;try{s=await this.managedAudioContext.getContext()}catch(b){console.error("[doConference] Failed to get AudioContext:",b),(T=this.context.logger)==null||T.error("[doConference] Failed to get AudioContext:",b);return}const r=s.state;if(r!=="running")if(console.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),(S=this.context.logger)==null||S.error(`[doConference] ERROR: AudioContext is not running! State: ${r}`),r==="suspended"||r==="interrupted")try{await s.resume();const b=s.state;if(b!=="running"){console.error(`[doConference] Failed to resume AudioContext, state: ${b}`),(E=this.context.logger)==null||E.error(`[doConference] Failed to resume AudioContext, state: ${b}`);return}}catch(b){console.error("[doConference] Error resuming AudioContext:",b),(C=this.context.logger)==null||C.error("[doConference] Error resuming AudioContext:",b);return}else if(r==="closed"){console.error("[doConference] AudioContext is closed, cannot proceed"),(A=this.context.logger)==null||A.error("[doConference] AudioContext is closed, cannot proceed");return}else return;await this.cleanupConferenceNodes(n),this.conferenceNodes[n]={sources:new Map,destinations:new Map,gains:new Map};const _=this.conferenceNodes[n],d=new Map;console.log("[doConference] - Before sessions forEach, sessions:",t),(R=this.context.logger)==null||R.log("[doConference] - Before sessions forEach, sessions:",t),t.forEach((b,ie)=>{var N,F,me;if(console.log("[doConference] - In sessions forEach, iteration for",b._id),(N=this.context.logger)==null||N.log("[doConference] - In sessions forEach, iteration for",b._id),b&&b.connection){const _e=b.connection.getReceivers();console.log("[doConference] - Receivers list length for",b._id,_e.length),(F=this.context.logger)==null||F.log("[doConference] - Receivers list length for",b._id,_e.length),_e.forEach((U,x)=>{var Y,V,X,k,P,B;U.track.enabled=!b.localMuted;const q=(Y=U.track)==null?void 0:Y.id;(V=U.track)==null||V.readyState,(X=U.track)==null||X.kind;const j=`${b._id}-${q}`;console.log("[doConference] - Gathering receiver tracks",b._id),console.log("[doConference] - Receiver track readyState",U.track.readyState),(k=this.context.logger)==null||k.log("[doConference] - Gathering receiver tracks",b._id),(P=this.context.logger)==null||P.log("[doConference] - Receiver track readyState",U.track.readyState),U.track&&U.track.readyState==="live"&&(console.log("[doConference] - Gathered receiver track",b._id),(B=this.context.logger)==null||B.log("[doConference] - Gathered receiver track",b._id),d.set(j,U.track))})}else console.log("[doConference] - No session or RTC connection, session:",b),(me=this.context.logger)==null||me.log("[doConference] - No session or RTC connection, session:",b)}),await this.setupActiveStream();const h={};await QT.forEach(t,async(b,ie)=>{var Y,V,X,k,P;if(!b||!b.connection){console.log("[doConference] - Return because of no session or connection, session:",b),(Y=this.context.logger)==null||Y.log("[doConference] - Return because of no session or connection, session:",b);return}const N=s.createMediaStreamDestination(),F=s.createMediaStreamDestination();_.destinations.set(b._id,N),_.destinations.set(`${b._id}-others`,F);const me=b.connection.getReceivers(),_e=me.length>0;console.log(`[doConference] Session ${b._id} has ${me.length} receivers`),(V=this.context.logger)==null||V.log(`[doConference] Session ${b._id} has ${me.length} receivers`),_e||(console.warn(`[doConference] Session ${b._id} has no receivers yet. Will re-configure when track arrives.`),(X=this.context.logger)==null||X.warn(`[doConference] Session ${b._id} has no receivers yet. Will re-configure when track arrives.`)),d.forEach((B,je)=>{var Q,K,G;if(console.log("[doConference] - In forEach receiverTracks for",b._id),(Q=this.context.logger)==null||Q.log("[doConference] - In forEach receiverTracks for",b._id),!je.startsWith(b._id)){if(!B||B.readyState!=="live"){console.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${b._id}`),(K=this.context.logger)==null||K.warn(`[doConference] Skipping invalid track ${(B==null?void 0:B.id)||"unknown"} for session ${b._id}`);return}try{const re=s.createMediaStreamSource(new MediaStream([B])),pe=s.createGain(),Ie=`${b._id}-${je}`;re.connect(pe),pe.connect(N),pe.connect(F),console.log("[doConference] - In forEach connect track for",b._id),(G=this.context.logger)==null||G.log("[doConference] - In forEach connect track for",b._id),_.sources.set(Ie,re),_.gains.set(Ie,pe)}catch(re){console.error(re)}}});const U=F.stream.getTracks();if(h[b._id]=U[0],o&&this.activeStreamValue)try{const B=this.activeStream,je=s.createMediaStreamSource(B),Q=s.createGain(),K=`${b._id}-local`;je.connect(Q),Q.connect(N),_.sources.set(K,je),_.gains.set(K,Q)}catch(B){console.error(B)}else o&&(console.error(`Host room but no activeStreamValue - skipping host microphone for session ${b._id}`),(k=this.context.logger)==null||k.error(`Host room but no activeStreamValue - skipping host microphone for session ${b._id}`));const q=b.connection.getSenders()[0],j=N.stream.getTracks();if(q&&j[0])try{console.log("[doConference] - Final replaceTrack for",b._id),(P=this.context.logger)==null||P.log("[doConference] - Final replaceTrack for",b._id),console.log("RIGHT 2 initial replace for ",b._id),await q.replaceTrack(j[0]),this.muteReconfigure(b)}catch(B){console.error(B)}}),["enabled","dynamic"].includes(this.noiseReduction.mode)&&(console.log("[doConference] - Call processVAD from doConference"),(L=this.context.logger)==null||L.log("[doConference] - Call processVAD from doConference"),this.processVADForActiveStream(h))}processCallerMute(t,n){const o=this.extendedCalls[t];o&&o.connection.getReceivers().length&&(o.localMuted=n,o.connection.getReceivers().forEach(a=>{a.track.enabled=!n}),this.updateCall(o))}muteCaller(t){this.processCallerMute(t,!0)}unmuteCaller(t){this.processCallerMute(t,!1)}terminateCall(t){const n=this.extendedCalls[t];n._status===4?n.terminate({status_code:603,reason_phrase:"Decline"}):n._status!==8&&n.terminate()}handleSipResponseForRingback(t,n){var s,r,_,d,h,m;let o=null;if(this.extendedCalls[t])o=t;else{const T=Object.values(this.extendedCalls).find(S=>S.id===t||S._id===t||S.id&&S.id.includes(t)||S._id&&S._id.includes(t));T&&(o=T.id)}if(!o){(s=this.context.logger)==null||s.warn(`[handleSipResponseForRingback] Could not find session for identifier ${t}, status ${n}`);return}const a=this.extendedCalls[o];if(!a){(r=this.context.logger)==null||r.warn(`[handleSipResponseForRingback] Call not found in extendedCalls for ${o}`);return}if(a.direction==="outgoing"){if(a._is_confirmed){(_=this.context.logger)==null||_.log(`[handleSipResponseForRingback] Call ${o} is already confirmed, skipping ringback tone`);return}if(n===Ao.TRYING||n===Ao.RINGING){if(this.ringbackTimers[o])return;this.ringbackSessionProgressReceived[o]=!1,this.ringbackTimers[o]=setTimeout(()=>{var S,E;const T=this.extendedCalls[o];T&&!T._is_confirmed&&!this.ringbackSessionProgressReceived[o]?(this.startLocalRingbackTone(o),(S=this.context.logger)==null||S.log(`[handleSipResponseForRingback] Started local ringback tone for call ${o} after 2 seconds without 183`)):T&&T._is_confirmed&&((E=this.context.logger)==null||E.log(`[handleSipResponseForRingback] Call ${o} was confirmed during 2-second wait, skipping ringback tone`)),delete this.ringbackTimers[o]},2e3),(d=this.context.logger)==null||d.log(`[handleSipResponseForRingback] Started 2-second timer for call ${o} after receiving ${n}`)}n===Ao.SESSION_PROGRESS&&(this.ringbackSessionProgressReceived[o]=!0,this.ringbackTimers[o]&&(clearTimeout(this.ringbackTimers[o]),delete this.ringbackTimers[o],(h=this.context.logger)==null||h.log(`[handleSipResponseForRingback] Cancelled ringback timer for call ${o} - 183 received`)),this.stopLocalRingbackTone(o),(m=this.context.logger)==null||m.log(`[handleSipResponseForRingback] Stopped local ringback tone for call ${o} - 183 received with SDP`))}}async startLocalRingbackTone(t){var n,o;if(!this.ringbackAudioContexts[t])try{const a=await this.managedAudioContext.getContext(),s=a.createOscillator(),r=a.createOscillator(),_=a.createGain();s.frequency.value=440,r.frequency.value=480,s.type="sine",r.type="sine",_.gain.value=0,s.connect(_),r.connect(_),_.connect(a.destination),s.start(),r.start();const d={context:a,oscillator1:s,oscillator2:r,gainNode:_,intervalId:null};this.ringbackAudioContexts[t]=d;const h=()=>{if(!this.ringbackAudioContexts[t])return;const T=a.currentTime;_.gain.cancelScheduledValues(T),_.gain.setValueAtTime(0,T),_.gain.linearRampToValueAtTime(.3,T+.05),_.gain.linearRampToValueAtTime(0,T+1)};h();const m=setInterval(()=>{if(!this.ringbackAudioContexts[t]){clearInterval(m);return}h()},4e3);d.intervalId=m,this.ringbackAudioContexts[t]=d,(n=this.context.logger)==null||n.log(`[startLocalRingbackTone] Started ringback tone for session ${t}`)}catch(a){(o=this.context.logger)==null||o.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a),console.error(`[startLocalRingbackTone] Error starting ringback tone for session ${t}:`,a)}}stopLocalRingbackTone(t){var o,a;const n=this.ringbackAudioContexts[t];if(n)try{n.intervalId&&clearInterval(n.intervalId),n.oscillator1&&n.oscillator1.stop(),n.oscillator2&&n.oscillator2.stop(),n.gainNode&&n.gainNode.disconnect(),delete this.ringbackAudioContexts[t],(o=this.context.logger)==null||o.log(`[stopLocalRingbackTone] Stopped ringback tone for session ${t}`)}catch(s){(a=this.context.logger)==null||a.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,s),console.error(`[stopLocalRingbackTone] Error stopping ringback tone for session ${t}:`,s),delete this.ringbackAudioContexts[t]}}cleanupRingbackTone(t){this.ringbackTimers[t]&&(clearTimeout(this.ringbackTimers[t]),delete this.ringbackTimers[t]),this.stopLocalRingbackTone(t),delete this.ringbackSessionProgressReceived[t]}async playHangupBeep(){var t,n;if(!this.hangupBeepContext)try{const o=await this.managedAudioContext.getContext(),a=o.createOscillator(),s=o.createGain();a.frequency.value=800,a.type="sine",s.gain.value=0,a.connect(s),s.connect(o.destination),this.hangupBeepContext={context:o,oscillator:a,gainNode:s},a.start();const r=o.currentTime;s.gain.setValueAtTime(0,r),s.gain.linearRampToValueAtTime(.3,r+.01),s.gain.setValueAtTime(.3,r+.15),s.gain.linearRampToValueAtTime(0,r+.2),a.stop(r+.2),setTimeout(()=>{if(this.hangupBeepContext){try{this.hangupBeepContext.oscillator&&this.hangupBeepContext.oscillator.disconnect(),this.hangupBeepContext.gainNode&&this.hangupBeepContext.gainNode.disconnect()}catch(_){console.error("[playHangupBeep] Cleanup playing hangup beep error:",_)}this.hangupBeepContext=null}},250),(t=this.context.logger)==null||t.log("[playHangupBeep] Played hangup beep")}catch(o){(n=this.context.logger)==null||n.error("[playHangupBeep] Error playing hangup beep:",o),console.error("[playHangupBeep] Error playing hangup beep:",o),this.hangupBeepContext=null}}transferCall(t,n){if(n.toString().length===0)return new Error("Target must be passed");const o=this.extendedCalls[t];if(!o._is_confirmed&&!o._is_canceled){const a=`sip:${n}@${this.context.sipDomain}`;o.terminate({status_code:302,reason_phrase:"Moved Temporarily",extraHeaders:[`Contact: ${a}`]});return}this.updateCallStatus({callId:t,isTransferring:!0,isTransferred:!1}),o.refer(`sip:${n}@${this.context.sipDomain}`,{eventHandlers:{requestSucceeded:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!0})},requestFailed:()=>{this.updateCallStatus({callId:t,isTransferring:!1,isTransferred:!1})}}}),this.updateCall(o)}mergeCall(t){const n=Object.values(this.extendedCalls).filter(s=>s.roomId===t);if(n.length!==2)return;const o=n[0],a=n[1];!o||!a||(this.updateCallStatus({callId:o._id,isMerging:!0}),this.updateCallStatus({callId:a._id,isMerging:!0}),o.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(o))}mergeCallByIds(t,n){const o=Object.values(this.extendedCalls).find(s=>s._id===t),a=Object.values(this.extendedCalls).find(s=>s._id===n);if(!o||!a)throw new Error("Call ID is not provided");this.updateCallStatus({callId:t,isMerging:!0}),this.updateCallStatus({callId:n,isMerging:!0}),o.refer(a.remote_identity.uri.toString(),{replaces:a}),this.updateCall(o)}setDND(t){this.isDNDEnabled=t,this.context.emit("changeIsDND",t)}setCallWaiting(t){this.isCallWaitingEnabled=t,this.context.emit("changeIsCallWaiting",t)}startCallTimer(t){this.removeTimeInterval(t);const n={callId:t,hours:0,minutes:0,seconds:0,formatted:""};this.setCallTime(n);const o=setInterval(()=>{const a={...this.callTime[t]},s=JT(a);this.setCallTime({callId:t,...s})},1e3);this.setTimeInterval(t,o)}async setActiveRoom(t){const n=this.currentActiveRoomId;t!==n&&(this.currentActiveRoomId=t,await this.roomReconfigure(n),await this.roomReconfigure(t))}getNewRoomId(){const t=Object.keys(this.activeRooms);return t.length===0?1:parseInt(t.sort()[t.length-1])+1}async setupCall(t){var h,m;const n=t.session;if(this.getActiveCalls[n.id]!==void 0)return;const a=this.getNewRoomId(),s={started:new Date,incomingInProgress:!1,roomId:a};if(n.direction==="incoming")this.context.logger.log("New incoming call from",(m=(h=n._remote_identity)==null?void 0:h._uri)==null?void 0:m._user),s.incomingInProgress=!0,this.context.subscribe(Xt.CALL_CONFIRMED,T=>{n.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.startCallTimer(n.id))}),this.context.subscribe(Xt.CALL_FAILED,T=>{n.id===T.id&&(this.updateRoom({incomingInProgress:!1,roomId:a}),this.deleteRoomIfEmpty(a))});else if(n.direction==="outgoing"){const T=S=>{var R,L,b,ie,N,F,me,_e,U;const E=!!((R=S==null?void 0:S.response)!=null&&R.body),C=(b=(L=S==null?void 0:S.response)==null?void 0:L.getHeader)==null?void 0:b.call(L,"Content-Type"),A=(N=(ie=S==null?void 0:S.response)==null?void 0:ie.getHeader)==null?void 0:N.call(ie,"Content-Length");console.log("PPP SDP Check:",{hasBody:E,contentType:C,contentLength:A,bodyLength:((me=(F=S==null?void 0:S.response)==null?void 0:F.body)==null?void 0:me.length)||0,bodyPreview:((U=(_e=S==null?void 0:S.response)==null?void 0:_e.body)==null?void 0:U.substring(0,100))||"N/A"}),S.response&&S.response.status_code===Ao.SESSION_PROGRESS&&(this.startCallTimer(n.id),n.off("progress",T))};n.on("progress",T),n.once("confirmed",()=>{this.startCallTimer(n.id)})}const r=n,_=this.hasAutoAnswerHeaders(t),d=r.direction==="incoming"&&!this.hasActiveCalls&&(_||this.autoAnswer);r.roomId=a,r.localMuted=!1,r.autoAnswer=d,d?this.addCall(r,!1):this.addCall(r),this.addCallStatus(n.id),this.addRoom(s),d&&setTimeout(()=>{this.answerCall(r._id)},250)}removeCall(t){const n={...this.activeCalls};delete n[t],this.activeCalls={...n};const o={...this.extendedCalls};delete o[t],this.extendedCalls={...o},this.context.emit("changeActiveCalls",this.activeCalls)}activeCallListRemove(t){const n=this.extendedCalls[t._id];if(!n)return;this.stopVUMeter("origin"),this.stopVUMeter(t._id);const o=n.roomId;this.removeCall(t._id),this.roomReconfigure(o).then(()=>{}).catch(a=>{console.error("Error reconfiguring room after call removal:",a)})}shouldTerminateNewSession(t){if(t.session.direction==="outgoing")return!1;const o=!this.isCallWaiting&&this.hasActiveCalls;return this.isDND||o}async newRTCSessionCallback(t){const n=t.session;if(this.shouldTerminateNewSession(t)){n.terminate({status_code:486,reason_phrase:"Do Not Disturb"});return}this.context.triggerListener({listenerType:Xt.NEW_CALL,session:n,event:t}),n.on("ended",a=>{var r,_,d;if(this.stopVUMeter(n.id),this.context.logger.log("Session ended for",(_=(r=n._remote_identity)==null?void 0:r._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_ENDED,session:n,event:a}),n._is_confirmed&&this.playHangupBeep(),n.connection){const h=n.connection.connectionState;(h==="closed"||h==="disconnected")&&this.context.emit("connectionStateChange",{session:n,connectionState:h})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(n.id);const s=this.getActiveCalls[n.id];s&&this.activeCallListRemove(s),this.stopCallTimer(n.id),this.removeCallStatus(n.id),this.removeCallMetrics(n.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(d=this.initialStreamValue)==null||d.getTracks().forEach(h=>h.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),n.on("progress",a=>{var s,r;this.context.logger.log("Session in progress for",(r=(s=n._remote_identity)==null?void 0:s._uri)==null?void 0:r._user),this.context.triggerListener({listenerType:Xt.CALL_PROGRESS,session:n,event:a})}),n.on("failed",a=>{var r,_,d;if(this.stopVUMeter(n.id),this.context.logger.log("Session failed for",(_=(r=n._remote_identity)==null?void 0:r._uri)==null?void 0:_._user),this.context.triggerListener({listenerType:Xt.CALL_FAILED,session:n,event:a}),n.connection){const h=n.connection.connectionState;(h==="closed"||h==="disconnected")&&this.context.emit("connectionStateChange",{session:n,connectionState:h})}["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.stopSessionVad(),this.cleanupRingbackTone(n.id),n.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0);const s=this.getActiveCalls[n.id];s&&this.activeCallListRemove(s),this.stopCallTimer(n.id),this.removeCallStatus(n.id),this.removeCallMetrics(n.id),Object.keys(this.extendedCalls).length||(this.setIsMuted(!1),(d=this.initialStreamValue)==null||d.getTracks().forEach(h=>h.stop()),this.initialStreamValue=null),this.context.isWaitingForSessionHangup()&&!this.hasActiveAnsweredCalls&&this.context.stopSessionAfterWaiting()}),n.on("confirmed",a=>{var s,r;this.context.logger.log("Session confirmed for",(r=(s=n._remote_identity)==null?void 0:s._uri)==null?void 0:r._user),this.context.triggerListener({listenerType:Xt.CALL_CONFIRMED,session:n,event:a}),this.updateCall(n),this.cleanupRingbackTone(n.id),n.id===this.callAddingInProgress&&(this.callAddingInProgress=void 0)});const o=a=>{a&&a.addEventListener("connectionstatechange",s=>{this.context.emit("connectionStateChange",{session:n,connectionState:a.connectionState})})};if(n.connection&&o(n.connection),n.on("peerconnection",({peerconnection:a})=>{o(a)}),await this.setupCall(t),n.direction==="outgoing"){const a=this.getActiveCalls[n.id].roomId;await this.setActiveRoom(a)}}setMuteWhenJoin(t){this.muteWhenJoinEnabled=t,this.context.emit("changeMuteWhenJoin",t)}setMicrophoneSensitivity(t){if(t<0||t>1)throw new Error("Value should be in range from 0 to 1!");this.microphoneInputLevelValue=t,this.roomReconfigure(this.currentActiveRoomId)}setSpeakerVolume(t){this.speakerVolumeValue=t,Object.values(this.extendedCalls).forEach(n=>{n.audioTag&&(n.audioTag.volume=t,this.updateCall(n))})}setAutoAnswer(t){this.isAutoAnswer=t}setSelectedInputDevice(t){localStorage.setItem(wo.SELECTED_INPUT_DEVICE,t),this.selectedMediaDevices.input=t,this.context.emit("changeActiveInputMediaDevice",t)}setSelectedOutputDevice(t){localStorage.setItem(wo.SELECTED_OUTPUT_DEVICE,t),this.selectedMediaDevices.output=t,this.context.emit("changeActiveOutputMediaDevice",t)}setCallMetrics(t){const n={...t};delete n.callId,this.callMetrics={...this.callMetrics,[t.callId]:n},this.context.emit("changeCallMetrics",this.callMetrics)}removeCallMetrics(t){const n={...this.callMetrics};delete n[t],this.callMetrics={...n},this.context.emit("changeCallMetrics",this.callMetrics)}getCallQuality(t){const n=new jv(this.metricConfig),o=n.createProbe(t.connection,{cid:t._id}),a=[];let s;o.onreport=r=>{Object.entries(r.audio).forEach(([h,m])=>{m.direction==="inbound"&&!a.includes(h)&&(a.push(h),s=h)});const _=r.audio[s];if(!_)return;const d=qv(_,Bv);d.callId=t._id,this.setCallMetrics(d)},this.context.subscribe(Xt.CALL_ENDED,r=>{r._id===t._id&&n.stopAllProbes()}),n.startAllProbes()}async setupVUMeter(t,n){await this.VUMeter.start(await this.managedAudioContext.getContext(),t,n)}stopVUMeter(t){this.VUMeter.stop(t)}async setupStream(){try{const t=Date.now(),n=await navigator.mediaDevices.getUserMedia(this.getUserMediaConstraints);this.initialStreamValue&&(this.initialStreamValue.getTracks().forEach((a,s)=>{a.stop()}),this.initialStreamValue=null),this.initialStreamValue=n}catch(t){throw t}}async triggerAddStream(t,n){var S,E;console.log(`[triggerAddStream] - For ${n._id}`),(S=this.context.logger)==null||S.log(`[triggerAddStream] - For ${n._id}`);const o=this.muteWhenJoin||this.isMuted;this.setIsMuted(o),this.initialStreamValue||await this.setupStream();const a=await this.managedAudioContext.getContext(),s=await Au(a,this.initialStreamValue,this.microphoneInputLevel*2),r=this.isMuted||this.muteWhenJoin;s.getTracks().forEach(C=>{C.enabled=!r}),await this.setActiveStream(s),await n.connection.getSenders()[0].replaceTrack(s.getTracks()[0]);const h=new MediaStream([t.track]);!Object.values(this.extendedCalls).find(C=>C.audioTag&&C.audioTag.id===n._id)&&kT(h,n,this.selectedOutputDevice,this.speakerVolume);const T=n.roomId===this.currentActiveRoomId;n.audioTag&&(n.audioTag.muted=!T),await this.setupVUMeter(h,n._id),this.getCallQuality(n),this.updateCall(n),n.roomId!==void 0&&Object.values(this.extendedCalls).filter(A=>A.roomId===n.roomId).length>1&&(console.log(`[triggerAddStream] Re-configuring conference for room ${n.roomId} - track received for call ${n._id}`),(E=this.context.logger)==null||E.log(`[triggerAddStream] Re-configuring conference for room ${n.roomId} - track received for call ${n._id}`),setTimeout(()=>{this.roomReconfigure(n.roomId)},100)),["enabled","dynamic"].includes(this.noiseReduction.mode)&&this.processVADForActiveStream()}initCall(t,n,o=!1){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`);const a=this.context.call(`sip:${t}@${this.context.sipDomain}`,this.sipOptions);if(this.callAddingInProgress=a.id,n&&this.currentActiveRoomId!==void 0&&(this.processRoomChange({callId:a.id,roomId:this.currentActiveRoomId}),o)){const s=Object.values(this.extendedCalls).filter(r=>r.roomId===this.currentActiveRoomId&&r._id!==a.id);for(const r of s)this.holdCall(r._id,!0)}a.connection.addEventListener("track",s=>{this.triggerAddStream(s,a)})}async processRoomChange({callId:t,roomId:n}){const o=this.extendedCalls[t];if(!o)return;const a=o.roomId;o.roomId=n,this.updateCall(o),await this.roomReconfigure(a),await this.roomReconfigure(n)}}class zv{constructor(t){this.context=t}get sipOptions(){return{...this.context.options.sipOptions}}initCall(t,n){if(t.length===0)return console.error("Target must be a valid string");this.context.logger.log(`Calling sip:${t}@${this.context.sipDomain}...`),this.context.joinVideoCall(`sip:${t}@${this.context.sipDomain}`,n,this.sipOptions)}stop(t={}){this.context.terminateJanusSessions(t)}startAudio(){this.context.enableJanusAudio(!0)}stopAudio(){this.context.enableJanusAudio(!1)}startVideo(){this.context.enableJanusVideo(!0)}stopVideo(){this.context.enableJanusVideo(!1)}changeMediaConstraints(t){this.context.changeMediaConstraints(t)}startScreenShare(){this.context.startScreenShare()}startBlur(){this.context.startBlur()}stopBlur(){this.context.stopBlur()}}class Xv{constructor(t){this.activeMessages={},this.extendedMessages={},this.msrpHistory={},this.context=t,this.context.on(this.context.newMSRPSessionEventName,this.newMSRPSessionCallback.bind(this))}get isMSRPInitializing(){return this.isMSRPInitializingValue}get getActiveMessages(){return this.activeMessages}msrpAnswer(t){const n=this.extendedMessages[t];this.updateMSRPSession(n)}updateMSRPSession(t){this.activeMessages[t._id]=Sd(t),this.context.emit("changeActiveMessages",this.activeMessages)}addMMSRPSession(t){this.activeMessages={...this.activeMessages,[t._id]:Sd(t)},this.extendedMessages[t._id]=t,this.context.emit("changeActiveMessages",this.activeMessages)}addMSRPMessage(t,n){const o=this.msrpHistory[n.id]||[];o.push(t),this.msrpHistory={...this.msrpHistory,[n.id]:[...o]},this.context.emit("newMSRPMessage",{message:t,session:n})}messageTerminate(t){const n=this.extendedMessages[t];n._status!==8&&n.terminate()}addMessageSession(t){if(!t._id||this.getActiveMessages[t._id]!==void 0)return;const o=t;this.addMMSRPSession(o)}triggerMSRPListener({listenerType:t,session:n,event:o}){const a=this.context.listenersList[t];!a||!a.length||a.forEach(s=>{s(n,o)})}removeMMSRPSession(t){const n={...this.activeMessages};delete n[t],this.activeMessages={...n};const o={...this.extendedMessages};delete o[t],this.extendedMessages={...o},this.context.emit("changeActiveMessages",this.activeMessages)}activeMessageListRemove(t){this.removeMMSRPSession(t._id)}newMSRPSessionCallback(t){t.session._id||(t.session._id=t.request.call_id+t.request.from._parameters.tag);const n=t.session;n.on("ended",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_ENDED,session:n,event:o});const a=this.getActiveMessages[n.id];this.activeMessageListRemove(a)}),n.on("failed",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_FAILED,session:n,event:o});const a=this.getActiveMessages[n.id];this.activeMessageListRemove(a)}),n.on("confirmed",o=>{this.triggerMSRPListener({listenerType:Xt.CALL_CONFIRMED,session:n,event:o}),this.updateMSRPSession(n)}),n.on("newMessage",o=>{this.addMSRPMessage(o,n)}),this.addMessageSession(n)}setIsMSRPInitializing(t){this.isMSRPInitializingValue=t,this.context.emit("isMSRPInitializingChanged",t)}initMSRP(t,n,o){if(t.length===0)return console.error("Target must be a valid string");const a=this.context.startMSRP(t,o);a.on("active",()=>{this.addMessageSession(a),a.sendMSRP(n),this.setIsMSRPInitializing(!1)}),this.setIsMSRPInitializing(!0)}sendMSRP(t,n){const o=this.extendedMessages[t];if(!o)throw new Error(`MSRP session with id ${t} doesn't exist!`);o.sendMSRP(n)}}const Oo={AUDIO:"audio",VIDEO:"video",MSRP:"msrp"};class Md{constructor(t){this.opensips=null,this.session=null,this.name=null,this.name=t}setOpensips(t){this.opensips=t}setSession(t){this.session=t}kill(){this.opensips.kill(this.name)}}class Ld extends Md{constructor(t,n){super(t),this._candidates=[],this._subscribeSent=!1,this._configureSent=!1,this._lastTrickleReceived=!1,this.type=n}connect(t={}){this.opaqueId=this.session.generateOpaqueId();const n=ke.cloneArray(t.extraHeaders),o={from_tag:this.session._from_tag};t.fromUserName&&(o.from_uri=new ln("sip",t.fromUserName,this.session._ua.configuration.uri.host),n.push(`P-Preferred-Identity: ${this.session._ua.configuration.uri.toString()}`)),t.fromDisplayName&&(o.from_display_name=t.fromDisplayName),n.push(`Contact: ${this.session._contact}`),n.push("Content-Type: application/json"),this.session._sessionTimers.enabled&&n.push(`Session-Expires: ${this.session._sessionTimers.defaultExpires}${this.session._ua.configuration.session_timers_force_refresher?";refresher=uac":""}`),this._request=new Tt.InitialOutgoingInviteRequest(this.session.target,this.session._ua,o,n),this._createRTCConnection(),this._sendInitialRequest()}getStream(){return this.stream}getConnection(){return this._connection}_createRTCConnection(){this._connection=new RTCPeerConnection({iceServers:[{urls:"stun:turn.voicenter.co",credential:"kxsjahnsdjns3eds23esd",username:"turn2es21e"}]});let t;this._connection.onicecandidate=n=>{this._connection.signalingState!=="stable"&&this._connection.signalingState!=="have-local-offer"||n.candidate&&(this._candidates.push(n.candidate),clearTimeout(t),t=setTimeout(()=>{this._lastTrickleReceived=!0,this._subscribeSent&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})},500))}}addTracks(t){t.forEach(n=>{this._connection.addTrack(n)})}async _sendInitialRequest(){const t=new Wr(this.session._ua,this._request,{onRequestTimeout:()=>{this.session.onRequestTimeout()},onTransportError:()=>{this.session.onTransportError()},onAuthenticated:s=>{this._request=s},onReceiveResponse:s=>{this._receiveInviteResponse(s)}});if(await this.generateStream(),!this.stream||!this.stream.getTracks().length)return;this.addTracks(this.stream.getTracks());const n={audio:!1,video:!0};this.jsep_offer=await this._connection.createOffer(n),await this._connection.setLocalDescription(this.jsep_offer);const o={janus:"attach",plugin:"janus.plugin.videoroom",opaque_id:this.opaqueId},a=JSON.stringify(o);this._request.body=a,t.send()}_receiveInviteResponse(t){if(this._publisherSubscribeSent||!t.body)return;const n=JSON.parse(t.body);this.handleId=n.data.id;const o={janus:"message",body:{request:"join",room:this.session.room_id,ptype:"publisher",display:this.session.display_name+" (Screen Share)",opaque_id:this.opaqueId},handle_id:this.handleId},a=[this.session.getPTypeHeader(kt.PUBLISHER)];this.session.sendRequest(H.SUBSCRIBE,{extraHeaders:a,body:JSON.stringify(o),eventHandlers:{onSuccessResponse:async s=>{var r,_,d,h;if(s.status_code===200){if(this._subscribeSent=!0,s.body)try{const m=JSON.parse(s.body)||{};((_=(r=m.plugindata)==null?void 0:r.data)==null?void 0:_.videoroom)==="joined"&&this.session.myFeedList.push(m.plugindata.data.id),(h=(d=m.plugindata)==null?void 0:d.data)!=null&&h.publishers&&this.session.receivePublishers(m)}catch(m){console.error(m)}this._lastTrickleReceived&&!this._configureSent&&this._sendConfigureMessage({audio:!0,video:!0})}}}}),this._publisherSubscribeSent=!0}async _sendConfigureMessage(t){const n=this._candidates.map(r=>({janus:"trickle",candidate:r,handle_id:this.handleId,session_id:this.session.session_id})),a={configure:{janus:"message",body:{request:"configure",record:!0,filename:this.session.getRecordFileName(),...t},jsep:this.jsep_offer,handle_id:this.handleId,session_id:this.session.session_id},trickles:[...n]},s=["Content-Type: application/json",this.session.getPTypeHeader(kt.ICE)];this.session.sendRequest(H.INFO,{extraHeaders:s,body:JSON.stringify(a),eventHandlers:{onSuccessResponse:async r=>{this._configureSent=!0;const d=r.data.split(`\r
159
159
  `),h=d[d.length-1],m=JSON.parse(h);await this._connection.setRemoteDescription(m.jsep),this._candidates=[]}}})}_sendDetach(){const t={janus:"detach",handle_id:this.handleId,session_id:this.session.session_id},n=[this.session.getPTypeHeader(kt.DETACH)];this.session.sendRequest(H.INFO,{extraHeaders:n,body:JSON.stringify(t)}),this.session._ua.emit("pluginDetach",this.name)}async stopMedia(){this._connection&&(this._connection.close(),this._connection=null),this.stream&&(this.stream=null)}async stop(){await this.session.stopProcessPlugins(this.type);const t=this._connection.getSenders();t.forEach(n=>{const o=n.track;o&&o.stop()}),t.forEach(n=>{this._connection.removeTrack(n)}),await this.stopMedia(),this._sendDetach()}async generateStream(){throw new Error("generateStream method is not implemented")}}class $d extends Md{constructor(t,n,o={}){super(t),this.stream=null,this.running=!1,this.immediate=!1,this.type="video",this.immediate=o.immediate||!1,this.type=n}start(t){return t}stop(){throw new Error("stop method is not implemented")}async process(t){if(this.immediate){const n=await this.start(t);return this.running=!0,n}return t}async connect(){this.running=!0,await this.session.resyncPlugins(this.type)}terminate(){this.stop()}async kill(){this.stop(),this.running=!1,await this.session.resyncPlugins(this.type)}}class Qv extends bT{constructor(t,n){if(!t.modules.length)throw new Error("options.modules should include at least 1 module");const o={...t.configuration,sockets:t.socketInterfaces.map(a=>new YT.WebSocketInterface(a))};super(o),this.initialized=!1,this.connected=!1,this.logger=console,this.newRTCSessionEventName="newRTCSession",this.registeredEventName="registered",this.unregisteredEventName="unregistered",this.disconnectedEventName="disconnected",this.connectedEventName="connected",this.newMSRPSessionEventName="newMSRPSession",this.isReconnecting=!1,this.activeConnection=!1,this.waitingForSessionHangup=!1,this.waitingForSessionTimeout=null,this.reconnectionAttemptsLimit=1/0,this.reconnectionAttemptsCounter=0,this.audio=null,this.msrp=null,this.video=null,this.listenersList={},this.modules=[],t.pnExtraHeaders&&Object.keys(t.pnExtraHeaders).length&&this.registrator().setExtraContactUriParams(t.pnExtraHeaders),this.options=t,this.modules=t.modules,t.configuration.reconnectionAttemptsLimit&&(this.reconnectionAttemptsLimit=t.configuration.reconnectionAttemptsLimit),n&&PT(n)&&(this.logger=n)}isWaitingForSessionHangup(){return this.waitingForSessionHangup}stopSessionAfterWaiting(){this.setInitialized(!1),this.waitingForSessionHangup=!1,clearTimeout(this.waitingForSessionTimeout),this.waitingForSessionTimeout=null,this.activeConnection&&this.reconnect()}get hasActiveSessions(){return this.modules.includes(Oo.AUDIO)?this.audio.hasActiveAnsweredCalls:!1}on(t,n){return super.on(t,n)}off(t,n){return super.off(t,n)}emit(t,n){return super.emit(t,n)}get sipDomain(){return this.options.sipDomain}use(t){if(this.newStreamPlugins.find(n=>n.name===t.name)||this.processStreamPlugins.find(n=>n.name===t.name))throw new Error(`Plugin with name ${t.name} already exists`);if(t instanceof Ld)t.setOpensips(this),this.newStreamPlugins.push(t);else if(t instanceof $d)t.setOpensips(this),this.processStreamPlugins.push(t);else throw new Error("Wrong plugin instance")}getPlugin(t){return this.newStreamPlugins.find(n=>n.name===t)||this.processStreamPlugins.find(n=>n.name===t)}reconnect(){if(this.reconnectionAttemptsCounter<this.reconnectionAttemptsLimit){const n=5e3*Math.pow(2,this.reconnectionAttemptsCounter);this.reconnectionAttemptsCounter++,setTimeout(this.start.bind(this),n)}else this.emit("reconnectionAttemptsLimitReached",void 0)}begin(){if(this.isConnected()){console.error("Connection is already established");return}return this.modules.includes(Oo.AUDIO)&&(this.audio=new Jv(this)),this.modules.includes(Oo.MSRP)&&(this.msrp=new Xv(this)),this.modules.includes(Oo.VIDEO)&&(this.video=new zv(this)),this.on(this.registeredEventName,()=>{this.logger.log("Successfully registered to",this.options.socketInterfaces[0]),this.setInitialized(!0)}),this.on(this.unregisteredEventName,()=>{this.logger.log("Unregistered from",this.options.socketInterfaces[0]),this.setInitialized(!1)}),this.on(this.connectedEventName,()=>{this.logger.log("Connected to",this.options.socketInterfaces[0]),this.setConnected(!0),this.setReconnecting(!1),this.activeConnection=!0,this.waitingForSessionHangup=!1,this.reconnectionAttemptsCounter=0}),this.on(this.disconnectedEventName,()=>{this.setConnected(!1),!this.isReconnecting&&(this.setReconnecting(!0),this.logger.log("Disconnected from",this.options.socketInterfaces[0]),this.logger.log("Reconnecting to",this.options.socketInterfaces[0]),this.hasActiveSessions?(this.waitingForSessionHangup=!0,this.stop(!1),this.waitingForSessionTimeout=setTimeout(()=>{this.terminateAllSessions(),this.setInitialized(!1),this.waitingForSessionHangup=!1,this.activeConnection&&this.reconnect()},12e5)):(this.stop(),this.setInitialized(!1),this.activeConnection&&this.reconnect()))}),this.logger.log("Connecting to",this.options.socketInterfaces[0]),this.start(),this}disconnect(){this.activeConnection=!1,this.stop()}subscribe(t,n){const a=!this.listenersList[t]||!this.listenersList[t].length?[n]:[...this.listenersList[t],n];this.listenersList={...this.listenersList,[t]:a}}removeIListener(t){const n={...this.listenersList};delete n[t],this.listenersList={...n}}triggerListener({listenerType:t,session:n,event:o}){const a=this.listenersList[t];!a||!a.length||a.forEach(s=>{s(n,o)})}setInitialized(t){this.initialized=t,this.emit("ready",t)}setConnected(t){this.connected=t,this.emit("connection",t)}setReconnecting(t){this.isReconnecting=t,this.emit("reconnecting",t)}}return Wt.BaseNewStreamPlugin=Ld,Wt.BaseProcessStreamPlugin=$d,Wt.default=Qv,Object.defineProperties(Wt,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),Wt}({});