@shenyin/embedded-call-widget 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- var EmbeddedCallWidgetRuntimeBundle=(function($e){"use strict";const dt="0.21.1";class ne extends Error{constructor(e){super(e),Object.setPrototypeOf(this,new.target.prototype)}}class _e extends ne{constructor(e){super(e||"Unsupported content type.")}}class fe extends ne{constructor(e){super(e||"Request pending.")}}class lt extends ne{constructor(e){super(e||"Unspecified session description handler error.")}}class De extends ne{constructor(){super("The session has terminated.")}}class pe extends ne{constructor(e){super(e||"An error occurred during state transition.")}}class ht{constructor(e){this.incomingAckRequest=e}get request(){return this.incomingAckRequest.message}}class ut{constructor(e){this.incomingByeRequest=e}get request(){return this.incomingByeRequest.message}accept(e){return this.incomingByeRequest.accept(e),Promise.resolve()}reject(e){return this.incomingByeRequest.reject(e),Promise.resolve()}}class gt{constructor(e){this.incomingCancelRequest=e}get request(){return this.incomingCancelRequest}}class me{constructor(){this.listeners=new Array}addListener(e,t){const s=i=>{this.removeListener(s),e(i)};t?.once===!0?this.listeners.push(s):this.listeners.push(e)}emit(e){this.listeners.slice().forEach(t=>t(e))}removeAllListeners(){this.listeners=[]}removeListener(e){this.listeners=this.listeners.filter(t=>t!==e)}on(e){return this.addListener(e)}off(e){return this.removeListener(e)}once(e){return this.addListener(e,{once:!0})}}class ft{constructor(e){this.incomingInfoRequest=e}get request(){return this.incomingInfoRequest.message}accept(e){return this.incomingInfoRequest.accept(e),Promise.resolve()}reject(e){return this.incomingInfoRequest.reject(e),Promise.resolve()}}class Be{constructor(e){this.parameters={};for(const t in e)e.hasOwnProperty(t)&&this.setParam(t,e[t])}setParam(e,t){e&&(this.parameters[e.toLowerCase()]=typeof t>"u"||t===null?null:t.toString())}getParam(e){if(e)return this.parameters[e.toLowerCase()]}hasParam(e){return!!(e&&this.parameters[e.toLowerCase()]!==void 0)}deleteParam(e){if(e=e.toLowerCase(),this.hasParam(e)){const t=this.parameters[e];return delete this.parameters[e],t}}clearParams(){this.parameters={}}}class O extends Be{constructor(e,t,s){super(s),this.uri=e,this._displayName=t}get friendlyName(){return this.displayName||this.uri.aor}get displayName(){return this._displayName}set displayName(e){this._displayName=e}clone(){return new O(this.uri.clone(),this._displayName,JSON.parse(JSON.stringify(this.parameters)))}toString(){let e=this.displayName||this.displayName==="0"?'"'+this.displayName+'" ':"";e+="<"+this.uri.toString()+">";for(const t in this.parameters)this.parameters.hasOwnProperty(t)&&(e+=";"+t,this.parameters[t]!==null&&(e+="="+this.parameters[t]));return e}}class K extends Be{constructor(e="sip",t,s,i,r,n){if(super(r||{}),this.headers={},!s)throw new TypeError('missing or invalid "host" parameter');for(const o in n)n.hasOwnProperty(o)&&this.setHeader(o,n[o]);this.raw={scheme:e,user:t,host:s,port:i},this.normal={scheme:e.toLowerCase(),user:t,host:s.toLowerCase(),port:i}}get scheme(){return this.normal.scheme}set scheme(e){this.raw.scheme=e,this.normal.scheme=e.toLowerCase()}get user(){return this.normal.user}set user(e){this.normal.user=this.raw.user=e}get host(){return this.normal.host}set host(e){this.raw.host=e,this.normal.host=e.toLowerCase()}get aor(){return this.normal.user+"@"+this.normal.host}get port(){return this.normal.port}set port(e){this.normal.port=this.raw.port=e}setHeader(e,t){this.headers[this.headerize(e)]=t instanceof Array?t:[t]}getHeader(e){if(e)return this.headers[this.headerize(e)]}hasHeader(e){return!!e&&!!this.headers.hasOwnProperty(this.headerize(e))}deleteHeader(e){if(e=this.headerize(e),this.headers.hasOwnProperty(e)){const t=this.headers[e];return delete this.headers[e],t}}clearHeaders(){this.headers={}}clone(){return new K(this._raw.scheme,this._raw.user||"",this._raw.host,this._raw.port,JSON.parse(JSON.stringify(this.parameters)),JSON.parse(JSON.stringify(this.headers)))}toRaw(){return this._toString(this._raw)}toString(){return this._toString(this._normal)}get _normal(){return this.normal}get _raw(){return this.raw}_toString(e){let t=e.scheme+":";e.scheme.toLowerCase().match("^sips?$")||(t+="//"),e.user&&(t+=this.escapeUser(e.user)+"@"),t+=e.host,(e.port||e.port===0)&&(t+=":"+e.port);for(const i in this.parameters)this.parameters.hasOwnProperty(i)&&(t+=";"+i,this.parameters[i]!==null&&(t+="="+this.parameters[i]));const s=[];for(const i in this.headers)if(this.headers.hasOwnProperty(i))for(const r in this.headers[i])this.headers[i].hasOwnProperty(r)&&s.push(i+"="+this.headers[i][r]);return s.length>0&&(t+="?"+s.join("&")),t}escapeUser(e){let t;try{t=decodeURIComponent(e)}catch(s){throw s}return encodeURIComponent(t).replace(/%3A/ig,":").replace(/%2B/ig,"+").replace(/%3F/ig,"?").replace(/%2F/ig,"/")}headerize(e){const t={"Call-Id":"Call-ID",Cseq:"CSeq","Min-Se":"Min-SE",Rack:"RAck",Rseq:"RSeq","Www-Authenticate":"WWW-Authenticate"},s=e.toLowerCase().replace(/_/g,"-").split("-"),i=s.length;let r="";for(let n=0;n<i;n++)n!==0&&(r+="-"),r+=s[n].charAt(0).toUpperCase()+s[n].substring(1);return t[r]&&(r=t[r]),r}}function Le(a,e){if(a.scheme!==e.scheme||a.user!==e.user||a.host!==e.host||a.port!==e.port)return!1;function t(r,n){const o=Object.keys(r.parameters),d=Object.keys(n.parameters);return!(!o.filter(g=>d.includes(g)).every(g=>r.parameters[g]===n.parameters[g])||!["user","ttl","method","transport"].every(g=>r.hasParam(g)&&n.hasParam(g)||!r.hasParam(g)&&!n.hasParam(g))||!["maddr"].every(g=>r.hasParam(g)&&n.hasParam(g)||!r.hasParam(g)&&!n.hasParam(g)))}if(!t(a,e))return!1;const s=Object.keys(a.headers),i=Object.keys(e.headers);if(s.length!==0||i.length!==0){if(s.length!==i.length)return!1;const r=s.filter(n=>i.includes(n));if(r.length!==i.length||!r.every(n=>a.headers[n].length&&e.headers[n].length&&a.headers[n][0]===e.headers[n][0]))return!1}return!0}function ke(a,e,t){return t=t||" ",a.length>e?a:(e-=a.length,t+=t.repeat(e),a+t.slice(0,e))}class le extends Error{constructor(e,t,s,i){super(),this.message=e,this.expected=t,this.found=s,this.location=i,this.name="SyntaxError",typeof Object.setPrototypeOf=="function"?Object.setPrototypeOf(this,le.prototype):this.__proto__=le.prototype,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,le)}static buildMessage(e,t){function s(p){return p.charCodeAt(0).toString(16).toUpperCase()}function i(p){return p.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+s(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+s(g))}function r(p){return p.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+s(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+s(g))}function n(p){switch(p.type){case"literal":return'"'+i(p.text)+'"';case"class":const g=p.parts.map(w=>Array.isArray(w)?r(w[0])+"-"+r(w[1]):r(w));return"["+(p.inverted?"^":"")+g+"]";case"any":return"any character";case"end":return"end of input";case"other":return p.description}}function o(p){const g=p.map(n);let w,S;if(g.sort(),g.length>0){for(w=1,S=1;w<g.length;w++)g[w-1]!==g[w]&&(g[S]=g[w],S++);g.length=S}switch(g.length){case 1:return g[0];case 2:return g[0]+" or "+g[1];default:return g.slice(0,-1).join(", ")+", or "+g[g.length-1]}}function d(p){return p?'"'+i(p)+'"':"end of input"}return"Expected "+o(e)+" but "+d(t)+" found."}format(e){let t="Error: "+this.message;if(this.location){let s=null,i;for(i=0;i<e.length;i++)if(e[i].source===this.location.source){s=e[i].text.split(/\r\n|\n|\r/g);break}let r=this.location.start,n=this.location.source+":"+r.line+":"+r.column;if(s){let o=this.location.end,d=ke("",r.line.toString().length," "),p=s[r.line-1],g=r.line===o.line?o.column:p.length+1;t+=`
1
+ var EmbeddedCallWidgetRuntimeBundle=(function($e){"use strict";const dt="0.21.1";class ne extends Error{constructor(e){super(e),Object.setPrototypeOf(this,new.target.prototype)}}class _e extends ne{constructor(e){super(e||"Unsupported content type.")}}class fe extends ne{constructor(e){super(e||"Request pending.")}}class lt extends ne{constructor(e){super(e||"Unspecified session description handler error.")}}class De extends ne{constructor(){super("The session has terminated.")}}class pe extends ne{constructor(e){super(e||"An error occurred during state transition.")}}class ht{constructor(e){this.incomingAckRequest=e}get request(){return this.incomingAckRequest.message}}class ut{constructor(e){this.incomingByeRequest=e}get request(){return this.incomingByeRequest.message}accept(e){return this.incomingByeRequest.accept(e),Promise.resolve()}reject(e){return this.incomingByeRequest.reject(e),Promise.resolve()}}class gt{constructor(e){this.incomingCancelRequest=e}get request(){return this.incomingCancelRequest}}class me{constructor(){this.listeners=new Array}addListener(e,t){const s=i=>{this.removeListener(s),e(i)};t?.once===!0?this.listeners.push(s):this.listeners.push(e)}emit(e){this.listeners.slice().forEach(t=>t(e))}removeAllListeners(){this.listeners=[]}removeListener(e){this.listeners=this.listeners.filter(t=>t!==e)}on(e){return this.addListener(e)}off(e){return this.removeListener(e)}once(e){return this.addListener(e,{once:!0})}}class ft{constructor(e){this.incomingInfoRequest=e}get request(){return this.incomingInfoRequest.message}accept(e){return this.incomingInfoRequest.accept(e),Promise.resolve()}reject(e){return this.incomingInfoRequest.reject(e),Promise.resolve()}}class Le{constructor(e){this.parameters={};for(const t in e)e.hasOwnProperty(t)&&this.setParam(t,e[t])}setParam(e,t){e&&(this.parameters[e.toLowerCase()]=typeof t>"u"||t===null?null:t.toString())}getParam(e){if(e)return this.parameters[e.toLowerCase()]}hasParam(e){return!!(e&&this.parameters[e.toLowerCase()]!==void 0)}deleteParam(e){if(e=e.toLowerCase(),this.hasParam(e)){const t=this.parameters[e];return delete this.parameters[e],t}}clearParams(){this.parameters={}}}class O extends Le{constructor(e,t,s){super(s),this.uri=e,this._displayName=t}get friendlyName(){return this.displayName||this.uri.aor}get displayName(){return this._displayName}set displayName(e){this._displayName=e}clone(){return new O(this.uri.clone(),this._displayName,JSON.parse(JSON.stringify(this.parameters)))}toString(){let e=this.displayName||this.displayName==="0"?'"'+this.displayName+'" ':"";e+="<"+this.uri.toString()+">";for(const t in this.parameters)this.parameters.hasOwnProperty(t)&&(e+=";"+t,this.parameters[t]!==null&&(e+="="+this.parameters[t]));return e}}class K extends Le{constructor(e="sip",t,s,i,r,n){if(super(r||{}),this.headers={},!s)throw new TypeError('missing or invalid "host" parameter');for(const o in n)n.hasOwnProperty(o)&&this.setHeader(o,n[o]);this.raw={scheme:e,user:t,host:s,port:i},this.normal={scheme:e.toLowerCase(),user:t,host:s.toLowerCase(),port:i}}get scheme(){return this.normal.scheme}set scheme(e){this.raw.scheme=e,this.normal.scheme=e.toLowerCase()}get user(){return this.normal.user}set user(e){this.normal.user=this.raw.user=e}get host(){return this.normal.host}set host(e){this.raw.host=e,this.normal.host=e.toLowerCase()}get aor(){return this.normal.user+"@"+this.normal.host}get port(){return this.normal.port}set port(e){this.normal.port=this.raw.port=e}setHeader(e,t){this.headers[this.headerize(e)]=t instanceof Array?t:[t]}getHeader(e){if(e)return this.headers[this.headerize(e)]}hasHeader(e){return!!e&&!!this.headers.hasOwnProperty(this.headerize(e))}deleteHeader(e){if(e=this.headerize(e),this.headers.hasOwnProperty(e)){const t=this.headers[e];return delete this.headers[e],t}}clearHeaders(){this.headers={}}clone(){return new K(this._raw.scheme,this._raw.user||"",this._raw.host,this._raw.port,JSON.parse(JSON.stringify(this.parameters)),JSON.parse(JSON.stringify(this.headers)))}toRaw(){return this._toString(this._raw)}toString(){return this._toString(this._normal)}get _normal(){return this.normal}get _raw(){return this.raw}_toString(e){let t=e.scheme+":";e.scheme.toLowerCase().match("^sips?$")||(t+="//"),e.user&&(t+=this.escapeUser(e.user)+"@"),t+=e.host,(e.port||e.port===0)&&(t+=":"+e.port);for(const i in this.parameters)this.parameters.hasOwnProperty(i)&&(t+=";"+i,this.parameters[i]!==null&&(t+="="+this.parameters[i]));const s=[];for(const i in this.headers)if(this.headers.hasOwnProperty(i))for(const r in this.headers[i])this.headers[i].hasOwnProperty(r)&&s.push(i+"="+this.headers[i][r]);return s.length>0&&(t+="?"+s.join("&")),t}escapeUser(e){let t;try{t=decodeURIComponent(e)}catch(s){throw s}return encodeURIComponent(t).replace(/%3A/ig,":").replace(/%2B/ig,"+").replace(/%3F/ig,"?").replace(/%2F/ig,"/")}headerize(e){const t={"Call-Id":"Call-ID",Cseq:"CSeq","Min-Se":"Min-SE",Rack:"RAck",Rseq:"RSeq","Www-Authenticate":"WWW-Authenticate"},s=e.toLowerCase().replace(/_/g,"-").split("-"),i=s.length;let r="";for(let n=0;n<i;n++)n!==0&&(r+="-"),r+=s[n].charAt(0).toUpperCase()+s[n].substring(1);return t[r]&&(r=t[r]),r}}function Be(a,e){if(a.scheme!==e.scheme||a.user!==e.user||a.host!==e.host||a.port!==e.port)return!1;function t(r,n){const o=Object.keys(r.parameters),d=Object.keys(n.parameters);return!(!o.filter(g=>d.includes(g)).every(g=>r.parameters[g]===n.parameters[g])||!["user","ttl","method","transport"].every(g=>r.hasParam(g)&&n.hasParam(g)||!r.hasParam(g)&&!n.hasParam(g))||!["maddr"].every(g=>r.hasParam(g)&&n.hasParam(g)||!r.hasParam(g)&&!n.hasParam(g)))}if(!t(a,e))return!1;const s=Object.keys(a.headers),i=Object.keys(e.headers);if(s.length!==0||i.length!==0){if(s.length!==i.length)return!1;const r=s.filter(n=>i.includes(n));if(r.length!==i.length||!r.every(n=>a.headers[n].length&&e.headers[n].length&&a.headers[n][0]===e.headers[n][0]))return!1}return!0}function ke(a,e,t){return t=t||" ",a.length>e?a:(e-=a.length,t+=t.repeat(e),a+t.slice(0,e))}class le extends Error{constructor(e,t,s,i){super(),this.message=e,this.expected=t,this.found=s,this.location=i,this.name="SyntaxError",typeof Object.setPrototypeOf=="function"?Object.setPrototypeOf(this,le.prototype):this.__proto__=le.prototype,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,le)}static buildMessage(e,t){function s(p){return p.charCodeAt(0).toString(16).toUpperCase()}function i(p){return p.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+s(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+s(g))}function r(p){return p.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,g=>"\\x0"+s(g)).replace(/[\x10-\x1F\x7F-\x9F]/g,g=>"\\x"+s(g))}function n(p){switch(p.type){case"literal":return'"'+i(p.text)+'"';case"class":const g=p.parts.map(w=>Array.isArray(w)?r(w[0])+"-"+r(w[1]):r(w));return"["+(p.inverted?"^":"")+g+"]";case"any":return"any character";case"end":return"end of input";case"other":return p.description}}function o(p){const g=p.map(n);let w,S;if(g.sort(),g.length>0){for(w=1,S=1;w<g.length;w++)g[w-1]!==g[w]&&(g[S]=g[w],S++);g.length=S}switch(g.length){case 1:return g[0];case 2:return g[0]+" or "+g[1];default:return g.slice(0,-1).join(", ")+", or "+g[g.length-1]}}function d(p){return p?'"'+i(p)+'"':"end of input"}return"Expected "+o(e)+" but "+d(t)+" found."}format(e){let t="Error: "+this.message;if(this.location){let s=null,i;for(i=0;i<e.length;i++)if(e[i].source===this.location.source){s=e[i].text.split(/\r\n|\n|\r/g);break}let r=this.location.start,n=this.location.source+":"+r.line+":"+r.column;if(s){let o=this.location.end,d=ke("",r.line.toString().length," "),p=s[r.line-1],g=r.line===o.line?o.column:p.length+1;t+=`
2
2
  --> `+n+`
3
3
  `+d+` |
4
4
  `+r.line+" | "+p+`
@@ -19,7 +19,7 @@ var EmbeddedCallWidgetRuntimeBundle=(function($e){"use strict";const dt="0.21.1"
19
19
  \r
20
20
  `:e+=`Content-Length: 0\r
21
21
  \r
22
- `,e}}function Ge(a){return a==="application/sdp"?"session":"render"}function Ee(a){const e=typeof a=="string"?a:a.body,t=typeof a=="string"?"application/sdp":a.contentType;return{contentDisposition:Ge(t),contentType:t,content:e}}function Ve(a){return a&&typeof a.content=="string"&&typeof a.contentType=="string"&&a.contentDisposition===void 0?!0:typeof a.contentDisposition=="string"}function be(a){let e,t,s;if(a instanceof he&&a.body){const i=a.parseHeader("Content-Disposition");e=i?i.type:void 0,t=a.parseHeader("Content-Type"),s=a.body}if(a instanceof Q&&a.body){const i=a.parseHeader("Content-Disposition");e=i?i.type:void 0,t=a.parseHeader("Content-Type"),s=a.body}if(a instanceof ae&&a.body)if(e=a.getHeader("Content-Disposition"),t=a.getHeader("Content-Type"),typeof a.body=="string"){if(!t)throw new Error("Header content type header does not equal body content type.");s=a.body}else{if(t&&t!==a.body.contentType)throw new Error("Header content type header does not equal body content type.");t=a.body.contentType,s=a.body.body}if(Ve(a)&&(e=a.contentDisposition,t=a.contentType,s=a.content),!!s){if(t&&!e&&(e=Ge(t)),!e)throw new Error("Content disposition undefined.");if(!t)throw new Error("Content type undefined.");return{contentDisposition:e,contentType:t,content:s}}}var L;(function(a){a.Initial="Initial",a.Early="Early",a.AckWait="AckWait",a.Confirmed="Confirmed",a.Terminated="Terminated"})(L=L||(L={}));var v;(function(a){a.Initial="Initial",a.HaveLocalOffer="HaveLocalOffer",a.HaveRemoteOffer="HaveRemoteOffer",a.Stable="Stable",a.Closed="Closed"})(v=v||(v={}));const Z=500,bt=4e3,Ke=5e3,H={T1:Z,T2:bt,TIMER_B:64*Z,TIMER_D:0*Z,TIMER_F:64*Z,TIMER_H:64*Z,TIMER_I:0*Ke,TIMER_J:0*Z,TIMER_K:0*Ke,TIMER_L:64*Z,TIMER_M:64*Z,TIMER_N:64*Z,PROVISIONAL_RESPONSE_INTERVAL:6e4};class ee extends ne{constructor(e){super(e||"Transaction state error.")}}var y;(function(a){a.ACK="ACK",a.BYE="BYE",a.CANCEL="CANCEL",a.INFO="INFO",a.INVITE="INVITE",a.MESSAGE="MESSAGE",a.NOTIFY="NOTIFY",a.OPTIONS="OPTIONS",a.REGISTER="REGISTER",a.UPDATE="UPDATE",a.SUBSCRIBE="SUBSCRIBE",a.PUBLISH="PUBLISH",a.REFER="REFER",a.PRACK="PRACK"})(y=y||(y={}));const te=[y.ACK,y.BYE,y.CANCEL,y.INFO,y.INVITE,y.MESSAGE,y.NOTIFY,y.OPTIONS,y.PRACK,y.REFER,y.REGISTER,y.SUBSCRIBE];class We{constructor(e){this.incomingMessageRequest=e}get request(){return this.incomingMessageRequest.message}accept(e){return this.incomingMessageRequest.accept(e),Promise.resolve()}reject(e){return this.incomingMessageRequest.reject(e),Promise.resolve()}}class Pe{constructor(e){this.incomingNotifyRequest=e}get request(){return this.incomingNotifyRequest.message}accept(e){return this.incomingNotifyRequest.accept(e),Promise.resolve()}reject(e){return this.incomingNotifyRequest.reject(e),Promise.resolve()}}class vt{constructor(e,t){this.incomingReferRequest=e,this.session=t}get referTo(){const e=this.incomingReferRequest.message.parseHeader("refer-to");if(!(e instanceof O))throw new Error("Failed to parse Refer-To header.");return e}get referredBy(){return this.incomingReferRequest.message.getHeader("referred-by")}get replaces(){const e=this.referTo.uri.getHeader("replaces");return e instanceof Array?e[0]:e}get request(){return this.incomingReferRequest.message}accept(e={statusCode:202}){return this.incomingReferRequest.accept(e),Promise.resolve()}reject(e){return this.incomingReferRequest.reject(e),Promise.resolve()}makeInviter(e){if(this.inviter)return this.inviter;const t=this.referTo.uri.clone();t.clearHeaders(),e=e||{};const s=(e.extraHeaders||[]).slice(),i=this.replaces;i&&s.push("Replaces: "+decodeURIComponent(i));const r=this.referredBy;return r&&s.push("Referred-By: "+r),e.extraHeaders=s,this.inviter=this.session.userAgent._makeInviter(t,e),this.inviter._referred=this.session,this.session._referral=this.inviter,this.inviter}}var m;(function(a){a.Initial="Initial",a.Establishing="Establishing",a.Established="Established",a.Terminating="Terminating",a.Terminated="Terminated"})(m=m||(m={}));class ue{constructor(e,t={}){this.pendingReinvite=!1,this.pendingReinviteAck=!1,this._state=m.Initial,this.delegate=t.delegate,this._stateEventEmitter=new me,this._userAgent=e}dispose(){switch(this.logger.log(`Session ${this.id} in state ${this._state} is being disposed`),delete this.userAgent._sessions[this.id],this._sessionDescriptionHandler&&this._sessionDescriptionHandler.close(),this.state){case m.Initial:break;case m.Establishing:break;case m.Established:return new Promise(e=>{this._bye({onAccept:()=>e(),onRedirect:()=>e(),onReject:()=>e()})});case m.Terminating:break;case m.Terminated:break;default:throw new Error("Unknown state.")}return Promise.resolve()}get assertedIdentity(){return this._assertedIdentity}get dialog(){return this._dialog}get id(){return this._id}get replacee(){return this._replacee}get sessionDescriptionHandler(){return this._sessionDescriptionHandler}get sessionDescriptionHandlerFactory(){return this.userAgent.configuration.sessionDescriptionHandlerFactory}get sessionDescriptionHandlerModifiers(){return this._sessionDescriptionHandlerModifiers||[]}set sessionDescriptionHandlerModifiers(e){this._sessionDescriptionHandlerModifiers=e.slice()}get sessionDescriptionHandlerOptions(){return this._sessionDescriptionHandlerOptions||{}}set sessionDescriptionHandlerOptions(e){this._sessionDescriptionHandlerOptions=Object.assign({},e)}get sessionDescriptionHandlerModifiersReInvite(){return this._sessionDescriptionHandlerModifiersReInvite||[]}set sessionDescriptionHandlerModifiersReInvite(e){this._sessionDescriptionHandlerModifiersReInvite=e.slice()}get sessionDescriptionHandlerOptionsReInvite(){return this._sessionDescriptionHandlerOptionsReInvite||{}}set sessionDescriptionHandlerOptionsReInvite(e){this._sessionDescriptionHandlerOptionsReInvite=Object.assign({},e)}get state(){return this._state}get stateChange(){return this._stateEventEmitter}get userAgent(){return this._userAgent}bye(e={}){let t="Session.bye() may only be called if established session.";switch(this.state){case m.Initial:typeof this.cancel=="function"?(t+=" However Inviter.invite() has not yet been called.",t+=" Perhaps you should have called Inviter.cancel()?"):typeof this.reject=="function"&&(t+=" However Invitation.accept() has not yet been called.",t+=" Perhaps you should have called Invitation.reject()?");break;case m.Establishing:typeof this.cancel=="function"?(t+=" However a dialog does not yet exist.",t+=" Perhaps you should have called Inviter.cancel()?"):typeof this.reject=="function"&&(t+=" However Invitation.accept() has not yet been called (or not yet resolved).",t+=" Perhaps you should have called Invitation.reject()?");break;case m.Established:{const s=e.requestDelegate,i=this.copyRequestOptions(e.requestOptions);return this._bye(s,i)}case m.Terminating:t+=" However this session is already terminating.",typeof this.cancel=="function"?t+=" Perhaps you have already called Inviter.cancel()?":typeof this.reject=="function"&&(t+=" Perhaps you have already called Session.bye()?");break;case m.Terminated:t+=" However this session is already terminated.";break;default:throw new Error("Unknown state")}return this.logger.error(t),Promise.reject(new Error(`Invalid session state ${this.state}`))}info(e={}){if(this.state!==m.Established)return this.logger.error("Session.info() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.requestDelegate,s=this.copyRequestOptions(e.requestOptions);return this._info(t,s)}invite(e={}){if(this.logger.log("Session.invite"),this.state!==m.Established)return Promise.reject(new Error(`Invalid session state ${this.state}`));if(this.pendingReinvite)return Promise.reject(new fe("Reinvite in progress. Please wait until complete, then try again."));this.pendingReinvite=!0,e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiersReInvite=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptionsReInvite=e.sessionDescriptionHandlerOptions);const t={onAccept:r=>{const n=be(r.message);if(!n){this.logger.error("Received 2xx response to re-INVITE without a session description"),this.ackAndBye(r,400,"Missing session description"),this.stateTransition(m.Terminated),this.pendingReinvite=!1;return}if(e.withoutSdp){const o={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.setOfferAndGetAnswer(n,o).then(d=>{r.ack({body:d})}).catch(d=>{this.logger.error("Failed to handle offer in 2xx response to re-INVITE"),this.logger.error(d.message),this.state===m.Terminated?r.ack():(this.ackAndBye(r,488,"Bad Media Description"),this.stateTransition(m.Terminated))}).then(()=>{this.pendingReinvite=!1,e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(r)})}else{const o={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.setAnswer(n,o).then(()=>{r.ack()}).catch(d=>{this.logger.error("Failed to handle answer in 2xx response to re-INVITE"),this.logger.error(d.message),this.state!==m.Terminated?(this.ackAndBye(r,488,"Bad Media Description"),this.stateTransition(m.Terminated)):r.ack()}).then(()=>{this.pendingReinvite=!1,e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(r)})}},onProgress:r=>{},onRedirect:r=>{},onReject:r=>{this.logger.warn("Received a non-2xx response to re-INVITE"),this.pendingReinvite=!1,e.withoutSdp?e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(r):this.rollbackOffer().catch(n=>{if(this.logger.error("Failed to rollback offer on non-2xx response to re-INVITE"),this.logger.error(n.message),this.state!==m.Terminated){if(!this.dialog)throw new Error("Dialog undefined.");const o=[];o.push("Reason: "+this.getReasonHeaderValue(500,"Internal Server Error")),this.dialog.bye(void 0,{extraHeaders:o}),this.stateTransition(m.Terminated)}}).then(()=>{e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(r)})},onTrying:r=>{}},s=e.requestOptions||{};if(s.extraHeaders=(s.extraHeaders||[]).slice(),s.extraHeaders.push("Allow: "+te.toString()),s.extraHeaders.push("Contact: "+this._contact),e.withoutSdp){if(!this.dialog)throw this.pendingReinvite=!1,new Error("Dialog undefined.");return Promise.resolve(this.dialog.invite(t,s))}const i={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};return this.getOffer(i).then(r=>{if(!this.dialog)throw this.pendingReinvite=!1,new Error("Dialog undefined.");return s.body=r,this.dialog.invite(t,s)}).catch(r=>{throw this.logger.error(r.message),this.logger.error("Failed to send re-INVITE"),this.pendingReinvite=!1,r})}message(e={}){if(this.state!==m.Established)return this.logger.error("Session.message() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.requestDelegate,s=this.copyRequestOptions(e.requestOptions);return this._message(t,s)}refer(e,t={}){if(this.state!==m.Established)return this.logger.error("Session.refer() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));if(e instanceof ue&&!e.dialog)return this.logger.error("Session.refer() may only be called with session which is established. You are perhaps attempting to attended transfer to a target for which there is not dialog yet established. Perhaps you are attempting a 'semi-attended' tansfer? Regardless, this is not supported. The recommended approached is to check to see if the target Session is in the Established state before calling refer(); if the state is not Established you may proceed by falling back using a URI as the target (blind transfer)."),Promise.reject(new Error(`Invalid session state ${this.state}`));const s=t.requestDelegate,i=this.copyRequestOptions(t.requestOptions);return i.extraHeaders=i.extraHeaders?i.extraHeaders.concat(this.referExtraHeaders(this.referToString(e))):this.referExtraHeaders(this.referToString(e)),this._refer(t.onNotify,s,i)}_bye(e,t){if(!this.dialog)return Promise.reject(new Error("Session dialog undefined."));const s=this.dialog;switch(s.sessionState){case L.Initial:throw new Error(`Invalid dialog state ${s.sessionState}`);case L.Early:throw new Error(`Invalid dialog state ${s.sessionState}`);case L.AckWait:return this.stateTransition(m.Terminating),new Promise(i=>{s.delegate={onAck:()=>{const r=s.bye(e,t);return this.stateTransition(m.Terminated),i(r),Promise.resolve()},onAckTimeout:()=>{const r=s.bye(e,t);this.stateTransition(m.Terminated),i(r)}}});case L.Confirmed:{const i=s.bye(e,t);return this.stateTransition(m.Terminated),Promise.resolve(i)}case L.Terminated:throw new Error(`Invalid dialog state ${s.sessionState}`);default:throw new Error("Unrecognized state.")}}_info(e,t){return this.dialog?Promise.resolve(this.dialog.info(e,t)):Promise.reject(new Error("Session dialog undefined."))}_message(e,t){return this.dialog?Promise.resolve(this.dialog.message(e,t)):Promise.reject(new Error("Session dialog undefined."))}_refer(e,t,s){return this.dialog?(this.onNotify=e,Promise.resolve(this.dialog.refer(t,s))):Promise.reject(new Error("Session dialog undefined."))}ackAndBye(e,t,s){e.ack();const i=[];t&&i.push("Reason: "+this.getReasonHeaderValue(t,s)),e.session.bye(void 0,{extraHeaders:i})}onAckRequest(e){if(this.logger.log("Session.onAckRequest"),this.state!==m.Established&&this.state!==m.Terminating)return this.logger.error(`ACK received while in state ${this.state}, dropping request`),Promise.resolve();const t=this.dialog;if(!t)throw new Error("Dialog undefined.");const s={sessionDescriptionHandlerOptions:this.pendingReinviteAck?this.sessionDescriptionHandlerOptionsReInvite:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.pendingReinviteAck?this._sessionDescriptionHandlerModifiersReInvite:this._sessionDescriptionHandlerModifiers};if(this.delegate&&this.delegate.onAck){const i=new ht(e);this.delegate.onAck(i)}switch(this.pendingReinviteAck=!1,t.signalingState){case v.Initial:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.Stable:{const i=be(e.message);return i?i.contentDisposition==="render"?(this._renderbody=i.content,this._rendertype=i.contentType,Promise.resolve()):i.contentDisposition!=="session"?Promise.resolve():this.setAnswer(i,s).catch(r=>{this.logger.error(r.message);const n=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];t.bye(void 0,{extraHeaders:n}),this.stateTransition(m.Terminated)}):Promise.resolve()}case v.HaveLocalOffer:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.HaveRemoteOffer:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.Closed:throw new Error(`Invalid signaling state ${t.signalingState}.`);default:throw new Error(`Invalid signaling state ${t.signalingState}.`)}}onByeRequest(e){if(this.logger.log("Session.onByeRequest"),this.state!==m.Established){this.logger.error(`BYE received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onBye){const t=new ut(e);this.delegate.onBye(t)}else e.accept();this.stateTransition(m.Terminated)}onInfoRequest(e){if(this.logger.log("Session.onInfoRequest"),this.state!==m.Established){this.logger.error(`INFO received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onInfo){const t=new ft(e);this.delegate.onInfo(t)}else e.accept()}onInviteRequest(e){if(this.logger.log("Session.onInviteRequest"),this.state!==m.Established){this.logger.error(`INVITE received while in state ${this.state}, dropping request`);return}this.pendingReinviteAck=!0;const t=["Contact: "+this._contact];if(e.message.hasHeader("P-Asserted-Identity")){const i=e.message.getHeader("P-Asserted-Identity");if(!i)throw new Error("Header undefined.");this._assertedIdentity=D.nameAddrHeaderParse(i)}const s={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.generateResponseOfferAnswerInDialog(s).then(i=>{const r=e.accept({statusCode:200,extraHeaders:t,body:i});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,200)}).catch(i=>{if(this.logger.error(i.message),this.logger.error("Failed to handle to re-INVITE request"),!this.dialog)throw new Error("Dialog undefined.");if(this.logger.error(this.dialog.signalingState),this.dialog.signalingState===v.Stable){const r=e.reject({statusCode:488});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,488);return}this.rollbackOffer().then(()=>{const r=e.reject({statusCode:488});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,488)}).catch(r=>{this.logger.error(r.message),this.logger.error("Failed to rollback offer on re-INVITE request");const n=e.reject({statusCode:488});if(this.state!==m.Terminated){if(!this.dialog)throw new Error("Dialog undefined.");const o=[];o.push("Reason: "+this.getReasonHeaderValue(500,"Internal Server Error")),this.dialog.bye(void 0,{extraHeaders:o}),this.stateTransition(m.Terminated)}this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,n.message,488)})})}onMessageRequest(e){if(this.logger.log("Session.onMessageRequest"),this.state!==m.Established){this.logger.error(`MESSAGE received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onMessage){const t=new We(e);this.delegate.onMessage(t)}else e.accept()}onNotifyRequest(e){if(this.logger.log("Session.onNotifyRequest"),this.state!==m.Established){this.logger.error(`NOTIFY received while in state ${this.state}, dropping request`);return}if(this.onNotify){const t=new Pe(e);this.onNotify(t);return}if(this.delegate&&this.delegate.onNotify){const t=new Pe(e);this.delegate.onNotify(t)}else e.accept()}onPrackRequest(e){if(this.logger.log("Session.onPrackRequest"),this.state!==m.Established){this.logger.error(`PRACK received while in state ${this.state}, dropping request`);return}throw new Error("Unimplemented.")}onReferRequest(e){if(this.logger.log("Session.onReferRequest"),this.state!==m.Established){this.logger.error(`REFER received while in state ${this.state}, dropping request`);return}if(!e.message.hasHeader("refer-to")){this.logger.warn("Invalid REFER packet. A refer-to header is required. Rejecting."),e.reject();return}const t=new vt(e,this);this.delegate&&this.delegate.onRefer?this.delegate.onRefer(t):(this.logger.log("No delegate available to handle REFER, automatically accepting and following."),t.accept().then(()=>t.makeInviter(this._referralInviterOptions).invite()).catch(s=>{this.logger.error(s.message)}))}generateResponseOfferAnswer(e,t){if(this.dialog)return this.generateResponseOfferAnswerInDialog(t);const s=be(e.message);return!s||s.contentDisposition!=="session"?this.getOffer(t):this.setOfferAndGetAnswer(s,t)}generateResponseOfferAnswerInDialog(e){if(!this.dialog)throw new Error("Dialog undefined.");switch(this.dialog.signalingState){case v.Initial:return this.getOffer(e);case v.HaveLocalOffer:return Promise.resolve(void 0);case v.HaveRemoteOffer:if(!this.dialog.offer)throw new Error(`Session offer undefined in signaling state ${this.dialog.signalingState}.`);return this.setOfferAndGetAnswer(this.dialog.offer,e);case v.Stable:return this.state!==m.Established?Promise.resolve(void 0):this.getOffer(e);case v.Closed:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);default:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`)}}getOffer(e){const t=this.setupSessionDescriptionHandler(),s=e.sessionDescriptionHandlerOptions,i=e.sessionDescriptionHandlerModifiers;try{return t.getDescription(s,i).then(r=>Ee(r)).catch(r=>{this.logger.error("Session.getOffer: SDH getDescription rejected...");const n=r instanceof Error?r:new Error("Session.getOffer unknown error.");throw this.logger.error(n.message),n})}catch(r){this.logger.error("Session.getOffer: SDH getDescription threw...");const n=r instanceof Error?r:new Error(r);return this.logger.error(n.message),Promise.reject(n)}}rollbackOffer(){const e=this.setupSessionDescriptionHandler();if(e.rollbackDescription===void 0)return Promise.resolve();try{return e.rollbackDescription().catch(t=>{this.logger.error("Session.rollbackOffer: SDH rollbackDescription rejected...");const s=t instanceof Error?t:new Error("Session.rollbackOffer unknown error.");throw this.logger.error(s.message),s})}catch(t){this.logger.error("Session.rollbackOffer: SDH rollbackDescription threw...");const s=t instanceof Error?t:new Error(t);return this.logger.error(s.message),Promise.reject(s)}}setAnswer(e,t){const s=this.setupSessionDescriptionHandler(),i=t.sessionDescriptionHandlerOptions,r=t.sessionDescriptionHandlerModifiers;try{if(!s.hasDescription(e.contentType))return Promise.reject(new _e)}catch(n){this.logger.error("Session.setAnswer: SDH hasDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}try{return s.setDescription(e.content,i,r).catch(n=>{this.logger.error("Session.setAnswer: SDH setDescription rejected...");const o=n instanceof Error?n:new Error("Session.setAnswer unknown error.");throw this.logger.error(o.message),o})}catch(n){this.logger.error("Session.setAnswer: SDH setDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}}setOfferAndGetAnswer(e,t){const s=this.setupSessionDescriptionHandler(),i=t.sessionDescriptionHandlerOptions,r=t.sessionDescriptionHandlerModifiers;try{if(!s.hasDescription(e.contentType))return Promise.reject(new _e)}catch(n){this.logger.error("Session.setOfferAndGetAnswer: SDH hasDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}try{return s.setDescription(e.content,i,r).then(()=>s.getDescription(i,r)).then(n=>Ee(n)).catch(n=>{this.logger.error("Session.setOfferAndGetAnswer: SDH setDescription or getDescription rejected...");const o=n instanceof Error?n:new Error("Session.setOfferAndGetAnswer unknown error.");throw this.logger.error(o.message),o})}catch(n){this.logger.error("Session.setOfferAndGetAnswer: SDH setDescription or getDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}}setSessionDescriptionHandler(e){if(this._sessionDescriptionHandler)throw new Error("Session description handler defined.");this._sessionDescriptionHandler=e}setupSessionDescriptionHandler(){var e;return this._sessionDescriptionHandler?this._sessionDescriptionHandler:(this._sessionDescriptionHandler=this.sessionDescriptionHandlerFactory(this,this.userAgent.configuration.sessionDescriptionHandlerFactoryOptions),!((e=this.delegate)===null||e===void 0)&&e.onSessionDescriptionHandler&&this.delegate.onSessionDescriptionHandler(this._sessionDescriptionHandler,!1),this._sessionDescriptionHandler)}stateTransition(e){const t=()=>{throw new Error(`Invalid state transition from ${this._state} to ${e}`)};switch(this._state){case m.Initial:e!==m.Establishing&&e!==m.Established&&e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Establishing:e!==m.Established&&e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Established:e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Terminating:e!==m.Terminated&&t();break;case m.Terminated:t();break;default:throw new Error("Unrecognized state.")}this._state=e,this.logger.log(`Session ${this.id} transitioned to state ${this._state}`),this._stateEventEmitter.emit(this._state),e===m.Terminated&&this.dispose()}copyRequestOptions(e={}){const t=e.extraHeaders?e.extraHeaders.slice():void 0,s=e.body?{contentDisposition:e.body.contentDisposition||"render",contentType:e.body.contentType||"text/plain",content:e.body.content||""}:void 0;return{extraHeaders:t,body:s}}getReasonHeaderValue(e,t){const s=e;let i=Se(e);return!i&&t&&(i=t),"SIP;cause="+s+';text="'+i+'"'}referExtraHeaders(e){const t=[];return t.push("Referred-By: <"+this.userAgent.configuration.uri+">"),t.push("Contact: "+this._contact),t.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),t.push("Refer-To: "+e),t}referToString(e){let t;if(e instanceof K)t=e.toString();else{if(!e.dialog)throw new Error("Dialog undefined.");const s=e.remoteIdentity.friendlyName,i=e.dialog.remoteTarget.toString(),r=e.dialog.callId,n=e.dialog.remoteTag,o=e.dialog.localTag,d=encodeURIComponent(`${r};to-tag=${n};from-tag=${o}`);t=`"${s}" <${i}?Replaces=${d}>`}return t}}var G;(function(a){a.Required="Required",a.Supported="Supported",a.Unsupported="Unsupported"})(G=G||(G={}));const yt={"100rel":!0,199:!0,answermode:!0,"early-session":!0,eventlist:!0,explicitsub:!0,"from-change":!0,"geolocation-http":!0,"geolocation-sip":!0,gin:!0,gruu:!0,histinfo:!0,ice:!0,join:!0,"multiple-refer":!0,norefersub:!0,nosub:!0,outbound:!0,path:!0,policy:!0,precondition:!0,pref:!0,privacy:!0,"recipient-list-invite":!0,"recipient-list-message":!0,"recipient-list-subscribe":!0,replaces:!0,"resource-priority":!0,"sdp-anat":!0,"sec-agree":!0,tdialog:!0,timer:!0,uui:!0};class ce extends ue{constructor(e,t){super(e),this.incomingInviteRequest=t,this.disposed=!1,this.expiresTimer=void 0,this.isCanceled=!1,this.rel100="none",this.rseq=Math.floor(Math.random()*1e4),this.userNoAnswerTimer=void 0,this.waitingForPrack=!1,this.logger=e.getLogger("sip.Invitation");const s=this.incomingInviteRequest.message,i=s.getHeader("require");i&&i.toLowerCase().includes("100rel")&&(this.rel100="required");const r=s.getHeader("supported");if(r&&r.toLowerCase().includes("100rel")&&(this.rel100="supported"),s.toTag=t.toTag,typeof s.toTag!="string")throw new TypeError("toTag should have been a string.");if(this.userNoAnswerTimer=setTimeout(()=>{t.reject({statusCode:480}),this.stateTransition(m.Terminated)},this.userAgent.configuration.noAnswerTimeout?this.userAgent.configuration.noAnswerTimeout*1e3:6e4),s.hasHeader("expires")){const d=Number(s.getHeader("expires")||0)*1e3;this.expiresTimer=setTimeout(()=>{this.state===m.Initial&&(t.reject({statusCode:487}),this.stateTransition(m.Terminated))},d)}const n=this.request.getHeader("P-Asserted-Identity");n&&(this._assertedIdentity=D.nameAddrHeaderParse(n)),this._contact=this.userAgent.contact.toString();const o=s.parseHeader("Content-Disposition");o&&o.type==="render"&&(this._renderbody=s.body,this._rendertype=s.getHeader("Content-Type")),this._id=s.callId+s.fromTag,this.userAgent._sessions[this._id]=this}dispose(){if(this.disposed)return Promise.resolve();switch(this.disposed=!0,this.expiresTimer&&(clearTimeout(this.expiresTimer),this.expiresTimer=void 0),this.userNoAnswerTimer&&(clearTimeout(this.userNoAnswerTimer),this.userNoAnswerTimer=void 0),this.prackNeverArrived(),this.state){case m.Initial:return this.reject().then(()=>super.dispose());case m.Establishing:return this.reject().then(()=>super.dispose());case m.Established:return super.dispose();case m.Terminating:return super.dispose();case m.Terminated:return super.dispose();default:throw new Error("Unknown state.")}}get autoSendAnInitialProvisionalResponse(){return this.rel100!=="required"&&this.userAgent.configuration.sendInitialProvisionalResponse}get body(){return this.incomingInviteRequest.message.body}get localIdentity(){return this.request.to}get remoteIdentity(){return this.request.from}get request(){return this.incomingInviteRequest.message}accept(e={}){if(this.logger.log("Invitation.accept"),this.state!==m.Initial){const t=new Error(`Invalid session state ${this.state}`);return this.logger.error(t.message),Promise.reject(t)}return e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),this.stateTransition(m.Establishing),this.sendAccept(e).then(({message:t,session:s})=>{s.delegate={onAck:i=>this.onAckRequest(i),onAckTimeout:()=>this.onAckTimeout(),onBye:i=>this.onByeRequest(i),onInfo:i=>this.onInfoRequest(i),onInvite:i=>this.onInviteRequest(i),onMessage:i=>this.onMessageRequest(i),onNotify:i=>this.onNotifyRequest(i),onPrack:i=>this.onPrackRequest(i),onRefer:i=>this.onReferRequest(i)},this._dialog=s,this.stateTransition(m.Established),this._replacee&&this._replacee._bye()}).catch(t=>this.handleResponseError(t))}progress(e={}){if(this.logger.log("Invitation.progress"),this.state!==m.Initial){const s=new Error(`Invalid session state ${this.state}`);return this.logger.error(s.message),Promise.reject(s)}const t=e.statusCode||180;if(t<100||t>199)throw new TypeError("Invalid statusCode: "+t);return e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),this.waitingForPrack?(this.logger.warn("Unexpected call for progress while waiting for prack, ignoring"),Promise.resolve()):e.statusCode===100?this.sendProgressTrying().then(()=>{}).catch(s=>this.handleResponseError(s)):this.rel100!=="required"&&!(this.rel100==="supported"&&e.rel100)&&!(this.rel100==="supported"&&this.userAgent.configuration.sipExtension100rel===G.Required)?this.sendProgress(e).then(()=>{}).catch(s=>this.handleResponseError(s)):this.sendProgressReliableWaitForPrack(e).then(()=>{}).catch(s=>this.handleResponseError(s))}reject(e={}){if(this.logger.log("Invitation.reject"),this.state!==m.Initial&&this.state!==m.Establishing){const n=new Error(`Invalid session state ${this.state}`);return this.logger.error(n.message),Promise.reject(n)}const t=e.statusCode||480,s=e.reasonPhrase?e.reasonPhrase:Se(t),i=e.extraHeaders||[];if(t<300||t>699)throw new TypeError("Invalid statusCode: "+t);const r=e.body?Ee(e.body):void 0;return t<400?this.incomingInviteRequest.redirect([],{statusCode:t,reasonPhrase:s,extraHeaders:i,body:r}):this.incomingInviteRequest.reject({statusCode:t,reasonPhrase:s,extraHeaders:i,body:r}),this.stateTransition(m.Terminated),Promise.resolve()}_onCancel(e){if(this.logger.log("Invitation._onCancel"),this.state!==m.Initial&&this.state!==m.Establishing){this.logger.error(`CANCEL received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onCancel){const t=new gt(e);this.delegate.onCancel(t)}this.isCanceled=!0,this.incomingInviteRequest.reject({statusCode:487}),this.stateTransition(m.Terminated)}handlePrackOfferAnswer(e){if(!this.dialog)throw new Error("Dialog undefined.");const t=be(e.message);if(!t||t.contentDisposition!=="session")return Promise.resolve(void 0);const s={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers};switch(this.dialog.signalingState){case v.Initial:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);case v.Stable:return this.setAnswer(t,s).then(()=>{});case v.HaveLocalOffer:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);case v.HaveRemoteOffer:return this.setOfferAndGetAnswer(t,s);case v.Closed:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);default:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`)}}handleResponseError(e){let t=480;if(e instanceof Error?this.logger.error(e.message):this.logger.error(e),e instanceof _e?(this.logger.error("A session description handler occurred while sending response (content type unsupported"),t=415):e instanceof lt?this.logger.error("A session description handler occurred while sending response"):e instanceof De?this.logger.error("Session ended before response could be formulated and sent (while waiting for PRACK)"):e instanceof ee&&this.logger.error("Session changed state before response could be formulated and sent"),this.state===m.Initial||this.state===m.Establishing)try{this.incomingInviteRequest.reject({statusCode:t}),this.stateTransition(m.Terminated)}catch(s){throw this.logger.error("An error occurred attempting to reject the request while handling another error"),s}if(this.isCanceled){this.logger.warn("An error occurred while attempting to formulate and send a response to an incoming INVITE. However a CANCEL was received and processed while doing so which can (and often does) result in errors occurring as the session terminates in the meantime. Said error is being ignored.");return}throw e}onAckTimeout(){if(this.logger.log("Invitation.onAckTimeout"),!this.dialog)throw new Error("Dialog undefined.");this.logger.log("No ACK received for an extended period of time, terminating session"),this.dialog.bye(),this.stateTransition(m.Terminated)}sendAccept(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.extraHeaders||[];return this.waitingForPrack?this.waitForArrivalOfPrack().then(()=>clearTimeout(this.userNoAnswerTimer)).then(()=>this.generateResponseOfferAnswer(this.incomingInviteRequest,t)).then(i=>this.incomingInviteRequest.accept({statusCode:200,body:i,extraHeaders:s})):(clearTimeout(this.userNoAnswerTimer),this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(i=>this.incomingInviteRequest.accept({statusCode:200,body:i,extraHeaders:s})))}sendProgress(e={}){const t=e.statusCode||180,s=e.reasonPhrase,i=(e.extraHeaders||[]).slice(),r=e.body?Ee(e.body):void 0;if(t===183&&!r)return this.sendProgressWithSDP(e);try{const n=this.incomingInviteRequest.progress({statusCode:t,reasonPhrase:s,extraHeaders:i,body:r});return this._dialog=n.session,Promise.resolve(n)}catch(n){return Promise.reject(n)}}sendProgressWithSDP(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.statusCode||183,i=e.reasonPhrase,r=(e.extraHeaders||[]).slice();return this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(n=>this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n})).then(n=>(this._dialog=n.session,n))}sendProgressReliable(e={}){return e.extraHeaders=(e.extraHeaders||[]).slice(),e.extraHeaders.push("Require: 100rel"),e.extraHeaders.push("RSeq: "+Math.floor(Math.random()*1e4)),this.sendProgressWithSDP(e)}sendProgressReliableWaitForPrack(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.statusCode||183,i=e.reasonPhrase,r=(e.extraHeaders||[]).slice();r.push("Require: 100rel"),r.push("RSeq: "+this.rseq++);let n;return new Promise((o,d)=>{this.waitingForPrack=!0,this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(p=>(n=p,this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n}))).then(p=>{this._dialog=p.session;let g,w;p.session.delegate={onPrack:f=>{g=f,clearTimeout(I),clearTimeout(de),this.waitingForPrack&&(this.waitingForPrack=!1,this.handlePrackOfferAnswer(g).then($=>{try{w=g.accept({statusCode:200,body:$}),this.prackArrived(),o({prackRequest:g,prackResponse:w,progressResponse:p})}catch(Ne){d(Ne)}}).catch($=>d($)))}};const I=setTimeout(()=>{this.waitingForPrack&&(this.waitingForPrack=!1,this.logger.warn("No PRACK received, rejecting INVITE."),clearTimeout(de),this.reject({statusCode:504}).then(()=>d(new De)).catch(f=>d(f)))},H.T1*64),A=()=>{try{this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n})}catch(f){this.waitingForPrack=!1,d(f);return}de=setTimeout(A,C*=2)};let C=H.T1,de=setTimeout(A,C)}).catch(p=>{this.waitingForPrack=!1,d(p)})})}sendProgressTrying(){try{const e=this.incomingInviteRequest.trying();return Promise.resolve(e)}catch(e){return Promise.reject(e)}}waitForArrivalOfPrack(){if(this.waitingForPrackPromise)throw new Error("Already waiting for PRACK");return this.waitingForPrackPromise=new Promise((e,t)=>{this.waitingForPrackResolve=e,this.waitingForPrackReject=t}),this.waitingForPrackPromise}prackArrived(){this.waitingForPrackResolve&&this.waitingForPrackResolve(),this.waitingForPrackPromise=void 0,this.waitingForPrackResolve=void 0,this.waitingForPrackReject=void 0}prackNeverArrived(){this.waitingForPrackReject&&this.waitingForPrackReject(new De),this.waitingForPrackPromise=void 0,this.waitingForPrackResolve=void 0,this.waitingForPrackReject=void 0}}class Ce extends ue{constructor(e,t,s={}){super(e,s),this.disposed=!1,this.earlyMedia=!1,this.earlyMediaSessionDescriptionHandlers=new Map,this.isCanceled=!1,this.inviteWithoutSdp=!1,this.logger=e.getLogger("sip.Inviter"),this.earlyMedia=s.earlyMedia!==void 0?s.earlyMedia:this.earlyMedia,this.fromTag=Te(),this.inviteWithoutSdp=s.inviteWithoutSdp!==void 0?s.inviteWithoutSdp:this.inviteWithoutSdp;const i=Object.assign({},s);i.params=Object.assign({},s.params);const r=s.anonymous||!1,n=e.contact.toString({anonymous:r,outbound:r?!e.contact.tempGruu:!e.contact.pubGruu});r&&e.configuration.uri&&(i.params.fromDisplayName="Anonymous",i.params.fromUri="sip:anonymous@anonymous.invalid");let o=e.userAgentCore.configuration.aor;if(i.params.fromUri&&(o=typeof i.params.fromUri=="string"?D.URIParse(i.params.fromUri):i.params.fromUri),!o)throw new TypeError("Invalid from URI: "+i.params.fromUri);let d=t;if(i.params.toUri&&(d=typeof i.params.toUri=="string"?D.URIParse(i.params.toUri):i.params.toUri),!d)throw new TypeError("Invalid to URI: "+i.params.toUri);const p=Object.assign({},i.params);p.fromTag=this.fromTag;const g=(i.extraHeaders||[]).slice();r&&e.configuration.uri&&(g.push("P-Preferred-Identity: "+e.configuration.uri.toString()),g.push("Privacy: id")),g.push("Contact: "+n),g.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),e.configuration.sipExtension100rel===G.Required&&g.push("Require: 100rel"),e.configuration.sipExtensionReplaces===G.Required&&g.push("Require: replaces"),i.extraHeaders=g;const w=void 0;this.outgoingRequestMessage=e.userAgentCore.makeOutgoingRequestMessage(y.INVITE,t,o,d,p,g,w),this._contact=n,this._referralInviterOptions=i,this._renderbody=s.renderbody,this._rendertype=s.rendertype,s.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=s.sessionDescriptionHandlerModifiers),s.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=s.sessionDescriptionHandlerOptions),s.sessionDescriptionHandlerModifiersReInvite&&(this.sessionDescriptionHandlerModifiersReInvite=s.sessionDescriptionHandlerModifiersReInvite),s.sessionDescriptionHandlerOptionsReInvite&&(this.sessionDescriptionHandlerOptionsReInvite=s.sessionDescriptionHandlerOptionsReInvite),this._id=this.outgoingRequestMessage.callId+this.fromTag,this.userAgent._sessions[this._id]=this}dispose(){if(this.disposed)return Promise.resolve();switch(this.disposed=!0,this.disposeEarlyMedia(),this.state){case m.Initial:return this.cancel().then(()=>super.dispose());case m.Establishing:return this.cancel().then(()=>super.dispose());case m.Established:return super.dispose();case m.Terminating:return super.dispose();case m.Terminated:return super.dispose();default:throw new Error("Unknown state.")}}get body(){return this.outgoingRequestMessage.body}get localIdentity(){return this.outgoingRequestMessage.from}get remoteIdentity(){return this.outgoingRequestMessage.to}get request(){return this.outgoingRequestMessage}cancel(e={}){if(this.logger.log("Inviter.cancel"),this.state!==m.Initial&&this.state!==m.Establishing){const s=new Error(`Invalid session state ${this.state}`);return this.logger.error(s.message),Promise.reject(s)}this.isCanceled=!0,this.stateTransition(m.Terminating);function t(s,i){if(s&&s<200||s>699)throw new TypeError("Invalid statusCode: "+s);if(s){const r=s,n=Se(s)||i;return"SIP;cause="+r+';text="'+n+'"'}}if(this.outgoingInviteRequest){let s;e.statusCode&&e.reasonPhrase&&(s=t(e.statusCode,e.reasonPhrase)),this.outgoingInviteRequest.cancel(s,e)}else this.logger.warn("Canceled session before INVITE was sent"),this.stateTransition(m.Terminated);return Promise.resolve()}invite(e={}){if(this.logger.log("Inviter.invite"),this.state!==m.Initial)return super.invite(e);if(e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),e.withoutSdp||this.inviteWithoutSdp)return this._renderbody&&this._rendertype&&(this.outgoingRequestMessage.body={contentType:this._rendertype,body:this._renderbody}),this.stateTransition(m.Establishing),Promise.resolve(this.sendInvite(e));const t={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.getOffer(t).then(s=>(this.outgoingRequestMessage.body={body:s.content,contentType:s.contentType},this.stateTransition(m.Establishing),this.sendInvite(e))).catch(s=>{throw this.logger.log(s.message),this.state!==m.Terminated&&this.stateTransition(m.Terminated),s})}sendInvite(e={}){return this.outgoingInviteRequest=this.userAgent.userAgentCore.invite(this.outgoingRequestMessage,{onAccept:t=>{if(this.dialog){this.logger.log("Additional confirmed dialog, sending ACK and BYE"),this.ackAndBye(t);return}if(this.isCanceled){this.logger.log("Canceled session accepted, sending ACK and BYE"),this.ackAndBye(t),this.stateTransition(m.Terminated);return}this.notifyReferer(t),this.onAccept(t).then(()=>{this.disposeEarlyMedia()}).catch(()=>{this.disposeEarlyMedia()}).then(()=>{e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(t)})},onProgress:t=>{this.isCanceled||(this.notifyReferer(t),this.onProgress(t).catch(()=>{this.disposeEarlyMedia()}).then(()=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(t)}))},onRedirect:t=>{this.notifyReferer(t),this.onRedirect(t),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(t)},onReject:t=>{this.notifyReferer(t),this.onReject(t),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(t)},onTrying:t=>{this.notifyReferer(t),this.onTrying(t),e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(t)}}),this.outgoingInviteRequest}disposeEarlyMedia(){this.earlyMediaSessionDescriptionHandlers.forEach(e=>{e.close()}),this.earlyMediaSessionDescriptionHandlers.clear()}notifyReferer(e){if(!this._referred)return;if(!(this._referred instanceof ue))throw new Error("Referred session not instance of session");if(!this._referred.dialog)return;if(!e.message.statusCode)throw new Error("Status code undefined.");if(!e.message.reasonPhrase)throw new Error("Reason phrase undefined.");const t=e.message.statusCode,s=e.message.reasonPhrase,i=`SIP/2.0 ${t} ${s}`.trim(),r=this._referred.dialog.notify(void 0,{extraHeaders:["Event: refer","Subscription-State: terminated"],body:{contentDisposition:"render",contentType:"message/sipfrag",content:i}});r.delegate={onReject:()=>{this._referred=void 0}}}onAccept(e){if(this.logger.log("Inviter.onAccept"),this.state!==m.Establishing)return this.logger.error(`Accept received while in state ${this.state}, dropping response`),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.message,s=e.session;switch(t.hasHeader("P-Asserted-Identity")&&(this._assertedIdentity=D.nameAddrHeaderParse(t.getHeader("P-Asserted-Identity"))),s.delegate={onAck:i=>this.onAckRequest(i),onBye:i=>this.onByeRequest(i),onInfo:i=>this.onInfoRequest(i),onInvite:i=>this.onInviteRequest(i),onMessage:i=>this.onMessageRequest(i),onNotify:i=>this.onNotifyRequest(i),onPrack:i=>this.onPrackRequest(i),onRefer:i=>this.onReferRequest(i)},this._dialog=s,s.signalingState){case v.Initial:return this.logger.error("Received 2xx response to INVITE without a session description"),this.ackAndBye(e,400,"Missing session description"),this.stateTransition(m.Terminated),Promise.reject(new Error("Bad Media Description"));case v.HaveLocalOffer:return this.logger.error("Received 2xx response to INVITE without a session description"),this.ackAndBye(e,400,"Missing session description"),this.stateTransition(m.Terminated),Promise.reject(new Error("Bad Media Description"));case v.HaveRemoteOffer:{if(!this._dialog.offer)throw new Error(`Session offer undefined in signaling state ${this._dialog.signalingState}.`);const i={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setOfferAndGetAnswer(this._dialog.offer,i).then(r=>{e.ack({body:r}),this.stateTransition(m.Established)}).catch(r=>{throw this.ackAndBye(e,488,"Invalid session description"),this.stateTransition(m.Terminated),r})}case v.Stable:{if(this.earlyMediaSessionDescriptionHandlers.size>0){const n=this.earlyMediaSessionDescriptionHandlers.get(s.id);if(!n)throw new Error("Session description handler undefined.");return this.setSessionDescriptionHandler(n),this.earlyMediaSessionDescriptionHandlers.delete(s.id),e.ack(),this.stateTransition(m.Established),Promise.resolve()}if(this.earlyMediaDialog){if(this.earlyMediaDialog!==s){this.earlyMedia&&this.logger.error("You have set the 'earlyMedia' option to 'true' which requires that your INVITE requests do not fork and yet this INVITE request did in fact fork. Consequentially and not surprisingly the end point which accepted the INVITE (confirmed dialog) does not match the end point with which early media has been setup (early dialog) and thus this session is unable to proceed. In accordance with the SIP specifications, the SIP servers your end point is connected to determine if an INVITE forks and the forking behavior of those servers cannot be controlled by this library. If you wish to use early media with this library you must configure those servers accordingly. Alternatively you may set the 'earlyMedia' to 'false' which will allow this library to function with any INVITE requests which do fork.");const n=new Error("Early media dialog does not equal confirmed dialog, terminating session");return this.logger.error(n.message),this.ackAndBye(e,488,"Not Acceptable Here"),this.stateTransition(m.Terminated),Promise.reject(n)}return e.ack(),this.stateTransition(m.Established),Promise.resolve()}const i=s.answer;if(!i)throw new Error("Answer is undefined.");const r={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setAnswer(i,r).then(()=>{let n;this._renderbody&&this._rendertype&&(n={body:{contentDisposition:"render",contentType:this._rendertype,content:this._renderbody}}),e.ack(n),this.stateTransition(m.Established)}).catch(n=>{throw this.logger.error(n.message),this.ackAndBye(e,488,"Not Acceptable Here"),this.stateTransition(m.Terminated),n})}case v.Closed:return Promise.reject(new Error("Terminated."));default:throw new Error("Unknown session signaling state.")}}onProgress(e){var t;if(this.logger.log("Inviter.onProgress"),this.state!==m.Establishing)return this.logger.error(`Progress received while in state ${this.state}, dropping response`),Promise.reject(new Error(`Invalid session state ${this.state}`));if(!this.outgoingInviteRequest)throw new Error("Outgoing INVITE request undefined.");const s=e.message,i=e.session;s.hasHeader("P-Asserted-Identity")&&(this._assertedIdentity=D.nameAddrHeaderParse(s.getHeader("P-Asserted-Identity")));const r=s.getHeader("require"),n=s.getHeader("rseq"),d=!!(r&&r.includes("100rel")&&n?Number(n):void 0),p=[];switch(d&&p.push("RAck: "+s.getHeader("rseq")+" "+s.getHeader("cseq")),i.signalingState){case v.Initial:return d&&(this.logger.warn("First reliable provisional response received MUST contain an offer when INVITE does not contain an offer."),e.prack({extraHeaders:p})),Promise.resolve();case v.HaveLocalOffer:return d&&e.prack({extraHeaders:p}),Promise.resolve();case v.HaveRemoteOffer:if(!d)return this.logger.warn("Non-reliable provisional response MUST NOT contain an initial offer, discarding response."),Promise.resolve();{const g=this.sessionDescriptionHandlerFactory(this,this.userAgent.configuration.sessionDescriptionHandlerFactoryOptions||{});return!((t=this.delegate)===null||t===void 0)&&t.onSessionDescriptionHandler&&this.delegate.onSessionDescriptionHandler(g,!0),this.earlyMediaSessionDescriptionHandlers.set(i.id,g),g.setDescription(s.body,this.sessionDescriptionHandlerOptions,this.sessionDescriptionHandlerModifiers).then(()=>g.getDescription(this.sessionDescriptionHandlerOptions,this.sessionDescriptionHandlerModifiers)).then(w=>{const S={contentDisposition:"session",contentType:w.contentType,content:w.body};e.prack({extraHeaders:p,body:S})}).catch(w=>{throw this.stateTransition(m.Terminated),w})}case v.Stable:if(d&&e.prack({extraHeaders:p}),this.earlyMedia&&!this.earlyMediaDialog){this.earlyMediaDialog=i;const g=i.answer;if(!g)throw new Error("Answer is undefined.");const w={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setAnswer(g,w).catch(S=>{throw this.stateTransition(m.Terminated),S})}return Promise.resolve();case v.Closed:return Promise.reject(new Error("Terminated."));default:throw new Error("Unknown session signaling state.")}}onRedirect(e){if(this.logger.log("Inviter.onRedirect"),this.state!==m.Establishing&&this.state!==m.Terminating){this.logger.error(`Redirect received while in state ${this.state}, dropping response`);return}this.stateTransition(m.Terminated)}onReject(e){if(this.logger.log("Inviter.onReject"),this.state!==m.Establishing&&this.state!==m.Terminating){this.logger.error(`Reject received while in state ${this.state}, dropping response`);return}this.stateTransition(m.Terminated)}onTrying(e){if(this.logger.log("Inviter.onTrying"),this.state!==m.Establishing){this.logger.error(`Trying received while in state ${this.state}, dropping response`);return}}}class St{constructor(e,t,s,i="text/plain",r={}){this.logger=e.getLogger("sip.Messager"),r.params=r.params||{};let n=e.userAgentCore.configuration.aor;if(r.params.fromUri&&(n=typeof r.params.fromUri=="string"?D.URIParse(r.params.fromUri):r.params.fromUri),!n)throw new TypeError("Invalid from URI: "+r.params.fromUri);let o=t;if(r.params.toUri&&(o=typeof r.params.toUri=="string"?D.URIParse(r.params.toUri):r.params.toUri),!o)throw new TypeError("Invalid to URI: "+r.params.toUri);const d=r.params?Object.assign({},r.params):{},p=(r.extraHeaders||[]).slice(),w={contentDisposition:"render",contentType:i,content:s};this.request=e.userAgentCore.makeOutgoingRequestMessage(y.MESSAGE,t,n,o,d,p,w),this.userAgent=e}message(e={}){return this.userAgent.userAgentCore.request(this.request,e.requestDelegate),Promise.resolve()}}var x;(function(a){a.Initial="Initial",a.Registered="Registered",a.Unregistered="Unregistered",a.Terminated="Terminated"})(x=x||(x={}));class Y{constructor(e,t={}){this.disposed=!1,this._contacts=[],this._retryAfter=void 0,this._state=x.Initial,this._waiting=!1,this._stateEventEmitter=new me,this._waitingEventEmitter=new me,this.userAgent=e;const s=e.configuration.uri.clone();if(s.user=void 0,this.options=Object.assign(Object.assign(Object.assign({},Y.defaultOptions()),{registrar:s}),Y.stripUndefinedProperties(t)),this.options.extraContactHeaderParams=(this.options.extraContactHeaderParams||[]).slice(),this.options.extraHeaders=(this.options.extraHeaders||[]).slice(),!this.options.registrar)throw new Error("Registrar undefined.");if(this.options.registrar=this.options.registrar.clone(),this.options.regId&&!this.options.instanceId?this.options.instanceId=this.userAgent.instanceId:!this.options.regId&&this.options.instanceId&&(this.options.regId=1),this.options.instanceId&&D.parse(this.options.instanceId,"uuid")===-1)throw new Error("Invalid instanceId.");if(this.options.regId&&this.options.regId<0)throw new Error("Invalid regId.");const i=this.options.registrar,r=this.options.params&&this.options.params.fromUri||e.userAgentCore.configuration.aor,n=this.options.params&&this.options.params.toUri||e.configuration.uri,o=this.options.params||{},d=(t.extraHeaders||[]).slice();if(this.request=e.userAgentCore.makeOutgoingRequestMessage(y.REGISTER,i,r,n,o,d,void 0),this.expires=this.options.expires||Y.defaultExpires,this.expires<0)throw new Error("Invalid expires.");if(this.refreshFrequency=this.options.refreshFrequency||Y.defaultRefreshFrequency,this.refreshFrequency<50||this.refreshFrequency>99)throw new Error("Invalid refresh frequency. The value represents a percentage of the expiration time and should be between 50 and 99.");this.logger=e.getLogger("sip.Registerer"),this.options.logConfiguration&&(this.logger.log("Configuration:"),Object.keys(this.options).forEach(p=>{const g=this.options[p];p==="registrar"?this.logger.log("· "+p+": "+g):this.logger.log("· "+p+": "+JSON.stringify(g))})),this.id=this.request.callId+this.request.from.parameters.tag,this.userAgent._registerers[this.id]=this}static defaultOptions(){return{expires:Y.defaultExpires,extraContactHeaderParams:[],extraHeaders:[],logConfiguration:!0,instanceId:"",params:{},regId:0,registrar:new K("sip","anonymous","anonymous.invalid"),refreshFrequency:Y.defaultRefreshFrequency}}static stripUndefinedProperties(e){return Object.keys(e).reduce((t,s)=>(e[s]!==void 0&&(t[s]=e[s]),t),{})}get contacts(){return this._contacts.slice()}get retryAfter(){return this._retryAfter}get state(){return this._state}get stateChange(){return this._stateEventEmitter}dispose(){return this.disposed?Promise.resolve():(this.disposed=!0,this.logger.log(`Registerer ${this.id} in state ${this.state} is being disposed`),delete this.userAgent._registerers[this.id],new Promise(e=>{const t=()=>{if(!this.waiting&&this._state===x.Registered){this.stateChange.addListener(()=>{this.terminated(),e()},{once:!0}),this.unregister();return}this.terminated(),e()};this.waiting?this.waitingChange.addListener(()=>{t()},{once:!0}):t()}))}register(e={}){if(this.state===x.Terminated)throw this.stateError(),new Error("Registerer terminated. Unable to register.");if(this.disposed)throw this.stateError(),new Error("Registerer disposed. Unable to register.");if(this.waiting){this.waitingWarning();const i=new fe("REGISTER request already in progress, waiting for final response");return Promise.reject(i)}e.requestOptions&&(this.options=Object.assign(Object.assign({},this.options),e.requestOptions));const t=(this.options.extraHeaders||[]).slice();t.push("Contact: "+this.generateContactHeader(this.expires)),t.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),this.request.cseq++,this.request.setHeader("cseq",this.request.cseq+" REGISTER"),this.request.extraHeaders=t,this.waitingToggle(!0);const s=this.userAgent.userAgentCore.register(this.request,{onAccept:i=>{let r;i.message.hasHeader("expires")&&(r=Number(i.message.getHeader("expires"))),this._contacts=i.message.getHeaders("contact");let n=this._contacts.length;if(!n){this.logger.error("No Contact header in response to REGISTER, dropping response."),this.unregistered();return}let o;for(;n--;){if(o=i.message.parseHeader("contact",n),!o)throw new Error("Contact undefined");if(this.userAgent.contact.pubGruu&&Le(o.uri,this.userAgent.contact.pubGruu)){r=Number(o.getParam("expires"));break}if(this.userAgent.configuration.contactName===""){if(o.uri.user===this.userAgent.contact.uri.user){r=Number(o.getParam("expires"));break}}else if(Le(o.uri,this.userAgent.contact.uri)){r=Number(o.getParam("expires"));break}o=void 0}if(o===void 0){this.logger.error("No Contact header pointing to us, dropping response"),this.unregistered(),this.waitingToggle(!1);return}if(r===void 0){this.logger.error("Contact pointing to us is missing expires parameter, dropping response"),this.unregistered(),this.waitingToggle(!1);return}if(o.hasParam("temp-gruu")){const d=o.getParam("temp-gruu");d&&(this.userAgent.contact.tempGruu=D.URIParse(d.replace(/"/g,"")))}if(o.hasParam("pub-gruu")){const d=o.getParam("pub-gruu");d&&(this.userAgent.contact.pubGruu=D.URIParse(d.replace(/"/g,"")))}this.registered(r),e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(i),this.waitingToggle(!1)},onProgress:i=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(i)},onRedirect:i=>{this.logger.error("Redirect received. Not supported."),this.unregistered(),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(i),this.waitingToggle(!1)},onReject:i=>{if(i.message.statusCode===423){if(!i.message.hasHeader("min-expires")){this.logger.error("423 response received for REGISTER without Min-Expires, dropping response"),this.unregistered(),this.waitingToggle(!1);return}this.expires=Number(i.message.getHeader("min-expires")),this.waitingToggle(!1),this.register();return}this.logger.warn(`Failed to register, status code ${i.message.statusCode}`);let r=NaN;if(i.message.statusCode===500||i.message.statusCode===503){const n=i.message.getHeader("retry-after");n&&(r=Number.parseInt(n,void 0))}this._retryAfter=isNaN(r)?void 0:r,this.unregistered(),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(i),this._retryAfter=void 0,this.waitingToggle(!1)},onTrying:i=>{e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(i)}});return Promise.resolve(s)}unregister(e={}){if(this.state===x.Terminated)throw this.stateError(),new Error("Registerer terminated. Unable to register.");if(this.disposed&&this.state!==x.Registered)throw this.stateError(),new Error("Registerer disposed. Unable to register.");if(this.waiting){this.waitingWarning();const i=new fe("REGISTER request already in progress, waiting for final response");return Promise.reject(i)}this._state!==x.Registered&&!e.all&&this.logger.warn("Not currently registered, but sending an unregister anyway.");const t=(e.requestOptions&&e.requestOptions.extraHeaders||[]).slice();this.request.extraHeaders=t,e.all?(t.push("Contact: *"),t.push("Expires: 0")):t.push("Contact: "+this.generateContactHeader(0)),this.request.cseq++,this.request.setHeader("cseq",this.request.cseq+" REGISTER"),this.registrationTimer!==void 0&&(clearTimeout(this.registrationTimer),this.registrationTimer=void 0),this.waitingToggle(!0);const s=this.userAgent.userAgentCore.register(this.request,{onAccept:i=>{this._contacts=i.message.getHeaders("contact"),this.unregistered(),e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(i),this.waitingToggle(!1)},onProgress:i=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(i)},onRedirect:i=>{this.logger.error("Unregister redirected. Not currently supported."),this.unregistered(),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(i),this.waitingToggle(!1)},onReject:i=>{this.logger.error(`Unregister rejected with status code ${i.message.statusCode}`),this.unregistered(),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(i),this.waitingToggle(!1)},onTrying:i=>{e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(i)}});return Promise.resolve(s)}clearTimers(){this.registrationTimer!==void 0&&(clearTimeout(this.registrationTimer),this.registrationTimer=void 0),this.registrationExpiredTimer!==void 0&&(clearTimeout(this.registrationExpiredTimer),this.registrationExpiredTimer=void 0)}generateContactHeader(e){let t=this.userAgent.contact.toString({register:!0});return this.options.regId&&this.options.instanceId&&(t+=";reg-id="+this.options.regId,t+=';+sip.instance="<urn:uuid:'+this.options.instanceId+'>"'),this.options.extraContactHeaderParams&&this.options.extraContactHeaderParams.forEach(s=>{t+=";"+s}),t+=";expires="+e,t}registered(e){this.clearTimers(),this.registrationTimer=setTimeout(()=>{this.registrationTimer=void 0,this.register()},this.refreshFrequency/100*e*1e3),this.registrationExpiredTimer=setTimeout(()=>{this.logger.warn("Registration expired"),this.unregistered()},e*1e3),this._state!==x.Registered&&this.stateTransition(x.Registered)}unregistered(){this.clearTimers(),this._state!==x.Unregistered&&this.stateTransition(x.Unregistered)}terminated(){this.clearTimers(),this._state!==x.Terminated&&this.stateTransition(x.Terminated)}stateTransition(e){const t=()=>{throw new Error(`Invalid state transition from ${this._state} to ${e}`)};switch(this._state){case x.Initial:e!==x.Registered&&e!==x.Unregistered&&e!==x.Terminated&&t();break;case x.Registered:e!==x.Unregistered&&e!==x.Terminated&&t();break;case x.Unregistered:e!==x.Registered&&e!==x.Terminated&&t();break;case x.Terminated:t();break;default:throw new Error("Unrecognized state.")}this._state=e,this.logger.log(`Registration transitioned to state ${this._state}`),this._stateEventEmitter.emit(this._state),e===x.Terminated&&this.dispose()}get waiting(){return this._waiting}get waitingChange(){return this._waitingEventEmitter}waitingToggle(e){if(this._waiting===e)throw new Error(`Invalid waiting transition from ${this._waiting} to ${e}`);this._waiting=e,this.logger.log(`Waiting toggled to ${this._waiting}`),this._waitingEventEmitter.emit(this._waiting)}waitingWarning(){let e="An attempt was made to send a REGISTER request while a prior one was still in progress.";e+=" RFC 3261 requires UAs MUST NOT send a new registration until they have received a final response",e+=" from the registrar for the previous one or the previous REGISTER request has timed out.",e+=" Note that if the transport disconnects, you still must wait for the prior request to time out before",e+=" sending a new REGISTER request or alternatively dispose of the current Registerer and create a new Registerer.",this.logger.warn(e)}stateError(){let t=`An attempt was made to send a REGISTER request when the Registerer ${this.state===x.Terminated?"is in 'Terminated' state":"has been disposed"}.`;t+=" The Registerer transitions to 'Terminated' when Registerer.dispose() is called.",t+=" Perhaps you called UserAgent.stop() which dipsoses of all Registerers?",this.logger.error(t)}}Y.defaultExpires=600,Y.defaultRefreshFrequency=99;var R;(function(a){a.Initial="Initial",a.NotifyWait="NotifyWait",a.Pending="Pending",a.Active="Active",a.Terminated="Terminated"})(R=R||(R={}));var T;(function(a){a.Connecting="Connecting",a.Connected="Connected",a.Disconnecting="Disconnecting",a.Disconnected="Disconnected"})(T=T||(T={}));var k;(function(a){a.Started="Started",a.Stopped="Stopped"})(k=k||(k={}));class P{constructor(){this._dataLength=0,this._bufferLength=0,this._state=new Int32Array(4),this._buffer=new ArrayBuffer(68),this._buffer8=new Uint8Array(this._buffer,0,68),this._buffer32=new Uint32Array(this._buffer,0,17),this.start()}static hashStr(e,t=!1){return this.onePassHasher.start().appendStr(e).end(t)}static hashAsciiStr(e,t=!1){return this.onePassHasher.start().appendAsciiStr(e).end(t)}static _hex(e){const t=P.hexChars,s=P.hexOut;let i,r,n,o;for(o=0;o<4;o+=1)for(r=o*8,i=e[o],n=0;n<8;n+=2)s[r+1+n]=t.charAt(i&15),i>>>=4,s[r+0+n]=t.charAt(i&15),i>>>=4;return s.join("")}static _md5cycle(e,t){let s=e[0],i=e[1],r=e[2],n=e[3];s+=(i&r|~i&n)+t[0]-680876936|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[1]-389564586|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[2]+606105819|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[3]-1044525330|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[4]-176418897|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[5]+1200080426|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[6]-1473231341|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[7]-45705983|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[8]+1770035416|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[9]-1958414417|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[10]-42063|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[11]-1990404162|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[12]+1804603682|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[13]-40341101|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[14]-1502002290|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[15]+1236535329|0,i=(i<<22|i>>>10)+r|0,s+=(i&n|r&~n)+t[1]-165796510|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[6]-1069501632|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[11]+643717713|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[0]-373897302|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[5]-701558691|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[10]+38016083|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[15]-660478335|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[4]-405537848|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[9]+568446438|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[14]-1019803690|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[3]-187363961|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[8]+1163531501|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[13]-1444681467|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[2]-51403784|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[7]+1735328473|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[12]-1926607734|0,i=(i<<20|i>>>12)+r|0,s+=(i^r^n)+t[5]-378558|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[8]-2022574463|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[11]+1839030562|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[14]-35309556|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[1]-1530992060|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[4]+1272893353|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[7]-155497632|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[10]-1094730640|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[13]+681279174|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[0]-358537222|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[3]-722521979|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[6]+76029189|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[9]-640364487|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[12]-421815835|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[15]+530742520|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[2]-995338651|0,i=(i<<23|i>>>9)+r|0,s+=(r^(i|~n))+t[0]-198630844|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[7]+1126891415|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[14]-1416354905|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[5]-57434055|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[12]+1700485571|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[3]-1894986606|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[10]-1051523|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[1]-2054922799|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[8]+1873313359|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[15]-30611744|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[6]-1560198380|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[13]+1309151649|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[4]-145523070|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[11]-1120210379|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[2]+718787259|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[9]-343485551|0,i=(i<<21|i>>>11)+r|0,e[0]=s+e[0]|0,e[1]=i+e[1]|0,e[2]=r+e[2]|0,e[3]=n+e[3]|0}start(){return this._dataLength=0,this._bufferLength=0,this._state.set(P.stateIdentity),this}appendStr(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n;for(n=0;n<e.length;n+=1){if(r=e.charCodeAt(n),r<128)t[i++]=r;else if(r<2048)t[i++]=(r>>>6)+192,t[i++]=r&63|128;else if(r<55296||r>56319)t[i++]=(r>>>12)+224,t[i++]=r>>>6&63|128,t[i++]=r&63|128;else{if(r=(r-55296)*1024+(e.charCodeAt(++n)-56320)+65536,r>1114111)throw new Error("Unicode standard supports code points up to U+10FFFF");t[i++]=(r>>>18)+240,t[i++]=r>>>12&63|128,t[i++]=r>>>6&63|128,t[i++]=r&63|128}i>=64&&(this._dataLength+=64,P._md5cycle(this._state,s),i-=64,s[0]=s[16])}return this._bufferLength=i,this}appendAsciiStr(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n=0;for(;;){for(r=Math.min(e.length-n,64-i);r--;)t[i++]=e.charCodeAt(n++);if(i<64)break;this._dataLength+=64,P._md5cycle(this._state,s),i=0}return this._bufferLength=i,this}appendByteArray(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n=0;for(;;){for(r=Math.min(e.length-n,64-i);r--;)t[i++]=e[n++];if(i<64)break;this._dataLength+=64,P._md5cycle(this._state,s),i=0}return this._bufferLength=i,this}getState(){const e=this,t=e._state;return{buffer:String.fromCharCode.apply(null,e._buffer8),buflen:e._bufferLength,length:e._dataLength,state:[t[0],t[1],t[2],t[3]]}}setState(e){const t=e.buffer,s=e.state,i=this._state;let r;for(this._dataLength=e.length,this._bufferLength=e.buflen,i[0]=s[0],i[1]=s[1],i[2]=s[2],i[3]=s[3],r=0;r<t.length;r+=1)this._buffer8[r]=t.charCodeAt(r)}end(e=!1){const t=this._bufferLength,s=this._buffer8,i=this._buffer32,r=(t>>2)+1;let n;if(this._dataLength+=t,s[t]=128,s[t+1]=s[t+2]=s[t+3]=0,i.set(P.buffer32Identity.subarray(r),r),t>55&&(P._md5cycle(this._state,i),i.set(P.buffer32Identity)),n=this._dataLength*8,n<=4294967295)i[14]=n;else{const o=n.toString(16).match(/(.*?)(.{0,8})$/);if(o===null)return;const d=parseInt(o[2],16),p=parseInt(o[1],16)||0;i[14]=d,i[15]=p}return P._md5cycle(this._state,i),e?this._state:P._hex(this._state)}}P.stateIdentity=new Int32Array([1732584193,-271733879,-1732584194,271733878]),P.buffer32Identity=new Int32Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),P.hexChars="0123456789abcdef",P.hexOut=[],P.onePassHasher=new P,P.hashStr("hello")!=="5d41402abc4b2a76b9719d911017c592"&&console.error("Md5 self test failed.");function se(a){return P.hashStr(a)}class Tt{constructor(e,t,s,i){this.logger=e.getLogger("sipjs.digestauthentication"),this.username=s,this.password=i,this.ha1=t,this.nc=0,this.ncHex="00000000"}authenticate(e,t,s){if(this.algorithm=t.algorithm,this.realm=t.realm,this.nonce=t.nonce,this.opaque=t.opaque,this.stale=t.stale,this.algorithm){if(this.algorithm!=="MD5")return this.logger.warn("challenge with Digest algorithm different than 'MD5', authentication aborted"),!1}else this.algorithm="MD5";if(!this.realm)return this.logger.warn("challenge without Digest realm, authentication aborted"),!1;if(!this.nonce)return this.logger.warn("challenge without Digest nonce, authentication aborted"),!1;if(t.qop)if(t.qop.indexOf("auth")>-1)this.qop="auth";else if(t.qop.indexOf("auth-int")>-1)this.qop="auth-int";else return this.logger.warn("challenge without Digest qop different than 'auth' or 'auth-int', authentication aborted"),!1;else this.qop=void 0;return this.method=e.method,this.uri=e.ruri,this.cnonce=oe(12),this.nc+=1,this.updateNcHex(),this.nc===4294967296&&(this.nc=1,this.ncHex="00000001"),this.calculateResponse(s),!0}toString(){const e=[];if(!this.response)throw new Error("response field does not exist, cannot generate Authorization header");return e.push("algorithm="+this.algorithm),e.push('username="'+this.username+'"'),e.push('realm="'+this.realm+'"'),e.push('nonce="'+this.nonce+'"'),e.push('uri="'+this.uri+'"'),e.push('response="'+this.response+'"'),this.opaque&&e.push('opaque="'+this.opaque+'"'),this.qop&&(e.push("qop="+this.qop),e.push('cnonce="'+this.cnonce+'"'),e.push("nc="+this.ncHex)),"Digest "+e.join(", ")}updateNcHex(){const e=Number(this.nc).toString(16);this.ncHex="00000000".substr(0,8-e.length)+e}calculateResponse(e){let t,s;t=this.ha1,(t===""||t===void 0)&&(t=se(this.username+":"+this.realm+":"+this.password)),this.qop==="auth"?(s=se(this.method+":"+this.uri),this.response=se(t+":"+this.nonce+":"+this.ncHex+":"+this.cnonce+":auth:"+s)):this.qop==="auth-int"?(s=se(this.method+":"+this.uri+":"+se(e||"")),this.response=se(t+":"+this.nonce+":"+this.ncHex+":"+this.cnonce+":auth-int:"+s)):this.qop===void 0&&(s=se(this.method+":"+this.uri),this.response=se(t+":"+this.nonce+":"+s))}}var M;(function(a){a[a.error=0]="error",a[a.warn=1]="warn",a[a.log=2]="log",a[a.debug=3]="debug"})(M=M||(M={}));class Ye{constructor(e,t,s){this.logger=e,this.category=t,this.label=s}error(e){this.genericLog(M.error,e)}warn(e){this.genericLog(M.warn,e)}log(e){this.genericLog(M.log,e)}debug(e){this.genericLog(M.debug,e)}genericLog(e,t){this.logger.genericLog(e,this.category,this.label,t)}get level(){return this.logger.level}set level(e){this.logger.level=e}}class Et{constructor(){this.builtinEnabled=!0,this._level=M.log,this.loggers={},this.logger=this.getLogger("sip:loggerfactory")}get level(){return this._level}set level(e){e>=0&&e<=3?this._level=e:e>3?this._level=3:M.hasOwnProperty(e)?this._level=e:this.logger.error("invalid 'level' parameter value: "+JSON.stringify(e))}get connector(){return this._connector}set connector(e){e?typeof e=="function"?this._connector=e:this.logger.error("invalid 'connector' parameter value: "+JSON.stringify(e)):this._connector=void 0}getLogger(e,t){if(t&&this.level===3)return new Ye(this,e,t);if(this.loggers[e])return this.loggers[e];{const s=new Ye(this,e);return this.loggers[e]=s,s}}genericLog(e,t,s,i){this.level>=e&&this.builtinEnabled&&this.print(e,t,s,i),this.connector&&this.connector(M[e],t,s,i)}print(e,t,s,i){if(typeof i=="string"){const r=[new Date,t];s&&r.push(s),i=r.concat(i).join(" | ")}switch(e){case M.error:console.error(i);break;case M.warn:console.warn(i);break;case M.log:console.log(i);break;case M.debug:console.debug(i);break}}}var xe;(function(a){function e(i,r){let n=r,o=0,d=0;if(i.substring(n,n+2).match(/(^\r\n)/))return-2;for(;o===0;){if(d=i.indexOf(`\r
22
+ `,e}}function Ge(a){return a==="application/sdp"?"session":"render"}function Ee(a){const e=typeof a=="string"?a:a.body,t=typeof a=="string"?"application/sdp":a.contentType;return{contentDisposition:Ge(t),contentType:t,content:e}}function Ve(a){return a&&typeof a.content=="string"&&typeof a.contentType=="string"&&a.contentDisposition===void 0?!0:typeof a.contentDisposition=="string"}function be(a){let e,t,s;if(a instanceof he&&a.body){const i=a.parseHeader("Content-Disposition");e=i?i.type:void 0,t=a.parseHeader("Content-Type"),s=a.body}if(a instanceof Q&&a.body){const i=a.parseHeader("Content-Disposition");e=i?i.type:void 0,t=a.parseHeader("Content-Type"),s=a.body}if(a instanceof ae&&a.body)if(e=a.getHeader("Content-Disposition"),t=a.getHeader("Content-Type"),typeof a.body=="string"){if(!t)throw new Error("Header content type header does not equal body content type.");s=a.body}else{if(t&&t!==a.body.contentType)throw new Error("Header content type header does not equal body content type.");t=a.body.contentType,s=a.body.body}if(Ve(a)&&(e=a.contentDisposition,t=a.contentType,s=a.content),!!s){if(t&&!e&&(e=Ge(t)),!e)throw new Error("Content disposition undefined.");if(!t)throw new Error("Content type undefined.");return{contentDisposition:e,contentType:t,content:s}}}var B;(function(a){a.Initial="Initial",a.Early="Early",a.AckWait="AckWait",a.Confirmed="Confirmed",a.Terminated="Terminated"})(B=B||(B={}));var v;(function(a){a.Initial="Initial",a.HaveLocalOffer="HaveLocalOffer",a.HaveRemoteOffer="HaveRemoteOffer",a.Stable="Stable",a.Closed="Closed"})(v=v||(v={}));const Z=500,bt=4e3,Ke=5e3,H={T1:Z,T2:bt,TIMER_B:64*Z,TIMER_D:0*Z,TIMER_F:64*Z,TIMER_H:64*Z,TIMER_I:0*Ke,TIMER_J:0*Z,TIMER_K:0*Ke,TIMER_L:64*Z,TIMER_M:64*Z,TIMER_N:64*Z,PROVISIONAL_RESPONSE_INTERVAL:6e4};class ee extends ne{constructor(e){super(e||"Transaction state error.")}}var y;(function(a){a.ACK="ACK",a.BYE="BYE",a.CANCEL="CANCEL",a.INFO="INFO",a.INVITE="INVITE",a.MESSAGE="MESSAGE",a.NOTIFY="NOTIFY",a.OPTIONS="OPTIONS",a.REGISTER="REGISTER",a.UPDATE="UPDATE",a.SUBSCRIBE="SUBSCRIBE",a.PUBLISH="PUBLISH",a.REFER="REFER",a.PRACK="PRACK"})(y=y||(y={}));const te=[y.ACK,y.BYE,y.CANCEL,y.INFO,y.INVITE,y.MESSAGE,y.NOTIFY,y.OPTIONS,y.PRACK,y.REFER,y.REGISTER,y.SUBSCRIBE];class We{constructor(e){this.incomingMessageRequest=e}get request(){return this.incomingMessageRequest.message}accept(e){return this.incomingMessageRequest.accept(e),Promise.resolve()}reject(e){return this.incomingMessageRequest.reject(e),Promise.resolve()}}class Pe{constructor(e){this.incomingNotifyRequest=e}get request(){return this.incomingNotifyRequest.message}accept(e){return this.incomingNotifyRequest.accept(e),Promise.resolve()}reject(e){return this.incomingNotifyRequest.reject(e),Promise.resolve()}}class vt{constructor(e,t){this.incomingReferRequest=e,this.session=t}get referTo(){const e=this.incomingReferRequest.message.parseHeader("refer-to");if(!(e instanceof O))throw new Error("Failed to parse Refer-To header.");return e}get referredBy(){return this.incomingReferRequest.message.getHeader("referred-by")}get replaces(){const e=this.referTo.uri.getHeader("replaces");return e instanceof Array?e[0]:e}get request(){return this.incomingReferRequest.message}accept(e={statusCode:202}){return this.incomingReferRequest.accept(e),Promise.resolve()}reject(e){return this.incomingReferRequest.reject(e),Promise.resolve()}makeInviter(e){if(this.inviter)return this.inviter;const t=this.referTo.uri.clone();t.clearHeaders(),e=e||{};const s=(e.extraHeaders||[]).slice(),i=this.replaces;i&&s.push("Replaces: "+decodeURIComponent(i));const r=this.referredBy;return r&&s.push("Referred-By: "+r),e.extraHeaders=s,this.inviter=this.session.userAgent._makeInviter(t,e),this.inviter._referred=this.session,this.session._referral=this.inviter,this.inviter}}var m;(function(a){a.Initial="Initial",a.Establishing="Establishing",a.Established="Established",a.Terminating="Terminating",a.Terminated="Terminated"})(m=m||(m={}));class ue{constructor(e,t={}){this.pendingReinvite=!1,this.pendingReinviteAck=!1,this._state=m.Initial,this.delegate=t.delegate,this._stateEventEmitter=new me,this._userAgent=e}dispose(){switch(this.logger.log(`Session ${this.id} in state ${this._state} is being disposed`),delete this.userAgent._sessions[this.id],this._sessionDescriptionHandler&&this._sessionDescriptionHandler.close(),this.state){case m.Initial:break;case m.Establishing:break;case m.Established:return new Promise(e=>{this._bye({onAccept:()=>e(),onRedirect:()=>e(),onReject:()=>e()})});case m.Terminating:break;case m.Terminated:break;default:throw new Error("Unknown state.")}return Promise.resolve()}get assertedIdentity(){return this._assertedIdentity}get dialog(){return this._dialog}get id(){return this._id}get replacee(){return this._replacee}get sessionDescriptionHandler(){return this._sessionDescriptionHandler}get sessionDescriptionHandlerFactory(){return this.userAgent.configuration.sessionDescriptionHandlerFactory}get sessionDescriptionHandlerModifiers(){return this._sessionDescriptionHandlerModifiers||[]}set sessionDescriptionHandlerModifiers(e){this._sessionDescriptionHandlerModifiers=e.slice()}get sessionDescriptionHandlerOptions(){return this._sessionDescriptionHandlerOptions||{}}set sessionDescriptionHandlerOptions(e){this._sessionDescriptionHandlerOptions=Object.assign({},e)}get sessionDescriptionHandlerModifiersReInvite(){return this._sessionDescriptionHandlerModifiersReInvite||[]}set sessionDescriptionHandlerModifiersReInvite(e){this._sessionDescriptionHandlerModifiersReInvite=e.slice()}get sessionDescriptionHandlerOptionsReInvite(){return this._sessionDescriptionHandlerOptionsReInvite||{}}set sessionDescriptionHandlerOptionsReInvite(e){this._sessionDescriptionHandlerOptionsReInvite=Object.assign({},e)}get state(){return this._state}get stateChange(){return this._stateEventEmitter}get userAgent(){return this._userAgent}bye(e={}){let t="Session.bye() may only be called if established session.";switch(this.state){case m.Initial:typeof this.cancel=="function"?(t+=" However Inviter.invite() has not yet been called.",t+=" Perhaps you should have called Inviter.cancel()?"):typeof this.reject=="function"&&(t+=" However Invitation.accept() has not yet been called.",t+=" Perhaps you should have called Invitation.reject()?");break;case m.Establishing:typeof this.cancel=="function"?(t+=" However a dialog does not yet exist.",t+=" Perhaps you should have called Inviter.cancel()?"):typeof this.reject=="function"&&(t+=" However Invitation.accept() has not yet been called (or not yet resolved).",t+=" Perhaps you should have called Invitation.reject()?");break;case m.Established:{const s=e.requestDelegate,i=this.copyRequestOptions(e.requestOptions);return this._bye(s,i)}case m.Terminating:t+=" However this session is already terminating.",typeof this.cancel=="function"?t+=" Perhaps you have already called Inviter.cancel()?":typeof this.reject=="function"&&(t+=" Perhaps you have already called Session.bye()?");break;case m.Terminated:t+=" However this session is already terminated.";break;default:throw new Error("Unknown state")}return this.logger.error(t),Promise.reject(new Error(`Invalid session state ${this.state}`))}info(e={}){if(this.state!==m.Established)return this.logger.error("Session.info() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.requestDelegate,s=this.copyRequestOptions(e.requestOptions);return this._info(t,s)}invite(e={}){if(this.logger.log("Session.invite"),this.state!==m.Established)return Promise.reject(new Error(`Invalid session state ${this.state}`));if(this.pendingReinvite)return Promise.reject(new fe("Reinvite in progress. Please wait until complete, then try again."));this.pendingReinvite=!0,e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiersReInvite=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptionsReInvite=e.sessionDescriptionHandlerOptions);const t={onAccept:r=>{const n=be(r.message);if(!n){this.logger.error("Received 2xx response to re-INVITE without a session description"),this.ackAndBye(r,400,"Missing session description"),this.stateTransition(m.Terminated),this.pendingReinvite=!1;return}if(e.withoutSdp){const o={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.setOfferAndGetAnswer(n,o).then(d=>{r.ack({body:d})}).catch(d=>{this.logger.error("Failed to handle offer in 2xx response to re-INVITE"),this.logger.error(d.message),this.state===m.Terminated?r.ack():(this.ackAndBye(r,488,"Bad Media Description"),this.stateTransition(m.Terminated))}).then(()=>{this.pendingReinvite=!1,e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(r)})}else{const o={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.setAnswer(n,o).then(()=>{r.ack()}).catch(d=>{this.logger.error("Failed to handle answer in 2xx response to re-INVITE"),this.logger.error(d.message),this.state!==m.Terminated?(this.ackAndBye(r,488,"Bad Media Description"),this.stateTransition(m.Terminated)):r.ack()}).then(()=>{this.pendingReinvite=!1,e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(r)})}},onProgress:r=>{},onRedirect:r=>{},onReject:r=>{this.logger.warn("Received a non-2xx response to re-INVITE"),this.pendingReinvite=!1,e.withoutSdp?e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(r):this.rollbackOffer().catch(n=>{if(this.logger.error("Failed to rollback offer on non-2xx response to re-INVITE"),this.logger.error(n.message),this.state!==m.Terminated){if(!this.dialog)throw new Error("Dialog undefined.");const o=[];o.push("Reason: "+this.getReasonHeaderValue(500,"Internal Server Error")),this.dialog.bye(void 0,{extraHeaders:o}),this.stateTransition(m.Terminated)}}).then(()=>{e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(r)})},onTrying:r=>{}},s=e.requestOptions||{};if(s.extraHeaders=(s.extraHeaders||[]).slice(),s.extraHeaders.push("Allow: "+te.toString()),s.extraHeaders.push("Contact: "+this._contact),e.withoutSdp){if(!this.dialog)throw this.pendingReinvite=!1,new Error("Dialog undefined.");return Promise.resolve(this.dialog.invite(t,s))}const i={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};return this.getOffer(i).then(r=>{if(!this.dialog)throw this.pendingReinvite=!1,new Error("Dialog undefined.");return s.body=r,this.dialog.invite(t,s)}).catch(r=>{throw this.logger.error(r.message),this.logger.error("Failed to send re-INVITE"),this.pendingReinvite=!1,r})}message(e={}){if(this.state!==m.Established)return this.logger.error("Session.message() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.requestDelegate,s=this.copyRequestOptions(e.requestOptions);return this._message(t,s)}refer(e,t={}){if(this.state!==m.Established)return this.logger.error("Session.refer() may only be called if established session."),Promise.reject(new Error(`Invalid session state ${this.state}`));if(e instanceof ue&&!e.dialog)return this.logger.error("Session.refer() may only be called with session which is established. You are perhaps attempting to attended transfer to a target for which there is not dialog yet established. Perhaps you are attempting a 'semi-attended' tansfer? Regardless, this is not supported. The recommended approached is to check to see if the target Session is in the Established state before calling refer(); if the state is not Established you may proceed by falling back using a URI as the target (blind transfer)."),Promise.reject(new Error(`Invalid session state ${this.state}`));const s=t.requestDelegate,i=this.copyRequestOptions(t.requestOptions);return i.extraHeaders=i.extraHeaders?i.extraHeaders.concat(this.referExtraHeaders(this.referToString(e))):this.referExtraHeaders(this.referToString(e)),this._refer(t.onNotify,s,i)}_bye(e,t){if(!this.dialog)return Promise.reject(new Error("Session dialog undefined."));const s=this.dialog;switch(s.sessionState){case B.Initial:throw new Error(`Invalid dialog state ${s.sessionState}`);case B.Early:throw new Error(`Invalid dialog state ${s.sessionState}`);case B.AckWait:return this.stateTransition(m.Terminating),new Promise(i=>{s.delegate={onAck:()=>{const r=s.bye(e,t);return this.stateTransition(m.Terminated),i(r),Promise.resolve()},onAckTimeout:()=>{const r=s.bye(e,t);this.stateTransition(m.Terminated),i(r)}}});case B.Confirmed:{const i=s.bye(e,t);return this.stateTransition(m.Terminated),Promise.resolve(i)}case B.Terminated:throw new Error(`Invalid dialog state ${s.sessionState}`);default:throw new Error("Unrecognized state.")}}_info(e,t){return this.dialog?Promise.resolve(this.dialog.info(e,t)):Promise.reject(new Error("Session dialog undefined."))}_message(e,t){return this.dialog?Promise.resolve(this.dialog.message(e,t)):Promise.reject(new Error("Session dialog undefined."))}_refer(e,t,s){return this.dialog?(this.onNotify=e,Promise.resolve(this.dialog.refer(t,s))):Promise.reject(new Error("Session dialog undefined."))}ackAndBye(e,t,s){e.ack();const i=[];t&&i.push("Reason: "+this.getReasonHeaderValue(t,s)),e.session.bye(void 0,{extraHeaders:i})}onAckRequest(e){if(this.logger.log("Session.onAckRequest"),this.state!==m.Established&&this.state!==m.Terminating)return this.logger.error(`ACK received while in state ${this.state}, dropping request`),Promise.resolve();const t=this.dialog;if(!t)throw new Error("Dialog undefined.");const s={sessionDescriptionHandlerOptions:this.pendingReinviteAck?this.sessionDescriptionHandlerOptionsReInvite:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.pendingReinviteAck?this._sessionDescriptionHandlerModifiersReInvite:this._sessionDescriptionHandlerModifiers};if(this.delegate&&this.delegate.onAck){const i=new ht(e);this.delegate.onAck(i)}switch(this.pendingReinviteAck=!1,t.signalingState){case v.Initial:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.Stable:{const i=be(e.message);return i?i.contentDisposition==="render"?(this._renderbody=i.content,this._rendertype=i.contentType,Promise.resolve()):i.contentDisposition!=="session"?Promise.resolve():this.setAnswer(i,s).catch(r=>{this.logger.error(r.message);const n=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];t.bye(void 0,{extraHeaders:n}),this.stateTransition(m.Terminated)}):Promise.resolve()}case v.HaveLocalOffer:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.HaveRemoteOffer:{this.logger.error(`Invalid signaling state ${t.signalingState}.`);const i=["Reason: "+this.getReasonHeaderValue(488,"Bad Media Description")];return t.bye(void 0,{extraHeaders:i}),this.stateTransition(m.Terminated),Promise.resolve()}case v.Closed:throw new Error(`Invalid signaling state ${t.signalingState}.`);default:throw new Error(`Invalid signaling state ${t.signalingState}.`)}}onByeRequest(e){if(this.logger.log("Session.onByeRequest"),this.state!==m.Established){this.logger.error(`BYE received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onBye){const t=new ut(e);this.delegate.onBye(t)}else e.accept();this.stateTransition(m.Terminated)}onInfoRequest(e){if(this.logger.log("Session.onInfoRequest"),this.state!==m.Established){this.logger.error(`INFO received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onInfo){const t=new ft(e);this.delegate.onInfo(t)}else e.accept()}onInviteRequest(e){if(this.logger.log("Session.onInviteRequest"),this.state!==m.Established){this.logger.error(`INVITE received while in state ${this.state}, dropping request`);return}this.pendingReinviteAck=!0;const t=["Contact: "+this._contact];if(e.message.hasHeader("P-Asserted-Identity")){const i=e.message.getHeader("P-Asserted-Identity");if(!i)throw new Error("Header undefined.");this._assertedIdentity=D.nameAddrHeaderParse(i)}const s={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptionsReInvite,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiersReInvite};this.generateResponseOfferAnswerInDialog(s).then(i=>{const r=e.accept({statusCode:200,extraHeaders:t,body:i});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,200)}).catch(i=>{if(this.logger.error(i.message),this.logger.error("Failed to handle to re-INVITE request"),!this.dialog)throw new Error("Dialog undefined.");if(this.logger.error(this.dialog.signalingState),this.dialog.signalingState===v.Stable){const r=e.reject({statusCode:488});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,488);return}this.rollbackOffer().then(()=>{const r=e.reject({statusCode:488});this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,r.message,488)}).catch(r=>{this.logger.error(r.message),this.logger.error("Failed to rollback offer on re-INVITE request");const n=e.reject({statusCode:488});if(this.state!==m.Terminated){if(!this.dialog)throw new Error("Dialog undefined.");const o=[];o.push("Reason: "+this.getReasonHeaderValue(500,"Internal Server Error")),this.dialog.bye(void 0,{extraHeaders:o}),this.stateTransition(m.Terminated)}this.delegate&&this.delegate.onInvite&&this.delegate.onInvite(e.message,n.message,488)})})}onMessageRequest(e){if(this.logger.log("Session.onMessageRequest"),this.state!==m.Established){this.logger.error(`MESSAGE received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onMessage){const t=new We(e);this.delegate.onMessage(t)}else e.accept()}onNotifyRequest(e){if(this.logger.log("Session.onNotifyRequest"),this.state!==m.Established){this.logger.error(`NOTIFY received while in state ${this.state}, dropping request`);return}if(this.onNotify){const t=new Pe(e);this.onNotify(t);return}if(this.delegate&&this.delegate.onNotify){const t=new Pe(e);this.delegate.onNotify(t)}else e.accept()}onPrackRequest(e){if(this.logger.log("Session.onPrackRequest"),this.state!==m.Established){this.logger.error(`PRACK received while in state ${this.state}, dropping request`);return}throw new Error("Unimplemented.")}onReferRequest(e){if(this.logger.log("Session.onReferRequest"),this.state!==m.Established){this.logger.error(`REFER received while in state ${this.state}, dropping request`);return}if(!e.message.hasHeader("refer-to")){this.logger.warn("Invalid REFER packet. A refer-to header is required. Rejecting."),e.reject();return}const t=new vt(e,this);this.delegate&&this.delegate.onRefer?this.delegate.onRefer(t):(this.logger.log("No delegate available to handle REFER, automatically accepting and following."),t.accept().then(()=>t.makeInviter(this._referralInviterOptions).invite()).catch(s=>{this.logger.error(s.message)}))}generateResponseOfferAnswer(e,t){if(this.dialog)return this.generateResponseOfferAnswerInDialog(t);const s=be(e.message);return!s||s.contentDisposition!=="session"?this.getOffer(t):this.setOfferAndGetAnswer(s,t)}generateResponseOfferAnswerInDialog(e){if(!this.dialog)throw new Error("Dialog undefined.");switch(this.dialog.signalingState){case v.Initial:return this.getOffer(e);case v.HaveLocalOffer:return Promise.resolve(void 0);case v.HaveRemoteOffer:if(!this.dialog.offer)throw new Error(`Session offer undefined in signaling state ${this.dialog.signalingState}.`);return this.setOfferAndGetAnswer(this.dialog.offer,e);case v.Stable:return this.state!==m.Established?Promise.resolve(void 0):this.getOffer(e);case v.Closed:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);default:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`)}}getOffer(e){const t=this.setupSessionDescriptionHandler(),s=e.sessionDescriptionHandlerOptions,i=e.sessionDescriptionHandlerModifiers;try{return t.getDescription(s,i).then(r=>Ee(r)).catch(r=>{this.logger.error("Session.getOffer: SDH getDescription rejected...");const n=r instanceof Error?r:new Error("Session.getOffer unknown error.");throw this.logger.error(n.message),n})}catch(r){this.logger.error("Session.getOffer: SDH getDescription threw...");const n=r instanceof Error?r:new Error(r);return this.logger.error(n.message),Promise.reject(n)}}rollbackOffer(){const e=this.setupSessionDescriptionHandler();if(e.rollbackDescription===void 0)return Promise.resolve();try{return e.rollbackDescription().catch(t=>{this.logger.error("Session.rollbackOffer: SDH rollbackDescription rejected...");const s=t instanceof Error?t:new Error("Session.rollbackOffer unknown error.");throw this.logger.error(s.message),s})}catch(t){this.logger.error("Session.rollbackOffer: SDH rollbackDescription threw...");const s=t instanceof Error?t:new Error(t);return this.logger.error(s.message),Promise.reject(s)}}setAnswer(e,t){const s=this.setupSessionDescriptionHandler(),i=t.sessionDescriptionHandlerOptions,r=t.sessionDescriptionHandlerModifiers;try{if(!s.hasDescription(e.contentType))return Promise.reject(new _e)}catch(n){this.logger.error("Session.setAnswer: SDH hasDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}try{return s.setDescription(e.content,i,r).catch(n=>{this.logger.error("Session.setAnswer: SDH setDescription rejected...");const o=n instanceof Error?n:new Error("Session.setAnswer unknown error.");throw this.logger.error(o.message),o})}catch(n){this.logger.error("Session.setAnswer: SDH setDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}}setOfferAndGetAnswer(e,t){const s=this.setupSessionDescriptionHandler(),i=t.sessionDescriptionHandlerOptions,r=t.sessionDescriptionHandlerModifiers;try{if(!s.hasDescription(e.contentType))return Promise.reject(new _e)}catch(n){this.logger.error("Session.setOfferAndGetAnswer: SDH hasDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}try{return s.setDescription(e.content,i,r).then(()=>s.getDescription(i,r)).then(n=>Ee(n)).catch(n=>{this.logger.error("Session.setOfferAndGetAnswer: SDH setDescription or getDescription rejected...");const o=n instanceof Error?n:new Error("Session.setOfferAndGetAnswer unknown error.");throw this.logger.error(o.message),o})}catch(n){this.logger.error("Session.setOfferAndGetAnswer: SDH setDescription or getDescription threw...");const o=n instanceof Error?n:new Error(n);return this.logger.error(o.message),Promise.reject(o)}}setSessionDescriptionHandler(e){if(this._sessionDescriptionHandler)throw new Error("Session description handler defined.");this._sessionDescriptionHandler=e}setupSessionDescriptionHandler(){var e;return this._sessionDescriptionHandler?this._sessionDescriptionHandler:(this._sessionDescriptionHandler=this.sessionDescriptionHandlerFactory(this,this.userAgent.configuration.sessionDescriptionHandlerFactoryOptions),!((e=this.delegate)===null||e===void 0)&&e.onSessionDescriptionHandler&&this.delegate.onSessionDescriptionHandler(this._sessionDescriptionHandler,!1),this._sessionDescriptionHandler)}stateTransition(e){const t=()=>{throw new Error(`Invalid state transition from ${this._state} to ${e}`)};switch(this._state){case m.Initial:e!==m.Establishing&&e!==m.Established&&e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Establishing:e!==m.Established&&e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Established:e!==m.Terminating&&e!==m.Terminated&&t();break;case m.Terminating:e!==m.Terminated&&t();break;case m.Terminated:t();break;default:throw new Error("Unrecognized state.")}this._state=e,this.logger.log(`Session ${this.id} transitioned to state ${this._state}`),this._stateEventEmitter.emit(this._state),e===m.Terminated&&this.dispose()}copyRequestOptions(e={}){const t=e.extraHeaders?e.extraHeaders.slice():void 0,s=e.body?{contentDisposition:e.body.contentDisposition||"render",contentType:e.body.contentType||"text/plain",content:e.body.content||""}:void 0;return{extraHeaders:t,body:s}}getReasonHeaderValue(e,t){const s=e;let i=Se(e);return!i&&t&&(i=t),"SIP;cause="+s+';text="'+i+'"'}referExtraHeaders(e){const t=[];return t.push("Referred-By: <"+this.userAgent.configuration.uri+">"),t.push("Contact: "+this._contact),t.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),t.push("Refer-To: "+e),t}referToString(e){let t;if(e instanceof K)t=e.toString();else{if(!e.dialog)throw new Error("Dialog undefined.");const s=e.remoteIdentity.friendlyName,i=e.dialog.remoteTarget.toString(),r=e.dialog.callId,n=e.dialog.remoteTag,o=e.dialog.localTag,d=encodeURIComponent(`${r};to-tag=${n};from-tag=${o}`);t=`"${s}" <${i}?Replaces=${d}>`}return t}}var G;(function(a){a.Required="Required",a.Supported="Supported",a.Unsupported="Unsupported"})(G=G||(G={}));const yt={"100rel":!0,199:!0,answermode:!0,"early-session":!0,eventlist:!0,explicitsub:!0,"from-change":!0,"geolocation-http":!0,"geolocation-sip":!0,gin:!0,gruu:!0,histinfo:!0,ice:!0,join:!0,"multiple-refer":!0,norefersub:!0,nosub:!0,outbound:!0,path:!0,policy:!0,precondition:!0,pref:!0,privacy:!0,"recipient-list-invite":!0,"recipient-list-message":!0,"recipient-list-subscribe":!0,replaces:!0,"resource-priority":!0,"sdp-anat":!0,"sec-agree":!0,tdialog:!0,timer:!0,uui:!0};class ce extends ue{constructor(e,t){super(e),this.incomingInviteRequest=t,this.disposed=!1,this.expiresTimer=void 0,this.isCanceled=!1,this.rel100="none",this.rseq=Math.floor(Math.random()*1e4),this.userNoAnswerTimer=void 0,this.waitingForPrack=!1,this.logger=e.getLogger("sip.Invitation");const s=this.incomingInviteRequest.message,i=s.getHeader("require");i&&i.toLowerCase().includes("100rel")&&(this.rel100="required");const r=s.getHeader("supported");if(r&&r.toLowerCase().includes("100rel")&&(this.rel100="supported"),s.toTag=t.toTag,typeof s.toTag!="string")throw new TypeError("toTag should have been a string.");if(this.userNoAnswerTimer=setTimeout(()=>{t.reject({statusCode:480}),this.stateTransition(m.Terminated)},this.userAgent.configuration.noAnswerTimeout?this.userAgent.configuration.noAnswerTimeout*1e3:6e4),s.hasHeader("expires")){const d=Number(s.getHeader("expires")||0)*1e3;this.expiresTimer=setTimeout(()=>{this.state===m.Initial&&(t.reject({statusCode:487}),this.stateTransition(m.Terminated))},d)}const n=this.request.getHeader("P-Asserted-Identity");n&&(this._assertedIdentity=D.nameAddrHeaderParse(n)),this._contact=this.userAgent.contact.toString();const o=s.parseHeader("Content-Disposition");o&&o.type==="render"&&(this._renderbody=s.body,this._rendertype=s.getHeader("Content-Type")),this._id=s.callId+s.fromTag,this.userAgent._sessions[this._id]=this}dispose(){if(this.disposed)return Promise.resolve();switch(this.disposed=!0,this.expiresTimer&&(clearTimeout(this.expiresTimer),this.expiresTimer=void 0),this.userNoAnswerTimer&&(clearTimeout(this.userNoAnswerTimer),this.userNoAnswerTimer=void 0),this.prackNeverArrived(),this.state){case m.Initial:return this.reject().then(()=>super.dispose());case m.Establishing:return this.reject().then(()=>super.dispose());case m.Established:return super.dispose();case m.Terminating:return super.dispose();case m.Terminated:return super.dispose();default:throw new Error("Unknown state.")}}get autoSendAnInitialProvisionalResponse(){return this.rel100!=="required"&&this.userAgent.configuration.sendInitialProvisionalResponse}get body(){return this.incomingInviteRequest.message.body}get localIdentity(){return this.request.to}get remoteIdentity(){return this.request.from}get request(){return this.incomingInviteRequest.message}accept(e={}){if(this.logger.log("Invitation.accept"),this.state!==m.Initial){const t=new Error(`Invalid session state ${this.state}`);return this.logger.error(t.message),Promise.reject(t)}return e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),this.stateTransition(m.Establishing),this.sendAccept(e).then(({message:t,session:s})=>{s.delegate={onAck:i=>this.onAckRequest(i),onAckTimeout:()=>this.onAckTimeout(),onBye:i=>this.onByeRequest(i),onInfo:i=>this.onInfoRequest(i),onInvite:i=>this.onInviteRequest(i),onMessage:i=>this.onMessageRequest(i),onNotify:i=>this.onNotifyRequest(i),onPrack:i=>this.onPrackRequest(i),onRefer:i=>this.onReferRequest(i)},this._dialog=s,this.stateTransition(m.Established),this._replacee&&this._replacee._bye()}).catch(t=>this.handleResponseError(t))}progress(e={}){if(this.logger.log("Invitation.progress"),this.state!==m.Initial){const s=new Error(`Invalid session state ${this.state}`);return this.logger.error(s.message),Promise.reject(s)}const t=e.statusCode||180;if(t<100||t>199)throw new TypeError("Invalid statusCode: "+t);return e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),this.waitingForPrack?(this.logger.warn("Unexpected call for progress while waiting for prack, ignoring"),Promise.resolve()):e.statusCode===100?this.sendProgressTrying().then(()=>{}).catch(s=>this.handleResponseError(s)):this.rel100!=="required"&&!(this.rel100==="supported"&&e.rel100)&&!(this.rel100==="supported"&&this.userAgent.configuration.sipExtension100rel===G.Required)?this.sendProgress(e).then(()=>{}).catch(s=>this.handleResponseError(s)):this.sendProgressReliableWaitForPrack(e).then(()=>{}).catch(s=>this.handleResponseError(s))}reject(e={}){if(this.logger.log("Invitation.reject"),this.state!==m.Initial&&this.state!==m.Establishing){const n=new Error(`Invalid session state ${this.state}`);return this.logger.error(n.message),Promise.reject(n)}const t=e.statusCode||480,s=e.reasonPhrase?e.reasonPhrase:Se(t),i=e.extraHeaders||[];if(t<300||t>699)throw new TypeError("Invalid statusCode: "+t);const r=e.body?Ee(e.body):void 0;return t<400?this.incomingInviteRequest.redirect([],{statusCode:t,reasonPhrase:s,extraHeaders:i,body:r}):this.incomingInviteRequest.reject({statusCode:t,reasonPhrase:s,extraHeaders:i,body:r}),this.stateTransition(m.Terminated),Promise.resolve()}_onCancel(e){if(this.logger.log("Invitation._onCancel"),this.state!==m.Initial&&this.state!==m.Establishing){this.logger.error(`CANCEL received while in state ${this.state}, dropping request`);return}if(this.delegate&&this.delegate.onCancel){const t=new gt(e);this.delegate.onCancel(t)}this.isCanceled=!0,this.incomingInviteRequest.reject({statusCode:487}),this.stateTransition(m.Terminated)}handlePrackOfferAnswer(e){if(!this.dialog)throw new Error("Dialog undefined.");const t=be(e.message);if(!t||t.contentDisposition!=="session")return Promise.resolve(void 0);const s={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers};switch(this.dialog.signalingState){case v.Initial:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);case v.Stable:return this.setAnswer(t,s).then(()=>{});case v.HaveLocalOffer:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);case v.HaveRemoteOffer:return this.setOfferAndGetAnswer(t,s);case v.Closed:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`);default:throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`)}}handleResponseError(e){let t=480;if(e instanceof Error?this.logger.error(e.message):this.logger.error(e),e instanceof _e?(this.logger.error("A session description handler occurred while sending response (content type unsupported"),t=415):e instanceof lt?this.logger.error("A session description handler occurred while sending response"):e instanceof De?this.logger.error("Session ended before response could be formulated and sent (while waiting for PRACK)"):e instanceof ee&&this.logger.error("Session changed state before response could be formulated and sent"),this.state===m.Initial||this.state===m.Establishing)try{this.incomingInviteRequest.reject({statusCode:t}),this.stateTransition(m.Terminated)}catch(s){throw this.logger.error("An error occurred attempting to reject the request while handling another error"),s}if(this.isCanceled){this.logger.warn("An error occurred while attempting to formulate and send a response to an incoming INVITE. However a CANCEL was received and processed while doing so which can (and often does) result in errors occurring as the session terminates in the meantime. Said error is being ignored.");return}throw e}onAckTimeout(){if(this.logger.log("Invitation.onAckTimeout"),!this.dialog)throw new Error("Dialog undefined.");this.logger.log("No ACK received for an extended period of time, terminating session"),this.dialog.bye(),this.stateTransition(m.Terminated)}sendAccept(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.extraHeaders||[];return this.waitingForPrack?this.waitForArrivalOfPrack().then(()=>clearTimeout(this.userNoAnswerTimer)).then(()=>this.generateResponseOfferAnswer(this.incomingInviteRequest,t)).then(i=>this.incomingInviteRequest.accept({statusCode:200,body:i,extraHeaders:s})):(clearTimeout(this.userNoAnswerTimer),this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(i=>this.incomingInviteRequest.accept({statusCode:200,body:i,extraHeaders:s})))}sendProgress(e={}){const t=e.statusCode||180,s=e.reasonPhrase,i=(e.extraHeaders||[]).slice(),r=e.body?Ee(e.body):void 0;if(t===183&&!r)return this.sendProgressWithSDP(e);try{const n=this.incomingInviteRequest.progress({statusCode:t,reasonPhrase:s,extraHeaders:i,body:r});return this._dialog=n.session,Promise.resolve(n)}catch(n){return Promise.reject(n)}}sendProgressWithSDP(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.statusCode||183,i=e.reasonPhrase,r=(e.extraHeaders||[]).slice();return this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(n=>this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n})).then(n=>(this._dialog=n.session,n))}sendProgressReliable(e={}){return e.extraHeaders=(e.extraHeaders||[]).slice(),e.extraHeaders.push("Require: 100rel"),e.extraHeaders.push("RSeq: "+Math.floor(Math.random()*1e4)),this.sendProgressWithSDP(e)}sendProgressReliableWaitForPrack(e={}){const t={sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions,sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers},s=e.statusCode||183,i=e.reasonPhrase,r=(e.extraHeaders||[]).slice();r.push("Require: 100rel"),r.push("RSeq: "+this.rseq++);let n;return new Promise((o,d)=>{this.waitingForPrack=!0,this.generateResponseOfferAnswer(this.incomingInviteRequest,t).then(p=>(n=p,this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n}))).then(p=>{this._dialog=p.session;let g,w;p.session.delegate={onPrack:f=>{g=f,clearTimeout(I),clearTimeout(de),this.waitingForPrack&&(this.waitingForPrack=!1,this.handlePrackOfferAnswer(g).then($=>{try{w=g.accept({statusCode:200,body:$}),this.prackArrived(),o({prackRequest:g,prackResponse:w,progressResponse:p})}catch(Ne){d(Ne)}}).catch($=>d($)))}};const I=setTimeout(()=>{this.waitingForPrack&&(this.waitingForPrack=!1,this.logger.warn("No PRACK received, rejecting INVITE."),clearTimeout(de),this.reject({statusCode:504}).then(()=>d(new De)).catch(f=>d(f)))},H.T1*64),A=()=>{try{this.incomingInviteRequest.progress({statusCode:s,reasonPhrase:i,extraHeaders:r,body:n})}catch(f){this.waitingForPrack=!1,d(f);return}de=setTimeout(A,C*=2)};let C=H.T1,de=setTimeout(A,C)}).catch(p=>{this.waitingForPrack=!1,d(p)})})}sendProgressTrying(){try{const e=this.incomingInviteRequest.trying();return Promise.resolve(e)}catch(e){return Promise.reject(e)}}waitForArrivalOfPrack(){if(this.waitingForPrackPromise)throw new Error("Already waiting for PRACK");return this.waitingForPrackPromise=new Promise((e,t)=>{this.waitingForPrackResolve=e,this.waitingForPrackReject=t}),this.waitingForPrackPromise}prackArrived(){this.waitingForPrackResolve&&this.waitingForPrackResolve(),this.waitingForPrackPromise=void 0,this.waitingForPrackResolve=void 0,this.waitingForPrackReject=void 0}prackNeverArrived(){this.waitingForPrackReject&&this.waitingForPrackReject(new De),this.waitingForPrackPromise=void 0,this.waitingForPrackResolve=void 0,this.waitingForPrackReject=void 0}}class Ce extends ue{constructor(e,t,s={}){super(e,s),this.disposed=!1,this.earlyMedia=!1,this.earlyMediaSessionDescriptionHandlers=new Map,this.isCanceled=!1,this.inviteWithoutSdp=!1,this.logger=e.getLogger("sip.Inviter"),this.earlyMedia=s.earlyMedia!==void 0?s.earlyMedia:this.earlyMedia,this.fromTag=Te(),this.inviteWithoutSdp=s.inviteWithoutSdp!==void 0?s.inviteWithoutSdp:this.inviteWithoutSdp;const i=Object.assign({},s);i.params=Object.assign({},s.params);const r=s.anonymous||!1,n=e.contact.toString({anonymous:r,outbound:r?!e.contact.tempGruu:!e.contact.pubGruu});r&&e.configuration.uri&&(i.params.fromDisplayName="Anonymous",i.params.fromUri="sip:anonymous@anonymous.invalid");let o=e.userAgentCore.configuration.aor;if(i.params.fromUri&&(o=typeof i.params.fromUri=="string"?D.URIParse(i.params.fromUri):i.params.fromUri),!o)throw new TypeError("Invalid from URI: "+i.params.fromUri);let d=t;if(i.params.toUri&&(d=typeof i.params.toUri=="string"?D.URIParse(i.params.toUri):i.params.toUri),!d)throw new TypeError("Invalid to URI: "+i.params.toUri);const p=Object.assign({},i.params);p.fromTag=this.fromTag;const g=(i.extraHeaders||[]).slice();r&&e.configuration.uri&&(g.push("P-Preferred-Identity: "+e.configuration.uri.toString()),g.push("Privacy: id")),g.push("Contact: "+n),g.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),e.configuration.sipExtension100rel===G.Required&&g.push("Require: 100rel"),e.configuration.sipExtensionReplaces===G.Required&&g.push("Require: replaces"),i.extraHeaders=g;const w=void 0;this.outgoingRequestMessage=e.userAgentCore.makeOutgoingRequestMessage(y.INVITE,t,o,d,p,g,w),this._contact=n,this._referralInviterOptions=i,this._renderbody=s.renderbody,this._rendertype=s.rendertype,s.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=s.sessionDescriptionHandlerModifiers),s.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=s.sessionDescriptionHandlerOptions),s.sessionDescriptionHandlerModifiersReInvite&&(this.sessionDescriptionHandlerModifiersReInvite=s.sessionDescriptionHandlerModifiersReInvite),s.sessionDescriptionHandlerOptionsReInvite&&(this.sessionDescriptionHandlerOptionsReInvite=s.sessionDescriptionHandlerOptionsReInvite),this._id=this.outgoingRequestMessage.callId+this.fromTag,this.userAgent._sessions[this._id]=this}dispose(){if(this.disposed)return Promise.resolve();switch(this.disposed=!0,this.disposeEarlyMedia(),this.state){case m.Initial:return this.cancel().then(()=>super.dispose());case m.Establishing:return this.cancel().then(()=>super.dispose());case m.Established:return super.dispose();case m.Terminating:return super.dispose();case m.Terminated:return super.dispose();default:throw new Error("Unknown state.")}}get body(){return this.outgoingRequestMessage.body}get localIdentity(){return this.outgoingRequestMessage.from}get remoteIdentity(){return this.outgoingRequestMessage.to}get request(){return this.outgoingRequestMessage}cancel(e={}){if(this.logger.log("Inviter.cancel"),this.state!==m.Initial&&this.state!==m.Establishing){const s=new Error(`Invalid session state ${this.state}`);return this.logger.error(s.message),Promise.reject(s)}this.isCanceled=!0,this.stateTransition(m.Terminating);function t(s,i){if(s&&s<200||s>699)throw new TypeError("Invalid statusCode: "+s);if(s){const r=s,n=Se(s)||i;return"SIP;cause="+r+';text="'+n+'"'}}if(this.outgoingInviteRequest){let s;e.statusCode&&e.reasonPhrase&&(s=t(e.statusCode,e.reasonPhrase)),this.outgoingInviteRequest.cancel(s,e)}else this.logger.warn("Canceled session before INVITE was sent"),this.stateTransition(m.Terminated);return Promise.resolve()}invite(e={}){if(this.logger.log("Inviter.invite"),this.state!==m.Initial)return super.invite(e);if(e.sessionDescriptionHandlerModifiers&&(this.sessionDescriptionHandlerModifiers=e.sessionDescriptionHandlerModifiers),e.sessionDescriptionHandlerOptions&&(this.sessionDescriptionHandlerOptions=e.sessionDescriptionHandlerOptions),e.withoutSdp||this.inviteWithoutSdp)return this._renderbody&&this._rendertype&&(this.outgoingRequestMessage.body={contentType:this._rendertype,body:this._renderbody}),this.stateTransition(m.Establishing),Promise.resolve(this.sendInvite(e));const t={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.getOffer(t).then(s=>(this.outgoingRequestMessage.body={body:s.content,contentType:s.contentType},this.stateTransition(m.Establishing),this.sendInvite(e))).catch(s=>{throw this.logger.log(s.message),this.state!==m.Terminated&&this.stateTransition(m.Terminated),s})}sendInvite(e={}){return this.outgoingInviteRequest=this.userAgent.userAgentCore.invite(this.outgoingRequestMessage,{onAccept:t=>{if(this.dialog){this.logger.log("Additional confirmed dialog, sending ACK and BYE"),this.ackAndBye(t);return}if(this.isCanceled){this.logger.log("Canceled session accepted, sending ACK and BYE"),this.ackAndBye(t),this.stateTransition(m.Terminated);return}this.notifyReferer(t),this.onAccept(t).then(()=>{this.disposeEarlyMedia()}).catch(()=>{this.disposeEarlyMedia()}).then(()=>{e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(t)})},onProgress:t=>{this.isCanceled||(this.notifyReferer(t),this.onProgress(t).catch(()=>{this.disposeEarlyMedia()}).then(()=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(t)}))},onRedirect:t=>{this.notifyReferer(t),this.onRedirect(t),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(t)},onReject:t=>{this.notifyReferer(t),this.onReject(t),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(t)},onTrying:t=>{this.notifyReferer(t),this.onTrying(t),e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(t)}}),this.outgoingInviteRequest}disposeEarlyMedia(){this.earlyMediaSessionDescriptionHandlers.forEach(e=>{e.close()}),this.earlyMediaSessionDescriptionHandlers.clear()}notifyReferer(e){if(!this._referred)return;if(!(this._referred instanceof ue))throw new Error("Referred session not instance of session");if(!this._referred.dialog)return;if(!e.message.statusCode)throw new Error("Status code undefined.");if(!e.message.reasonPhrase)throw new Error("Reason phrase undefined.");const t=e.message.statusCode,s=e.message.reasonPhrase,i=`SIP/2.0 ${t} ${s}`.trim(),r=this._referred.dialog.notify(void 0,{extraHeaders:["Event: refer","Subscription-State: terminated"],body:{contentDisposition:"render",contentType:"message/sipfrag",content:i}});r.delegate={onReject:()=>{this._referred=void 0}}}onAccept(e){if(this.logger.log("Inviter.onAccept"),this.state!==m.Establishing)return this.logger.error(`Accept received while in state ${this.state}, dropping response`),Promise.reject(new Error(`Invalid session state ${this.state}`));const t=e.message,s=e.session;switch(t.hasHeader("P-Asserted-Identity")&&(this._assertedIdentity=D.nameAddrHeaderParse(t.getHeader("P-Asserted-Identity"))),s.delegate={onAck:i=>this.onAckRequest(i),onBye:i=>this.onByeRequest(i),onInfo:i=>this.onInfoRequest(i),onInvite:i=>this.onInviteRequest(i),onMessage:i=>this.onMessageRequest(i),onNotify:i=>this.onNotifyRequest(i),onPrack:i=>this.onPrackRequest(i),onRefer:i=>this.onReferRequest(i)},this._dialog=s,s.signalingState){case v.Initial:return this.logger.error("Received 2xx response to INVITE without a session description"),this.ackAndBye(e,400,"Missing session description"),this.stateTransition(m.Terminated),Promise.reject(new Error("Bad Media Description"));case v.HaveLocalOffer:return this.logger.error("Received 2xx response to INVITE without a session description"),this.ackAndBye(e,400,"Missing session description"),this.stateTransition(m.Terminated),Promise.reject(new Error("Bad Media Description"));case v.HaveRemoteOffer:{if(!this._dialog.offer)throw new Error(`Session offer undefined in signaling state ${this._dialog.signalingState}.`);const i={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setOfferAndGetAnswer(this._dialog.offer,i).then(r=>{e.ack({body:r}),this.stateTransition(m.Established)}).catch(r=>{throw this.ackAndBye(e,488,"Invalid session description"),this.stateTransition(m.Terminated),r})}case v.Stable:{if(this.earlyMediaSessionDescriptionHandlers.size>0){const n=this.earlyMediaSessionDescriptionHandlers.get(s.id);if(!n)throw new Error("Session description handler undefined.");return this.setSessionDescriptionHandler(n),this.earlyMediaSessionDescriptionHandlers.delete(s.id),e.ack(),this.stateTransition(m.Established),Promise.resolve()}if(this.earlyMediaDialog){if(this.earlyMediaDialog!==s){this.earlyMedia&&this.logger.error("You have set the 'earlyMedia' option to 'true' which requires that your INVITE requests do not fork and yet this INVITE request did in fact fork. Consequentially and not surprisingly the end point which accepted the INVITE (confirmed dialog) does not match the end point with which early media has been setup (early dialog) and thus this session is unable to proceed. In accordance with the SIP specifications, the SIP servers your end point is connected to determine if an INVITE forks and the forking behavior of those servers cannot be controlled by this library. If you wish to use early media with this library you must configure those servers accordingly. Alternatively you may set the 'earlyMedia' to 'false' which will allow this library to function with any INVITE requests which do fork.");const n=new Error("Early media dialog does not equal confirmed dialog, terminating session");return this.logger.error(n.message),this.ackAndBye(e,488,"Not Acceptable Here"),this.stateTransition(m.Terminated),Promise.reject(n)}return e.ack(),this.stateTransition(m.Established),Promise.resolve()}const i=s.answer;if(!i)throw new Error("Answer is undefined.");const r={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setAnswer(i,r).then(()=>{let n;this._renderbody&&this._rendertype&&(n={body:{contentDisposition:"render",contentType:this._rendertype,content:this._renderbody}}),e.ack(n),this.stateTransition(m.Established)}).catch(n=>{throw this.logger.error(n.message),this.ackAndBye(e,488,"Not Acceptable Here"),this.stateTransition(m.Terminated),n})}case v.Closed:return Promise.reject(new Error("Terminated."));default:throw new Error("Unknown session signaling state.")}}onProgress(e){var t;if(this.logger.log("Inviter.onProgress"),this.state!==m.Establishing)return this.logger.error(`Progress received while in state ${this.state}, dropping response`),Promise.reject(new Error(`Invalid session state ${this.state}`));if(!this.outgoingInviteRequest)throw new Error("Outgoing INVITE request undefined.");const s=e.message,i=e.session;s.hasHeader("P-Asserted-Identity")&&(this._assertedIdentity=D.nameAddrHeaderParse(s.getHeader("P-Asserted-Identity")));const r=s.getHeader("require"),n=s.getHeader("rseq"),d=!!(r&&r.includes("100rel")&&n?Number(n):void 0),p=[];switch(d&&p.push("RAck: "+s.getHeader("rseq")+" "+s.getHeader("cseq")),i.signalingState){case v.Initial:return d&&(this.logger.warn("First reliable provisional response received MUST contain an offer when INVITE does not contain an offer."),e.prack({extraHeaders:p})),Promise.resolve();case v.HaveLocalOffer:return d&&e.prack({extraHeaders:p}),Promise.resolve();case v.HaveRemoteOffer:if(!d)return this.logger.warn("Non-reliable provisional response MUST NOT contain an initial offer, discarding response."),Promise.resolve();{const g=this.sessionDescriptionHandlerFactory(this,this.userAgent.configuration.sessionDescriptionHandlerFactoryOptions||{});return!((t=this.delegate)===null||t===void 0)&&t.onSessionDescriptionHandler&&this.delegate.onSessionDescriptionHandler(g,!0),this.earlyMediaSessionDescriptionHandlers.set(i.id,g),g.setDescription(s.body,this.sessionDescriptionHandlerOptions,this.sessionDescriptionHandlerModifiers).then(()=>g.getDescription(this.sessionDescriptionHandlerOptions,this.sessionDescriptionHandlerModifiers)).then(w=>{const S={contentDisposition:"session",contentType:w.contentType,content:w.body};e.prack({extraHeaders:p,body:S})}).catch(w=>{throw this.stateTransition(m.Terminated),w})}case v.Stable:if(d&&e.prack({extraHeaders:p}),this.earlyMedia&&!this.earlyMediaDialog){this.earlyMediaDialog=i;const g=i.answer;if(!g)throw new Error("Answer is undefined.");const w={sessionDescriptionHandlerModifiers:this.sessionDescriptionHandlerModifiers,sessionDescriptionHandlerOptions:this.sessionDescriptionHandlerOptions};return this.setAnswer(g,w).catch(S=>{throw this.stateTransition(m.Terminated),S})}return Promise.resolve();case v.Closed:return Promise.reject(new Error("Terminated."));default:throw new Error("Unknown session signaling state.")}}onRedirect(e){if(this.logger.log("Inviter.onRedirect"),this.state!==m.Establishing&&this.state!==m.Terminating){this.logger.error(`Redirect received while in state ${this.state}, dropping response`);return}this.stateTransition(m.Terminated)}onReject(e){if(this.logger.log("Inviter.onReject"),this.state!==m.Establishing&&this.state!==m.Terminating){this.logger.error(`Reject received while in state ${this.state}, dropping response`);return}this.stateTransition(m.Terminated)}onTrying(e){if(this.logger.log("Inviter.onTrying"),this.state!==m.Establishing){this.logger.error(`Trying received while in state ${this.state}, dropping response`);return}}}class St{constructor(e,t,s,i="text/plain",r={}){this.logger=e.getLogger("sip.Messager"),r.params=r.params||{};let n=e.userAgentCore.configuration.aor;if(r.params.fromUri&&(n=typeof r.params.fromUri=="string"?D.URIParse(r.params.fromUri):r.params.fromUri),!n)throw new TypeError("Invalid from URI: "+r.params.fromUri);let o=t;if(r.params.toUri&&(o=typeof r.params.toUri=="string"?D.URIParse(r.params.toUri):r.params.toUri),!o)throw new TypeError("Invalid to URI: "+r.params.toUri);const d=r.params?Object.assign({},r.params):{},p=(r.extraHeaders||[]).slice(),w={contentDisposition:"render",contentType:i,content:s};this.request=e.userAgentCore.makeOutgoingRequestMessage(y.MESSAGE,t,n,o,d,p,w),this.userAgent=e}message(e={}){return this.userAgent.userAgentCore.request(this.request,e.requestDelegate),Promise.resolve()}}var x;(function(a){a.Initial="Initial",a.Registered="Registered",a.Unregistered="Unregistered",a.Terminated="Terminated"})(x=x||(x={}));class Y{constructor(e,t={}){this.disposed=!1,this._contacts=[],this._retryAfter=void 0,this._state=x.Initial,this._waiting=!1,this._stateEventEmitter=new me,this._waitingEventEmitter=new me,this.userAgent=e;const s=e.configuration.uri.clone();if(s.user=void 0,this.options=Object.assign(Object.assign(Object.assign({},Y.defaultOptions()),{registrar:s}),Y.stripUndefinedProperties(t)),this.options.extraContactHeaderParams=(this.options.extraContactHeaderParams||[]).slice(),this.options.extraHeaders=(this.options.extraHeaders||[]).slice(),!this.options.registrar)throw new Error("Registrar undefined.");if(this.options.registrar=this.options.registrar.clone(),this.options.regId&&!this.options.instanceId?this.options.instanceId=this.userAgent.instanceId:!this.options.regId&&this.options.instanceId&&(this.options.regId=1),this.options.instanceId&&D.parse(this.options.instanceId,"uuid")===-1)throw new Error("Invalid instanceId.");if(this.options.regId&&this.options.regId<0)throw new Error("Invalid regId.");const i=this.options.registrar,r=this.options.params&&this.options.params.fromUri||e.userAgentCore.configuration.aor,n=this.options.params&&this.options.params.toUri||e.configuration.uri,o=this.options.params||{},d=(t.extraHeaders||[]).slice();if(this.request=e.userAgentCore.makeOutgoingRequestMessage(y.REGISTER,i,r,n,o,d,void 0),this.expires=this.options.expires||Y.defaultExpires,this.expires<0)throw new Error("Invalid expires.");if(this.refreshFrequency=this.options.refreshFrequency||Y.defaultRefreshFrequency,this.refreshFrequency<50||this.refreshFrequency>99)throw new Error("Invalid refresh frequency. The value represents a percentage of the expiration time and should be between 50 and 99.");this.logger=e.getLogger("sip.Registerer"),this.options.logConfiguration&&(this.logger.log("Configuration:"),Object.keys(this.options).forEach(p=>{const g=this.options[p];p==="registrar"?this.logger.log("· "+p+": "+g):this.logger.log("· "+p+": "+JSON.stringify(g))})),this.id=this.request.callId+this.request.from.parameters.tag,this.userAgent._registerers[this.id]=this}static defaultOptions(){return{expires:Y.defaultExpires,extraContactHeaderParams:[],extraHeaders:[],logConfiguration:!0,instanceId:"",params:{},regId:0,registrar:new K("sip","anonymous","anonymous.invalid"),refreshFrequency:Y.defaultRefreshFrequency}}static stripUndefinedProperties(e){return Object.keys(e).reduce((t,s)=>(e[s]!==void 0&&(t[s]=e[s]),t),{})}get contacts(){return this._contacts.slice()}get retryAfter(){return this._retryAfter}get state(){return this._state}get stateChange(){return this._stateEventEmitter}dispose(){return this.disposed?Promise.resolve():(this.disposed=!0,this.logger.log(`Registerer ${this.id} in state ${this.state} is being disposed`),delete this.userAgent._registerers[this.id],new Promise(e=>{const t=()=>{if(!this.waiting&&this._state===x.Registered){this.stateChange.addListener(()=>{this.terminated(),e()},{once:!0}),this.unregister();return}this.terminated(),e()};this.waiting?this.waitingChange.addListener(()=>{t()},{once:!0}):t()}))}register(e={}){if(this.state===x.Terminated)throw this.stateError(),new Error("Registerer terminated. Unable to register.");if(this.disposed)throw this.stateError(),new Error("Registerer disposed. Unable to register.");if(this.waiting){this.waitingWarning();const i=new fe("REGISTER request already in progress, waiting for final response");return Promise.reject(i)}e.requestOptions&&(this.options=Object.assign(Object.assign({},this.options),e.requestOptions));const t=(this.options.extraHeaders||[]).slice();t.push("Contact: "+this.generateContactHeader(this.expires)),t.push("Allow: "+["ACK","CANCEL","INVITE","MESSAGE","BYE","OPTIONS","INFO","NOTIFY","REFER"].toString()),this.request.cseq++,this.request.setHeader("cseq",this.request.cseq+" REGISTER"),this.request.extraHeaders=t,this.waitingToggle(!0);const s=this.userAgent.userAgentCore.register(this.request,{onAccept:i=>{let r;i.message.hasHeader("expires")&&(r=Number(i.message.getHeader("expires"))),this._contacts=i.message.getHeaders("contact");let n=this._contacts.length;if(!n){this.logger.error("No Contact header in response to REGISTER, dropping response."),this.unregistered();return}let o;for(;n--;){if(o=i.message.parseHeader("contact",n),!o)throw new Error("Contact undefined");if(this.userAgent.contact.pubGruu&&Be(o.uri,this.userAgent.contact.pubGruu)){r=Number(o.getParam("expires"));break}if(this.userAgent.configuration.contactName===""){if(o.uri.user===this.userAgent.contact.uri.user){r=Number(o.getParam("expires"));break}}else if(Be(o.uri,this.userAgent.contact.uri)){r=Number(o.getParam("expires"));break}o=void 0}if(o===void 0){this.logger.error("No Contact header pointing to us, dropping response"),this.unregistered(),this.waitingToggle(!1);return}if(r===void 0){this.logger.error("Contact pointing to us is missing expires parameter, dropping response"),this.unregistered(),this.waitingToggle(!1);return}if(o.hasParam("temp-gruu")){const d=o.getParam("temp-gruu");d&&(this.userAgent.contact.tempGruu=D.URIParse(d.replace(/"/g,"")))}if(o.hasParam("pub-gruu")){const d=o.getParam("pub-gruu");d&&(this.userAgent.contact.pubGruu=D.URIParse(d.replace(/"/g,"")))}this.registered(r),e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(i),this.waitingToggle(!1)},onProgress:i=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(i)},onRedirect:i=>{this.logger.error("Redirect received. Not supported."),this.unregistered(),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(i),this.waitingToggle(!1)},onReject:i=>{if(i.message.statusCode===423){if(!i.message.hasHeader("min-expires")){this.logger.error("423 response received for REGISTER without Min-Expires, dropping response"),this.unregistered(),this.waitingToggle(!1);return}this.expires=Number(i.message.getHeader("min-expires")),this.waitingToggle(!1),this.register();return}this.logger.warn(`Failed to register, status code ${i.message.statusCode}`);let r=NaN;if(i.message.statusCode===500||i.message.statusCode===503){const n=i.message.getHeader("retry-after");n&&(r=Number.parseInt(n,void 0))}this._retryAfter=isNaN(r)?void 0:r,this.unregistered(),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(i),this._retryAfter=void 0,this.waitingToggle(!1)},onTrying:i=>{e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(i)}});return Promise.resolve(s)}unregister(e={}){if(this.state===x.Terminated)throw this.stateError(),new Error("Registerer terminated. Unable to register.");if(this.disposed&&this.state!==x.Registered)throw this.stateError(),new Error("Registerer disposed. Unable to register.");if(this.waiting){this.waitingWarning();const i=new fe("REGISTER request already in progress, waiting for final response");return Promise.reject(i)}this._state!==x.Registered&&!e.all&&this.logger.warn("Not currently registered, but sending an unregister anyway.");const t=(e.requestOptions&&e.requestOptions.extraHeaders||[]).slice();this.request.extraHeaders=t,e.all?(t.push("Contact: *"),t.push("Expires: 0")):t.push("Contact: "+this.generateContactHeader(0)),this.request.cseq++,this.request.setHeader("cseq",this.request.cseq+" REGISTER"),this.registrationTimer!==void 0&&(clearTimeout(this.registrationTimer),this.registrationTimer=void 0),this.waitingToggle(!0);const s=this.userAgent.userAgentCore.register(this.request,{onAccept:i=>{this._contacts=i.message.getHeaders("contact"),this.unregistered(),e.requestDelegate&&e.requestDelegate.onAccept&&e.requestDelegate.onAccept(i),this.waitingToggle(!1)},onProgress:i=>{e.requestDelegate&&e.requestDelegate.onProgress&&e.requestDelegate.onProgress(i)},onRedirect:i=>{this.logger.error("Unregister redirected. Not currently supported."),this.unregistered(),e.requestDelegate&&e.requestDelegate.onRedirect&&e.requestDelegate.onRedirect(i),this.waitingToggle(!1)},onReject:i=>{this.logger.error(`Unregister rejected with status code ${i.message.statusCode}`),this.unregistered(),e.requestDelegate&&e.requestDelegate.onReject&&e.requestDelegate.onReject(i),this.waitingToggle(!1)},onTrying:i=>{e.requestDelegate&&e.requestDelegate.onTrying&&e.requestDelegate.onTrying(i)}});return Promise.resolve(s)}clearTimers(){this.registrationTimer!==void 0&&(clearTimeout(this.registrationTimer),this.registrationTimer=void 0),this.registrationExpiredTimer!==void 0&&(clearTimeout(this.registrationExpiredTimer),this.registrationExpiredTimer=void 0)}generateContactHeader(e){let t=this.userAgent.contact.toString({register:!0});return this.options.regId&&this.options.instanceId&&(t+=";reg-id="+this.options.regId,t+=';+sip.instance="<urn:uuid:'+this.options.instanceId+'>"'),this.options.extraContactHeaderParams&&this.options.extraContactHeaderParams.forEach(s=>{t+=";"+s}),t+=";expires="+e,t}registered(e){this.clearTimers(),this.registrationTimer=setTimeout(()=>{this.registrationTimer=void 0,this.register()},this.refreshFrequency/100*e*1e3),this.registrationExpiredTimer=setTimeout(()=>{this.logger.warn("Registration expired"),this.unregistered()},e*1e3),this._state!==x.Registered&&this.stateTransition(x.Registered)}unregistered(){this.clearTimers(),this._state!==x.Unregistered&&this.stateTransition(x.Unregistered)}terminated(){this.clearTimers(),this._state!==x.Terminated&&this.stateTransition(x.Terminated)}stateTransition(e){const t=()=>{throw new Error(`Invalid state transition from ${this._state} to ${e}`)};switch(this._state){case x.Initial:e!==x.Registered&&e!==x.Unregistered&&e!==x.Terminated&&t();break;case x.Registered:e!==x.Unregistered&&e!==x.Terminated&&t();break;case x.Unregistered:e!==x.Registered&&e!==x.Terminated&&t();break;case x.Terminated:t();break;default:throw new Error("Unrecognized state.")}this._state=e,this.logger.log(`Registration transitioned to state ${this._state}`),this._stateEventEmitter.emit(this._state),e===x.Terminated&&this.dispose()}get waiting(){return this._waiting}get waitingChange(){return this._waitingEventEmitter}waitingToggle(e){if(this._waiting===e)throw new Error(`Invalid waiting transition from ${this._waiting} to ${e}`);this._waiting=e,this.logger.log(`Waiting toggled to ${this._waiting}`),this._waitingEventEmitter.emit(this._waiting)}waitingWarning(){let e="An attempt was made to send a REGISTER request while a prior one was still in progress.";e+=" RFC 3261 requires UAs MUST NOT send a new registration until they have received a final response",e+=" from the registrar for the previous one or the previous REGISTER request has timed out.",e+=" Note that if the transport disconnects, you still must wait for the prior request to time out before",e+=" sending a new REGISTER request or alternatively dispose of the current Registerer and create a new Registerer.",this.logger.warn(e)}stateError(){let t=`An attempt was made to send a REGISTER request when the Registerer ${this.state===x.Terminated?"is in 'Terminated' state":"has been disposed"}.`;t+=" The Registerer transitions to 'Terminated' when Registerer.dispose() is called.",t+=" Perhaps you called UserAgent.stop() which dipsoses of all Registerers?",this.logger.error(t)}}Y.defaultExpires=600,Y.defaultRefreshFrequency=99;var R;(function(a){a.Initial="Initial",a.NotifyWait="NotifyWait",a.Pending="Pending",a.Active="Active",a.Terminated="Terminated"})(R=R||(R={}));var T;(function(a){a.Connecting="Connecting",a.Connected="Connected",a.Disconnecting="Disconnecting",a.Disconnected="Disconnected"})(T=T||(T={}));var k;(function(a){a.Started="Started",a.Stopped="Stopped"})(k=k||(k={}));class P{constructor(){this._dataLength=0,this._bufferLength=0,this._state=new Int32Array(4),this._buffer=new ArrayBuffer(68),this._buffer8=new Uint8Array(this._buffer,0,68),this._buffer32=new Uint32Array(this._buffer,0,17),this.start()}static hashStr(e,t=!1){return this.onePassHasher.start().appendStr(e).end(t)}static hashAsciiStr(e,t=!1){return this.onePassHasher.start().appendAsciiStr(e).end(t)}static _hex(e){const t=P.hexChars,s=P.hexOut;let i,r,n,o;for(o=0;o<4;o+=1)for(r=o*8,i=e[o],n=0;n<8;n+=2)s[r+1+n]=t.charAt(i&15),i>>>=4,s[r+0+n]=t.charAt(i&15),i>>>=4;return s.join("")}static _md5cycle(e,t){let s=e[0],i=e[1],r=e[2],n=e[3];s+=(i&r|~i&n)+t[0]-680876936|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[1]-389564586|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[2]+606105819|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[3]-1044525330|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[4]-176418897|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[5]+1200080426|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[6]-1473231341|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[7]-45705983|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[8]+1770035416|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[9]-1958414417|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[10]-42063|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[11]-1990404162|0,i=(i<<22|i>>>10)+r|0,s+=(i&r|~i&n)+t[12]+1804603682|0,s=(s<<7|s>>>25)+i|0,n+=(s&i|~s&r)+t[13]-40341101|0,n=(n<<12|n>>>20)+s|0,r+=(n&s|~n&i)+t[14]-1502002290|0,r=(r<<17|r>>>15)+n|0,i+=(r&n|~r&s)+t[15]+1236535329|0,i=(i<<22|i>>>10)+r|0,s+=(i&n|r&~n)+t[1]-165796510|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[6]-1069501632|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[11]+643717713|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[0]-373897302|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[5]-701558691|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[10]+38016083|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[15]-660478335|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[4]-405537848|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[9]+568446438|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[14]-1019803690|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[3]-187363961|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[8]+1163531501|0,i=(i<<20|i>>>12)+r|0,s+=(i&n|r&~n)+t[13]-1444681467|0,s=(s<<5|s>>>27)+i|0,n+=(s&r|i&~r)+t[2]-51403784|0,n=(n<<9|n>>>23)+s|0,r+=(n&i|s&~i)+t[7]+1735328473|0,r=(r<<14|r>>>18)+n|0,i+=(r&s|n&~s)+t[12]-1926607734|0,i=(i<<20|i>>>12)+r|0,s+=(i^r^n)+t[5]-378558|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[8]-2022574463|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[11]+1839030562|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[14]-35309556|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[1]-1530992060|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[4]+1272893353|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[7]-155497632|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[10]-1094730640|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[13]+681279174|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[0]-358537222|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[3]-722521979|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[6]+76029189|0,i=(i<<23|i>>>9)+r|0,s+=(i^r^n)+t[9]-640364487|0,s=(s<<4|s>>>28)+i|0,n+=(s^i^r)+t[12]-421815835|0,n=(n<<11|n>>>21)+s|0,r+=(n^s^i)+t[15]+530742520|0,r=(r<<16|r>>>16)+n|0,i+=(r^n^s)+t[2]-995338651|0,i=(i<<23|i>>>9)+r|0,s+=(r^(i|~n))+t[0]-198630844|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[7]+1126891415|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[14]-1416354905|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[5]-57434055|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[12]+1700485571|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[3]-1894986606|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[10]-1051523|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[1]-2054922799|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[8]+1873313359|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[15]-30611744|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[6]-1560198380|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[13]+1309151649|0,i=(i<<21|i>>>11)+r|0,s+=(r^(i|~n))+t[4]-145523070|0,s=(s<<6|s>>>26)+i|0,n+=(i^(s|~r))+t[11]-1120210379|0,n=(n<<10|n>>>22)+s|0,r+=(s^(n|~i))+t[2]+718787259|0,r=(r<<15|r>>>17)+n|0,i+=(n^(r|~s))+t[9]-343485551|0,i=(i<<21|i>>>11)+r|0,e[0]=s+e[0]|0,e[1]=i+e[1]|0,e[2]=r+e[2]|0,e[3]=n+e[3]|0}start(){return this._dataLength=0,this._bufferLength=0,this._state.set(P.stateIdentity),this}appendStr(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n;for(n=0;n<e.length;n+=1){if(r=e.charCodeAt(n),r<128)t[i++]=r;else if(r<2048)t[i++]=(r>>>6)+192,t[i++]=r&63|128;else if(r<55296||r>56319)t[i++]=(r>>>12)+224,t[i++]=r>>>6&63|128,t[i++]=r&63|128;else{if(r=(r-55296)*1024+(e.charCodeAt(++n)-56320)+65536,r>1114111)throw new Error("Unicode standard supports code points up to U+10FFFF");t[i++]=(r>>>18)+240,t[i++]=r>>>12&63|128,t[i++]=r>>>6&63|128,t[i++]=r&63|128}i>=64&&(this._dataLength+=64,P._md5cycle(this._state,s),i-=64,s[0]=s[16])}return this._bufferLength=i,this}appendAsciiStr(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n=0;for(;;){for(r=Math.min(e.length-n,64-i);r--;)t[i++]=e.charCodeAt(n++);if(i<64)break;this._dataLength+=64,P._md5cycle(this._state,s),i=0}return this._bufferLength=i,this}appendByteArray(e){const t=this._buffer8,s=this._buffer32;let i=this._bufferLength,r,n=0;for(;;){for(r=Math.min(e.length-n,64-i);r--;)t[i++]=e[n++];if(i<64)break;this._dataLength+=64,P._md5cycle(this._state,s),i=0}return this._bufferLength=i,this}getState(){const e=this,t=e._state;return{buffer:String.fromCharCode.apply(null,e._buffer8),buflen:e._bufferLength,length:e._dataLength,state:[t[0],t[1],t[2],t[3]]}}setState(e){const t=e.buffer,s=e.state,i=this._state;let r;for(this._dataLength=e.length,this._bufferLength=e.buflen,i[0]=s[0],i[1]=s[1],i[2]=s[2],i[3]=s[3],r=0;r<t.length;r+=1)this._buffer8[r]=t.charCodeAt(r)}end(e=!1){const t=this._bufferLength,s=this._buffer8,i=this._buffer32,r=(t>>2)+1;let n;if(this._dataLength+=t,s[t]=128,s[t+1]=s[t+2]=s[t+3]=0,i.set(P.buffer32Identity.subarray(r),r),t>55&&(P._md5cycle(this._state,i),i.set(P.buffer32Identity)),n=this._dataLength*8,n<=4294967295)i[14]=n;else{const o=n.toString(16).match(/(.*?)(.{0,8})$/);if(o===null)return;const d=parseInt(o[2],16),p=parseInt(o[1],16)||0;i[14]=d,i[15]=p}return P._md5cycle(this._state,i),e?this._state:P._hex(this._state)}}P.stateIdentity=new Int32Array([1732584193,-271733879,-1732584194,271733878]),P.buffer32Identity=new Int32Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),P.hexChars="0123456789abcdef",P.hexOut=[],P.onePassHasher=new P,P.hashStr("hello")!=="5d41402abc4b2a76b9719d911017c592"&&console.error("Md5 self test failed.");function se(a){return P.hashStr(a)}class Tt{constructor(e,t,s,i){this.logger=e.getLogger("sipjs.digestauthentication"),this.username=s,this.password=i,this.ha1=t,this.nc=0,this.ncHex="00000000"}authenticate(e,t,s){if(this.algorithm=t.algorithm,this.realm=t.realm,this.nonce=t.nonce,this.opaque=t.opaque,this.stale=t.stale,this.algorithm){if(this.algorithm!=="MD5")return this.logger.warn("challenge with Digest algorithm different than 'MD5', authentication aborted"),!1}else this.algorithm="MD5";if(!this.realm)return this.logger.warn("challenge without Digest realm, authentication aborted"),!1;if(!this.nonce)return this.logger.warn("challenge without Digest nonce, authentication aborted"),!1;if(t.qop)if(t.qop.indexOf("auth")>-1)this.qop="auth";else if(t.qop.indexOf("auth-int")>-1)this.qop="auth-int";else return this.logger.warn("challenge without Digest qop different than 'auth' or 'auth-int', authentication aborted"),!1;else this.qop=void 0;return this.method=e.method,this.uri=e.ruri,this.cnonce=oe(12),this.nc+=1,this.updateNcHex(),this.nc===4294967296&&(this.nc=1,this.ncHex="00000001"),this.calculateResponse(s),!0}toString(){const e=[];if(!this.response)throw new Error("response field does not exist, cannot generate Authorization header");return e.push("algorithm="+this.algorithm),e.push('username="'+this.username+'"'),e.push('realm="'+this.realm+'"'),e.push('nonce="'+this.nonce+'"'),e.push('uri="'+this.uri+'"'),e.push('response="'+this.response+'"'),this.opaque&&e.push('opaque="'+this.opaque+'"'),this.qop&&(e.push("qop="+this.qop),e.push('cnonce="'+this.cnonce+'"'),e.push("nc="+this.ncHex)),"Digest "+e.join(", ")}updateNcHex(){const e=Number(this.nc).toString(16);this.ncHex="00000000".substr(0,8-e.length)+e}calculateResponse(e){let t,s;t=this.ha1,(t===""||t===void 0)&&(t=se(this.username+":"+this.realm+":"+this.password)),this.qop==="auth"?(s=se(this.method+":"+this.uri),this.response=se(t+":"+this.nonce+":"+this.ncHex+":"+this.cnonce+":auth:"+s)):this.qop==="auth-int"?(s=se(this.method+":"+this.uri+":"+se(e||"")),this.response=se(t+":"+this.nonce+":"+this.ncHex+":"+this.cnonce+":auth-int:"+s)):this.qop===void 0&&(s=se(this.method+":"+this.uri),this.response=se(t+":"+this.nonce+":"+s))}}var M;(function(a){a[a.error=0]="error",a[a.warn=1]="warn",a[a.log=2]="log",a[a.debug=3]="debug"})(M=M||(M={}));class Ye{constructor(e,t,s){this.logger=e,this.category=t,this.label=s}error(e){this.genericLog(M.error,e)}warn(e){this.genericLog(M.warn,e)}log(e){this.genericLog(M.log,e)}debug(e){this.genericLog(M.debug,e)}genericLog(e,t){this.logger.genericLog(e,this.category,this.label,t)}get level(){return this.logger.level}set level(e){this.logger.level=e}}class Et{constructor(){this.builtinEnabled=!0,this._level=M.log,this.loggers={},this.logger=this.getLogger("sip:loggerfactory")}get level(){return this._level}set level(e){e>=0&&e<=3?this._level=e:e>3?this._level=3:M.hasOwnProperty(e)?this._level=e:this.logger.error("invalid 'level' parameter value: "+JSON.stringify(e))}get connector(){return this._connector}set connector(e){e?typeof e=="function"?this._connector=e:this.logger.error("invalid 'connector' parameter value: "+JSON.stringify(e)):this._connector=void 0}getLogger(e,t){if(t&&this.level===3)return new Ye(this,e,t);if(this.loggers[e])return this.loggers[e];{const s=new Ye(this,e);return this.loggers[e]=s,s}}genericLog(e,t,s,i){this.level>=e&&this.builtinEnabled&&this.print(e,t,s,i),this.connector&&this.connector(M[e],t,s,i)}print(e,t,s,i){if(typeof i=="string"){const r=[new Date,t];s&&r.push(s),i=r.concat(i).join(" | ")}switch(e){case M.error:console.error(i);break;case M.warn:console.warn(i);break;case M.log:console.log(i);break;case M.debug:console.debug(i);break}}}var xe;(function(a){function e(i,r){let n=r,o=0,d=0;if(i.substring(n,n+2).match(/(^\r\n)/))return-2;for(;o===0;){if(d=i.indexOf(`\r
23
23
  `,n),d===-1)return d;!i.substring(d+2,d+4).match(/(^\r\n)/)&&i.charAt(d+2).match(/(^\s+)/)?n=d+2:o=d}return o}a.getHeader=e;function t(i,r,n,o){const d=r.indexOf(":",n),p=r.substring(n,d).trim(),g=r.substring(d+1,o).trim();let w;switch(p.toLowerCase()){case"via":case"v":i.addHeader("via",g),i.getHeaders("via").length===1?(w=i.parseHeader("Via"),w&&(i.via=w,i.viaBranch=w.branch)):w=0;break;case"from":case"f":i.setHeader("from",g),w=i.parseHeader("from"),w&&(i.from=w,i.fromTag=w.getParam("tag"));break;case"to":case"t":i.setHeader("to",g),w=i.parseHeader("to"),w&&(i.to=w,i.toTag=w.getParam("tag"));break;case"record-route":if(w=D.parse(g,"Record_Route"),w===-1){w=void 0;break}if(!(w instanceof Array)){w=void 0;break}w.forEach(S=>{i.addHeader("record-route",g.substring(S.position,S.offset)),i.headers["Record-Route"][i.getHeaders("record-route").length-1].parsed=S.parsed});break;case"call-id":case"i":i.setHeader("call-id",g),w=i.parseHeader("call-id"),w&&(i.callId=g);break;case"contact":case"m":if(w=D.parse(g,"Contact"),w===-1){w=void 0;break}if(!(w instanceof Array)){w=void 0;break}w.forEach(S=>{i.addHeader("contact",g.substring(S.position,S.offset)),i.headers.Contact[i.getHeaders("contact").length-1].parsed=S.parsed});break;case"content-length":case"l":i.setHeader("content-length",g),w=i.parseHeader("content-length");break;case"content-type":case"c":i.setHeader("content-type",g),w=i.parseHeader("content-type");break;case"cseq":i.setHeader("cseq",g),w=i.parseHeader("cseq"),w&&(i.cseq=w.value),i instanceof Q&&(i.method=w.method);break;case"max-forwards":i.setHeader("max-forwards",g),w=i.parseHeader("max-forwards");break;case"www-authenticate":i.setHeader("www-authenticate",g),w=i.parseHeader("www-authenticate");break;case"proxy-authenticate":i.setHeader("proxy-authenticate",g),w=i.parseHeader("proxy-authenticate");break;case"refer-to":case"r":i.setHeader("refer-to",g),w=i.parseHeader("refer-to"),w&&(i.referTo=w);break;default:i.addHeader(p.toLowerCase(),g),w=0}return w===void 0?{error:"error parsing header '"+p+"'"}:!0}a.parseHeader=t;function s(i,r){let n=0,o=i.indexOf(`\r
24
24
  `);if(o===-1){r.warn("no CRLF found, not a SIP message, discarded");return}const d=i.substring(0,o),p=D.parse(d,"Request_Response");let g;if(p===-1){r.warn('error parsing first line of SIP message: "'+d+'"');return}else p.status_code?(g=new Q,g.statusCode=p.status_code,g.reasonPhrase=p.reason_phrase):(g=new he,g.method=p.method,g.ruri=p.uri);g.data=i,n=o+2;let w;for(;;){if(o=e(i,n),o===-2){w=n+2;break}else if(o===-1){r.error("malformed message");return}const S=t(g,i,n,o);if(S&&S!==!0){r.error(S.error);return}n=o+2}return g.hasHeader("content-length")?g.body=i.substr(w,Number(g.getHeader("content-length"))):g.body=i.substring(w),g}a.parseMessage=s})(xe=xe||(xe={}));function ze(a,e){if(e.statusCode<100||e.statusCode>699)throw new TypeError("Invalid statusCode: "+e.statusCode);const s=e.reasonPhrase?e.reasonPhrase:Se(e.statusCode);let i="SIP/2.0 "+e.statusCode+" "+s+`\r
25
25
  `;e.statusCode>=100&&e.statusCode<200,e.statusCode;const r="From: "+a.getHeader("From")+`\r
@@ -45,7 +45,7 @@ var EmbeddedCallWidgetRuntimeBundle=(function($e){"use strict";const dt="0.21.1"
45
45
  `,p+=`Max-Forwards: 70\r
46
46
  `,p+=`Content-Length: 0\r
47
47
  \r
48
- `,this.send(p).catch(g=>{this.logTransportError(g,"Failed to send ACK to non-2xx response.")})}stateTransition(e,t=!1){const s=()=>{throw new Error(`Invalid state transition from ${this.state} to ${e}`)};switch(e){case u.Calling:s();break;case u.Proceeding:this.state!==u.Calling&&s();break;case u.Accepted:case u.Completed:this.state!==u.Calling&&this.state!==u.Proceeding&&s();break;case u.Terminated:this.state!==u.Calling&&this.state!==u.Accepted&&this.state!==u.Completed&&(t||s());break;default:s()}this.B&&(clearTimeout(this.B),this.B=void 0),u.Proceeding,e===u.Completed&&(this.D=setTimeout(()=>this.timerD(),H.TIMER_D)),e===u.Accepted&&(this.M=setTimeout(()=>this.timerM(),H.TIMER_M)),e===u.Terminated&&this.dispose(),this.setState(e)}timerA(){}timerB(){this.logger.debug(`Timer B expired for INVITE client transaction ${this.id}.`),this.state===u.Calling&&(this.onRequestTimeout(),this.stateTransition(u.Terminated))}timerD(){this.logger.debug(`Timer D expired for INVITE client transaction ${this.id}.`),this.state===u.Completed&&this.stateTransition(u.Terminated)}timerM(){this.logger.debug(`Timer M expired for INVITE client transaction ${this.id}.`),this.state===u.Accepted&&this.stateTransition(u.Terminated)}}class q{constructor(e,t,s,i){this.transactionConstructor=e,this.core=t,this.message=s,this.delegate=i,this.challenged=!1,this.stale=!1,this.logger=this.loggerFactory.getLogger("sip.user-agent-client"),this.init()}dispose(){this.transaction.dispose()}get loggerFactory(){return this.core.loggerFactory}get transaction(){if(!this._transaction)throw new Error("Transaction undefined.");return this._transaction}cancel(e,t={}){if(!this.transaction)throw new Error("Transaction undefined.");if(!this.message.to)throw new Error("To undefined.");if(!this.message.from)throw new Error("From undefined.");const s=this.core.makeOutgoingRequestMessage(y.CANCEL,this.message.ruri,this.message.from.uri,this.message.to.uri,{toTag:this.message.toTag,fromTag:this.message.fromTag,callId:this.message.callId,cseq:this.message.cseq},t.extraHeaders);return s.branch=this.message.branch,this.message.headers.Route&&(s.headers.Route=this.message.headers.Route),e&&s.setHeader("Reason",e),this.transaction.state===u.Proceeding?new q(U,this.core,s):this.transaction.addStateChangeListener(()=>{this.transaction&&this.transaction.state===u.Proceeding&&new q(U,this.core,s)},{once:!0}),s}authenticationGuard(e,t){const s=e.statusCode;if(!s)throw new Error("Response status code undefined.");if(s!==401&&s!==407)return!0;let i,r;if(s===401?(i=e.parseHeader("www-authenticate"),r="authorization"):(i=e.parseHeader("proxy-authenticate"),r="proxy-authorization"),!i)return this.logger.warn(s+" with wrong or missing challenge, cannot authenticate"),!0;if(this.challenged&&(this.stale||i.stale!==!0))return this.logger.warn(s+" apparently in authentication loop, cannot authenticate"),!0;if(!this.credentials&&(this.credentials=this.core.configuration.authenticationFactory(),!this.credentials))return this.logger.warn("Unable to obtain credentials, cannot authenticate"),!0;if(!this.credentials.authenticate(this.message,i))return!0;this.challenged=!0,i.stale&&(this.stale=!0);let n=this.message.cseq+=1;return t&&t.localSequenceNumber&&(t.incrementLocalSequenceNumber(),n=this.message.cseq=t.localSequenceNumber),this.message.setHeader("cseq",n+" "+this.message.method),this.message.setHeader(r,this.credentials.toString()),this.init(),!1}onRequestTimeout(){this.logger.warn("User agent client request timed out. Generating internal 408 Request Timeout.");const e=new Q;e.statusCode=408,e.reasonPhrase="Request Timeout",this.receiveResponse(e)}onTransportError(e){this.logger.error(e.message),this.logger.error("User agent client request transport error. Generating internal 503 Service Unavailable.");const t=new Q;t.statusCode=503,t.reasonPhrase="Service Unavailable",this.receiveResponse(t)}receiveResponse(e){if(!this.authenticationGuard(e))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});break;case/^1[0-9]{2}$/.test(t):this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e});break;case/^2[0-9]{2}$/.test(t):this.delegate&&this.delegate.onAccept&&this.delegate.onAccept({message:e});break;case/^3[0-9]{2}$/.test(t):this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});break;case/^[4-6][0-9]{2}$/.test(t):this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});break;default:throw new Error(`Invalid status code ${t}`)}}init(){const e={loggerFactory:this.loggerFactory,onRequestTimeout:()=>this.onRequestTimeout(),onStateChange:i=>{i===u.Terminated&&(this.core.userAgentClients.delete(s),t===this._transaction&&this.dispose())},onTransportError:i=>this.onTransportError(i),receiveResponse:i=>this.receiveResponse(i)},t=new this.transactionConstructor(this.message,this.core.transport,e);this._transaction=t;const s=t.id+t.request.method;this.core.userAgentClients.set(s,this)}}class Ct extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.BYE,s);super(U,e.userAgentCore,i,t),e.dispose()}}class B extends Ze{constructor(e,t,s){super(e,t,s,u.Trying,"sip.transaction.nist")}dispose(){this.J&&(clearTimeout(this.J),this.J=void 0),super.dispose()}get kind(){return"nist"}receiveRequest(e){switch(this.state){case u.Trying:break;case u.Proceeding:if(!this.lastResponse)throw new Error("Last response undefined.");this.send(this.lastResponse).catch(t=>{this.logTransportError(t,"Failed to send retransmission of provisional response.")});break;case u.Completed:if(!this.lastResponse)throw new Error("Last response undefined.");this.send(this.lastResponse).catch(t=>{this.logTransportError(t,"Failed to send retransmission of final response.")});break;case u.Terminated:break;default:throw new Error(`Invalid state ${this.state}`)}}receiveResponse(e,t){if(e<100||e>699)throw new Error(`Invalid status code ${e}`);if(e>100&&e<=199)throw new Error("Provisional response other than 100 not allowed.");switch(this.state){case u.Trying:if(this.lastResponse=t,e>=100&&e<200){this.stateTransition(u.Proceeding),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send provisional response.")});return}if(e>=200&&e<=699){this.stateTransition(u.Completed),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send final response.")});return}break;case u.Proceeding:if(this.lastResponse=t,e>=200&&e<=699){this.stateTransition(u.Completed),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send final response.")});return}break;case u.Completed:return;case u.Terminated:break;default:throw new Error(`Invalid state ${this.state}`)}const s=`Non-INVITE server transaction received unexpected ${e} response from TU while in state ${this.state}.`;throw this.logger.error(s),new Error(s)}onTransportError(e){this.user.onTransportError&&this.user.onTransportError(e),this.stateTransition(u.Terminated,!0)}typeToString(){return"non-INVITE server transaction"}stateTransition(e,t=!1){const s=()=>{throw new Error(`Invalid state transition from ${this.state} to ${e}`)};switch(e){case u.Trying:s();break;case u.Proceeding:this.state!==u.Trying&&s();break;case u.Completed:this.state!==u.Trying&&this.state!==u.Proceeding&&s();break;case u.Terminated:this.state!==u.Proceeding&&this.state!==u.Completed&&(t||s());break;default:s()}e===u.Completed&&(this.J=setTimeout(()=>this.timerJ(),H.TIMER_J)),e===u.Terminated&&this.dispose(),this.setState(e)}timerJ(){this.logger.debug(`Timer J expired for NON-INVITE server transaction ${this.id}.`),this.state===u.Completed&&this.stateTransition(u.Terminated)}}class z{constructor(e,t,s,i){this.transactionConstructor=e,this.core=t,this.message=s,this.delegate=i,this.logger=this.loggerFactory.getLogger("sip.user-agent-server"),this.toTag=s.toTag?s.toTag:Te(),this.init()}dispose(){this.transaction.dispose()}get loggerFactory(){return this.core.loggerFactory}get transaction(){if(!this._transaction)throw new Error("Transaction undefined.");return this._transaction}accept(e={statusCode:200}){if(!this.acceptable)throw new ee(`${this.message.method} not acceptable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<200||t>299)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}progress(e={statusCode:180}){if(!this.progressable)throw new ee(`${this.message.method} not progressable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<101||t>199)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}redirect(e,t={statusCode:302}){if(!this.redirectable)throw new ee(`${this.message.method} not redirectable in state ${this.transaction.state}.`);const s=t.statusCode;if(s<300||s>399)throw new TypeError(`Invalid statusCode: ${s}`);const i=new Array;return e.forEach(n=>i.push(`Contact: ${n.toString()}`)),t.extraHeaders=(t.extraHeaders||[]).concat(i),this.reply(t)}reject(e={statusCode:480}){if(!this.rejectable)throw new ee(`${this.message.method} not rejectable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<400||t>699)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}trying(e){if(!this.tryingable)throw new ee(`${this.message.method} not tryingable in state ${this.transaction.state}.`);return this.reply({statusCode:100})}receiveCancel(e){this.delegate&&this.delegate.onCancel&&this.delegate.onCancel(e)}get acceptable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding||this.transaction.state===u.Accepted;if(this.transaction instanceof B)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get progressable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof B)return!1;throw new Error("Unknown transaction type.")}get redirectable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof B)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get rejectable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof B)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get tryingable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof B)return this.transaction.state===u.Trying;throw new Error("Unknown transaction type.")}reply(e){!e.toTag&&e.statusCode!==100&&(e.toTag=this.toTag),e.userAgent=e.userAgent||this.core.configuration.userAgentHeaderFieldValue,e.supported=e.supported||this.core.configuration.supportedOptionTagsResponse;const t=ze(this.message,e);return this.transaction.receiveResponse(e.statusCode,t.message),t}init(){const e={loggerFactory:this.loggerFactory,onStateChange:i=>{i===u.Terminated&&(this.core.userAgentServers.delete(s),this.dispose())},onTransportError:i=>{this.logger.error(i.message),this.delegate&&this.delegate.onTransportError?this.delegate.onTransportError(i):this.logger.error("User agent server response transport error.")}},t=new this.transactionConstructor(this.message,this.core.transport,e);this._transaction=t;const s=t.id;this.core.userAgentServers.set(t.id,this)}}class xt extends z{constructor(e,t,s){super(B,e.userAgentCore,t,s)}}class Rt extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.INFO,s);super(U,e.userAgentCore,i,t)}}class It extends z{constructor(e,t,s){super(B,e.userAgentCore,t,s)}}class Xe extends q{constructor(e,t,s){super(U,e,t,s)}}class Qe extends z{constructor(e,t,s){super(B,e,t,s)}}class At extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.NOTIFY,s);super(U,e.userAgentCore,i,t)}}function $t(a){return a.userAgentCore!==void 0}class Ie extends z{constructor(e,t,s){const i=$t(e)?e.userAgentCore:e;super(B,i,t,s)}}class _t extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.PRACK,s);super(U,e.userAgentCore,i,t),e.signalingStateTransition(i)}}class Dt extends z{constructor(e,t,s){super(B,e.userAgentCore,t,s),e.signalingStateTransition(t),this.dialog=e}accept(e={statusCode:200}){return e.body&&this.dialog.signalingStateTransition(e.body),super.accept(e)}}class kt extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.INVITE,s);super(ie,e.userAgentCore,i,t),this.delegate=t,e.signalingStateTransition(i),e.reinviteUserAgentClient=this,this.dialog=e}receiveResponse(e){if(!this.authenticationGuard(e,this.dialog))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});break;case/^1[0-9]{2}$/.test(t):this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e,session:this.dialog,prack:s=>{throw new Error("Unimplemented.")}});break;case/^2[0-9]{2}$/.test(t):this.dialog.signalingStateTransition(e),this.delegate&&this.delegate.onAccept&&this.delegate.onAccept({message:e,session:this.dialog,ack:s=>this.dialog.ack(s)});break;case/^3[0-9]{2}$/.test(t):this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentClient=void 0,this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});break;case/^[4-6][0-9]{2}$/.test(t):this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentClient=void 0,this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});break;default:throw new Error(`Invalid status code ${t}`)}}}class Pt extends z{constructor(e,t,s){super(N,e.userAgentCore,t,s),e.reinviteUserAgentServer=this,this.dialog=e}accept(e={statusCode:200}){e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(this.dialog.routeSet.map(r=>`Record-Route: ${r}`));const t=super.accept(e),s=this.dialog,i=Object.assign(Object.assign({},t),{session:s});return e.body&&this.dialog.signalingStateTransition(e.body),this.dialog.reConfirm(),i}progress(e={statusCode:180}){const t=super.progress(e),s=this.dialog,i=Object.assign(Object.assign({},t),{session:s});return e.body&&this.dialog.signalingStateTransition(e.body),i}redirect(e,t={statusCode:302}){throw this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentServer=void 0,new Error("Unimplemented.")}reject(e={statusCode:488}){return this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentServer=void 0,super.reject(e)}}class Ht extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.REFER,s);super(U,e.userAgentCore,i,t)}}function Mt(a){return a.userAgentCore!==void 0}class et extends z{constructor(e,t,s){const i=Mt(e)?e.userAgentCore:e;super(B,i,t,s)}}class Ae extends ge{constructor(e,t,s,i){super(t,s),this.initialTransaction=e,this._signalingState=v.Initial,this.ackWait=!1,this.ackProcessing=!1,this.delegate=i,e instanceof N&&(this.ackWait=!0),this.early||this.start2xxRetransmissionTimer(),this.signalingStateTransition(e.request),this.logger=t.loggerFactory.getLogger("sip.invite-dialog"),this.logger.log(`INVITE dialog ${this.id} constructed`)}dispose(){super.dispose(),this._signalingState=v.Closed,this._offer=void 0,this._answer=void 0,this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.logger.log(`INVITE dialog ${this.id} destroyed`)}get sessionState(){return this.early?L.Early:this.ackWait?L.AckWait:this._signalingState===v.Closed?L.Terminated:L.Confirmed}get signalingState(){return this._signalingState}get offer(){return this._offer}get answer(){return this._answer}confirm(){this.early&&this.start2xxRetransmissionTimer(),super.confirm()}reConfirm(){this.reinviteUserAgentServer&&this.startReInvite2xxRetransmissionTimer()}ack(e={}){this.logger.log(`INVITE dialog ${this.id} sending ACK request`);let t;if(this.reinviteUserAgentClient){if(!(this.reinviteUserAgentClient.transaction instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");t=this.reinviteUserAgentClient.transaction,this.reinviteUserAgentClient=void 0}else{if(!(this.initialTransaction instanceof ie))throw new Error("Initial transaction not instance of InviteClientTransaction.");t=this.initialTransaction}const s=this.createOutgoingRequestMessage(y.ACK,{cseq:t.request.cseq,extraHeaders:e.extraHeaders,body:e.body});return t.ackResponse(s),this.signalingStateTransition(s),{message:s}}bye(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending BYE request`),this.initialTransaction instanceof N){if(this.early)throw new Error("UAS MUST NOT send a BYE on early dialogs.");if(this.ackWait&&this.initialTransaction.state!==u.Terminated)throw new Error("UAS MUST NOT send a BYE on a confirmed dialog until it has received an ACK for its 2xx response or until the server transaction times out.")}return new Ct(this,e,t)}info(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending INFO request`),this.early)throw new Error("Dialog not confirmed.");return new Rt(this,e,t)}invite(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending INVITE request`),this.early)throw new Error("Dialog not confirmed.");if(this.reinviteUserAgentClient)throw new Error("There is an ongoing re-INVITE client transaction.");if(this.reinviteUserAgentServer)throw new Error("There is an ongoing re-INVITE server transaction.");return new kt(this,e,t)}message(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending MESSAGE request`),this.early)throw new Error("Dialog not confirmed.");const s=this.createOutgoingRequestMessage(y.MESSAGE,t);return new Xe(this.core,s,e)}notify(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending NOTIFY request`),this.early)throw new Error("Dialog not confirmed.");return new At(this,e,t)}prack(e,t){return this.logger.log(`INVITE dialog ${this.id} sending PRACK request`),new _t(this,e,t)}refer(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending REFER request`),this.early)throw new Error("Dialog not confirmed.");return new Ht(this,e,t)}receiveRequest(e){if(this.logger.log(`INVITE dialog ${this.id} received ${e.method} request`),e.method===y.ACK){if(this.ackWait){if(this.initialTransaction instanceof ie){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}if(this.initialTransaction.request.cseq!==e.cseq){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}this.ackWait=!1}else{if(!this.reinviteUserAgentServer){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}if(this.reinviteUserAgentServer.transaction.request.cseq!==e.cseq){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}this.reinviteUserAgentServer=void 0}if(this.signalingStateTransition(e),this.delegate&&this.delegate.onAck){const t=this.delegate.onAck({message:e});t instanceof Promise&&(this.ackProcessing=!0,t.then(()=>this.ackProcessing=!1).catch(()=>this.ackProcessing=!1))}return}if(!this.sequenceGuard(e)){this.logger.log(`INVITE dialog ${this.id} rejected out of order ${e.method} request.`);return}if(super.receiveRequest(e),e.method===y.INVITE){const t=()=>{const r=this.ackWait?"waiting for initial ACK":"processing initial ACK";this.logger.warn(`INVITE dialog ${this.id} received re-INVITE while ${r}`);let n="RFC 5407 suggests the following to avoid this race condition... ";n+=" Note: Implementation issues are outside the scope of this document,",n+=" but the following tip is provided for avoiding race conditions of",n+=" this type. The caller can delay sending re-INVITE F6 for some period",n+=" of time (2 seconds, perhaps), after which the caller can reasonably",n+=" assume that its ACK has been received. Implementors can decouple the",n+=" actions of the user (e.g., pressing the hold button) from the actions",n+=" of the protocol (the sending of re-INVITE F6), so that the UA can",n+=" behave like this. In this case, it is the implementor's choice as to",n+=" how long to wait. In most cases, such an implementation may be",n+=" useful to prevent the type of race condition shown in this section.",n+=" This document expresses no preference about whether or not they",n+=" should wait for an ACK to be delivered. After considering the impact",n+=" on user experience, implementors should decide whether or not to wait",n+=" for a while, because the user experience depends on the",n+=" implementation and has no direct bearing on protocol behavior.",this.logger.warn(n)},i=[`Retry-After: ${Math.floor(Math.random()*10)+1}`];if(this.ackProcessing){this.core.replyStateless(e,{statusCode:500,extraHeaders:i}),t();return}if(this.ackWait&&this.signalingState!==v.Stable){this.core.replyStateless(e,{statusCode:500,extraHeaders:i}),t();return}if(this.reinviteUserAgentServer){this.core.replyStateless(e,{statusCode:500,extraHeaders:i});return}if(this.reinviteUserAgentClient){this.core.replyStateless(e,{statusCode:491});return}}if(e.method===y.INVITE){const t=e.parseHeader("contact");if(!t)throw new Error("Contact undefined.");if(!(t instanceof O))throw new Error("Contact not instance of NameAddrHeader.");this.dialogState.remoteTarget=t.uri}switch(e.method){case y.BYE:{const t=new xt(this,e);this.delegate&&this.delegate.onBye?this.delegate.onBye(t):t.accept(),this.dispose()}break;case y.INFO:{const t=new It(this,e);this.delegate&&this.delegate.onInfo?this.delegate.onInfo(t):t.reject({statusCode:469,extraHeaders:["Recv-Info:"]})}break;case y.INVITE:{const t=new Pt(this,e);this.signalingStateTransition(e),this.delegate&&this.delegate.onInvite?this.delegate.onInvite(t):t.reject({statusCode:488})}break;case y.MESSAGE:{const t=new Qe(this.core,e);this.delegate&&this.delegate.onMessage?this.delegate.onMessage(t):t.accept()}break;case y.NOTIFY:{const t=new Ie(this,e);this.delegate&&this.delegate.onNotify?this.delegate.onNotify(t):t.accept()}break;case y.PRACK:{const t=new Dt(this,e);this.delegate&&this.delegate.onPrack?this.delegate.onPrack(t):t.accept()}break;case y.REFER:{const t=new et(this,e);this.delegate&&this.delegate.onRefer?this.delegate.onRefer(t):t.reject()}break;default:this.logger.log(`INVITE dialog ${this.id} received unimplemented ${e.method} request`),this.core.replyStateless(e,{statusCode:501});break}}reliableSequenceGuard(e){const t=e.statusCode;if(!t)throw new Error("Status code undefined");if(t>100&&t<200){const s=e.getHeader("require"),i=e.getHeader("rseq"),r=s&&s.includes("100rel")&&i?Number(i):void 0;if(r){if(this.rseq&&this.rseq+1!==r)return!1;this.rseq=this.rseq?this.rseq+1:r}}return!0}signalingStateRollback(){(this._signalingState===v.HaveLocalOffer||this.signalingState===v.HaveRemoteOffer)&&this._rollbackOffer&&this._rollbackAnswer&&(this._signalingState=v.Stable,this._offer=this._rollbackOffer,this._answer=this._rollbackAnswer)}signalingStateTransition(e){const t=be(e);if(!(!t||t.contentDisposition!=="session")){if(this._signalingState===v.Stable&&(this._rollbackOffer=this._offer,this._rollbackAnswer=this._answer),e instanceof he)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveRemoteOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:this._signalingState=v.Stable,this._answer=t;break;case v.HaveRemoteOffer:break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(e instanceof Q)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveRemoteOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:this._signalingState=v.Stable,this._answer=t;break;case v.HaveRemoteOffer:break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(e instanceof ae)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveLocalOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:break;case v.HaveRemoteOffer:this._signalingState=v.Stable,this._answer=t;break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(Ve(e))switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveLocalOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:break;case v.HaveRemoteOffer:this._signalingState=v.Stable,this._answer=t;break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}}}start2xxRetransmissionTimer(){if(this.initialTransaction instanceof N){const e=this.initialTransaction;let t=H.T1;const s=()=>{if(!this.ackWait){this.invite2xxTimer=void 0;return}this.logger.log("No ACK for 2xx response received, attempting retransmission"),e.retransmitAcceptedResponse(),t=Math.min(t*2,H.T2),this.invite2xxTimer=setTimeout(s,t)};this.invite2xxTimer=setTimeout(s,t);const i=()=>{e.state===u.Terminated&&(e.removeStateChangeListener(i),this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.ackWait&&(this.delegate&&this.delegate.onAckTimeout?this.delegate.onAckTimeout():this.bye()))};e.addStateChangeListener(i)}}startReInvite2xxRetransmissionTimer(){if(this.reinviteUserAgentServer&&this.reinviteUserAgentServer.transaction instanceof N){const e=this.reinviteUserAgentServer.transaction;let t=H.T1;const s=()=>{if(!this.reinviteUserAgentServer){this.invite2xxTimer=void 0;return}this.logger.log("No ACK for 2xx response received, attempting retransmission"),e.retransmitAcceptedResponse(),t=Math.min(t*2,H.T2),this.invite2xxTimer=setTimeout(s,t)};this.invite2xxTimer=setTimeout(s,t);const i=()=>{e.state===u.Terminated&&(e.removeStateChangeListener(i),this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.reinviteUserAgentServer)};e.addStateChangeListener(i)}}}class qt extends q{constructor(e,t,s){super(ie,e,t,s),this.confirmedDialogAcks=new Map,this.confirmedDialogs=new Map,this.earlyDialogs=new Map,this.delegate=s}dispose(){this.earlyDialogs.forEach(e=>e.dispose()),this.earlyDialogs.clear(),super.dispose()}onTransportError(e){if(this.transaction.state===u.Calling)return super.onTransportError(e);this.logger.error(e.message),this.logger.error("User agent client request transport error while sending ACK.")}receiveResponse(e){if(!this.authenticationGuard(e))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});return;case/^1[0-9]{2}$/.test(t):{if(!e.toTag){this.logger.warn("Non-100 1xx INVITE response received without a to tag, dropping.");return}if(!e.parseHeader("contact")){this.logger.error("Non-100 1xx INVITE response received without a Contact header field, dropping.");return}const i=ge.initialDialogStateForUserAgentClient(this.message,e);let r=this.earlyDialogs.get(i.id);if(!r){const o=this.transaction;if(!(o instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");r=new Ae(o,this.core,i),this.earlyDialogs.set(r.id,r)}if(!r.reliableSequenceGuard(e)){this.logger.warn("1xx INVITE reliable response received out of order or is a retransmission, dropping.");return}(r.signalingState===v.Initial||r.signalingState===v.HaveLocalOffer)&&r.signalingStateTransition(e);const n=r;this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e,session:n,prack:o=>n.prack(void 0,o)})}return;case/^2[0-9]{2}$/.test(t):{if(!e.toTag){this.logger.error("2xx INVITE response received without a to tag, dropping.");return}if(!e.parseHeader("contact")){this.logger.error("2xx INVITE response received without a Contact header field, dropping.");return}const i=ge.initialDialogStateForUserAgentClient(this.message,e);let r=this.confirmedDialogs.get(i.id);if(r){const o=this.confirmedDialogAcks.get(i.id);if(o){const d=this.transaction;if(!(d instanceof ie))throw new Error("Client transaction not instance of InviteClientTransaction.");d.ackResponse(o.message)}return}if(r=this.earlyDialogs.get(i.id),r)r.confirm(),r.recomputeRouteSet(e),this.earlyDialogs.delete(r.id),this.confirmedDialogs.set(r.id,r);else{const o=this.transaction;if(!(o instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");r=new Ae(o,this.core,i),this.confirmedDialogs.set(r.id,r)}(r.signalingState===v.Initial||r.signalingState===v.HaveLocalOffer)&&r.signalingStateTransition(e);const n=r;if(this.delegate&&this.delegate.onAccept)this.delegate.onAccept({message:e,session:n,ack:o=>{const d=n.ack(o);return this.confirmedDialogAcks.set(n.id,d),d}});else{const o=n.ack();this.confirmedDialogAcks.set(n.id,o)}}return;case/^3[0-9]{2}$/.test(t):this.earlyDialogs.forEach(s=>s.dispose()),this.earlyDialogs.clear(),this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});return;case/^[4-6][0-9]{2}$/.test(t):this.earlyDialogs.forEach(s=>s.dispose()),this.earlyDialogs.clear(),this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});return;default:throw new Error(`Invalid status code ${t}`)}}}class Me extends z{constructor(e,t,s){super(N,e,t,s),this.core=e}dispose(){this.earlyDialog&&this.earlyDialog.dispose(),super.dispose()}accept(e={statusCode:200}){if(!this.acceptable)throw new ee(`${this.message.method} not acceptable in state ${this.transaction.state}.`);if(!this.confirmedDialog)if(this.earlyDialog)this.earlyDialog.confirm(),this.confirmedDialog=this.earlyDialog,this.earlyDialog=void 0;else{const d=this.transaction;if(!(d instanceof N))throw new Error("Transaction not instance of InviteClientTransaction.");const p=ge.initialDialogStateForUserAgentServer(this.message,this.toTag);this.confirmedDialog=new Ae(d,this.core,p)}const t=this.message.getHeaders("record-route").map(d=>`Record-Route: ${d}`),s=`Contact: ${this.core.configuration.contact.toString()}`,i="Allow: "+te.toString();if(!e.body){if(this.confirmedDialog.signalingState===v.Stable)e.body=this.confirmedDialog.answer;else if(this.confirmedDialog.signalingState===v.Initial||this.confirmedDialog.signalingState===v.HaveRemoteOffer)throw new Error("Response must have a body.")}e.statusCode=e.statusCode||200,e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(t),e.extraHeaders.push(i),e.extraHeaders.push(s);const r=super.accept(e),n=this.confirmedDialog,o=Object.assign(Object.assign({},r),{session:n});return e.body&&this.confirmedDialog.signalingState!==v.Stable&&this.confirmedDialog.signalingStateTransition(e.body),o}progress(e={statusCode:180}){if(!this.progressable)throw new ee(`${this.message.method} not progressable in state ${this.transaction.state}.`);if(!this.earlyDialog){const o=this.transaction;if(!(o instanceof N))throw new Error("Transaction not instance of InviteClientTransaction.");const d=ge.initialDialogStateForUserAgentServer(this.message,this.toTag,!0);this.earlyDialog=new Ae(o,this.core,d)}const t=this.message.getHeaders("record-route").map(o=>`Record-Route: ${o}`),s=`Contact: ${this.core.configuration.contact}`;e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(t),e.extraHeaders.push(s);const i=super.progress(e),r=this.earlyDialog,n=Object.assign(Object.assign({},i),{session:r});return e.body&&this.earlyDialog.signalingState!==v.Stable&&this.earlyDialog.signalingStateTransition(e.body),n}redirect(e,t={statusCode:302}){return super.redirect(e,t)}reject(e={statusCode:486}){return super.reject(e)}}class Ft extends q{constructor(e,t,s){super(U,e,t,s)}}class Ot extends q{constructor(e,t,s){super(U,e,t,s)}}class Nt extends z{constructor(e,t,s){super(B,e,t,s),this.core=e}}class Ut extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.SUBSCRIBE,s);super(U,e.userAgentCore,i,t),this.dialog=e}waitNotifyStop(){}receiveResponse(e){if(e.statusCode&&e.statusCode>=200&&e.statusCode<300){const t=e.getHeader("Expires");if(!t)this.logger.warn("Expires header missing in a 200-class response to SUBSCRIBE");else{const s=Number(t);this.dialog.subscriptionExpires>s&&(this.dialog.subscriptionExpires=s)}}e.statusCode&&e.statusCode>=400&&e.statusCode<700&&[404,405,410,416,480,481,482,483,484,485,489,501,604].includes(e.statusCode)&&this.dialog.terminate(),super.receiveResponse(e)}}class tt extends ge{constructor(e,t,s,i,r,n){super(i,r),this.delegate=n,this._autoRefresh=!1,this._subscriptionEvent=e,this._subscriptionExpires=t,this._subscriptionExpiresInitial=t,this._subscriptionExpiresLastSet=Math.floor(Date.now()/1e3),this._subscriptionRefresh=void 0,this._subscriptionRefreshLastSet=void 0,this._subscriptionState=s,this.logger=i.loggerFactory.getLogger("sip.subscribe-dialog"),this.logger.log(`SUBSCRIBE dialog ${this.id} constructed`)}static initialDialogStateForSubscription(e,t){const i=t.getHeaders("record-route"),r=t.parseHeader("contact");if(!r)throw new Error("Contact undefined.");if(!(r instanceof O))throw new Error("Contact not instance of NameAddrHeader.");const n=r.uri,o=e.cseq,d=void 0,p=e.callId,g=e.fromTag,w=t.fromTag;if(!p)throw new Error("Call id undefined.");if(!g)throw new Error("From tag undefined.");if(!w)throw new Error("To tag undefined.");if(!e.from)throw new Error("From undefined.");if(!e.to)throw new Error("To undefined.");const S=e.from.uri,I=e.to.uri;return{id:p+g+w,early:!1,callId:p,localTag:g,remoteTag:w,localSequenceNumber:o,remoteSequenceNumber:d,localURI:S,remoteURI:I,remoteTarget:n,routeSet:i,secure:!1}}dispose(){super.dispose(),this.N&&(clearTimeout(this.N),this.N=void 0),this.refreshTimerClear(),this.logger.log(`SUBSCRIBE dialog ${this.id} destroyed`)}get autoRefresh(){return this._autoRefresh}set autoRefresh(e){this._autoRefresh=!0,this.refreshTimerSet()}get subscriptionEvent(){return this._subscriptionEvent}get subscriptionExpires(){const e=Math.floor(Date.now()/1e3)-this._subscriptionExpiresLastSet,t=this._subscriptionExpires-e;return Math.max(t,0)}set subscriptionExpires(e){if(e<0)throw new Error("Expires must be greater than or equal to zero.");if(this._subscriptionExpires=e,this._subscriptionExpiresLastSet=Math.floor(Date.now()/1e3),this.autoRefresh){const t=this.subscriptionRefresh;(t===void 0||t>=e)&&this.refreshTimerSet()}}get subscriptionExpiresInitial(){return this._subscriptionExpiresInitial}get subscriptionRefresh(){if(this._subscriptionRefresh===void 0||this._subscriptionRefreshLastSet===void 0)return;const e=Math.floor(Date.now()/1e3)-this._subscriptionRefreshLastSet,t=this._subscriptionRefresh-e;return Math.max(t,0)}get subscriptionState(){return this._subscriptionState}receiveRequest(e){if(this.logger.log(`SUBSCRIBE dialog ${this.id} received ${e.method} request`),!this.sequenceGuard(e)){this.logger.log(`SUBSCRIBE dialog ${this.id} rejected out of order ${e.method} request.`);return}super.receiveRequest(e),e.method===y.NOTIFY?this.onNotify(e):(this.logger.log(`SUBSCRIBE dialog ${this.id} received unimplemented ${e.method} request`),this.core.replyStateless(e,{statusCode:501}))}refresh(){const e="Allow: "+te.toString(),t={};return t.extraHeaders=(t.extraHeaders||[]).slice(),t.extraHeaders.push(e),t.extraHeaders.push("Event: "+this.subscriptionEvent),t.extraHeaders.push("Expires: "+this.subscriptionExpiresInitial),t.extraHeaders.push("Contact: "+this.core.configuration.contact.toString()),this.subscribe(void 0,t)}subscribe(e,t={}){var s;if(this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active)throw new Error(`Invalid state ${this.subscriptionState}. May only re-subscribe while in state "pending" or "active".`);this.logger.log(`SUBSCRIBE dialog ${this.id} sending SUBSCRIBE request`);const i=new Ut(this,e,t);return this.N&&(clearTimeout(this.N),this.N=void 0),!((s=t.extraHeaders)===null||s===void 0)&&s.includes("Expires: 0")||(this.N=setTimeout(()=>this.timerN(),H.TIMER_N)),i}terminate(){this.stateTransition(R.Terminated),this.onTerminated()}unsubscribe(){const e="Allow: "+te.toString(),t={};return t.extraHeaders=(t.extraHeaders||[]).slice(),t.extraHeaders.push(e),t.extraHeaders.push("Event: "+this.subscriptionEvent),t.extraHeaders.push("Expires: 0"),t.extraHeaders.push("Contact: "+this.core.configuration.contact.toString()),this.subscribe(void 0,t)}onNotify(e){const t=e.parseHeader("Event").event;if(!t||t!==this.subscriptionEvent){this.core.replyStateless(e,{statusCode:489});return}this.N&&(clearTimeout(this.N),this.N=void 0);const s=e.parseHeader("Subscription-State");if(!s||!s.state){this.core.replyStateless(e,{statusCode:489});return}const i=s.state,r=s.expires?Math.max(s.expires,0):void 0;switch(i){case"pending":this.stateTransition(R.Pending,r);break;case"active":this.stateTransition(R.Active,r);break;case"terminated":this.stateTransition(R.Terminated,r);break;default:this.logger.warn("Unrecognized subscription state.");break}const n=new Ie(this,e);this.delegate&&this.delegate.onNotify?this.delegate.onNotify(n):n.accept()}onRefresh(e){this.delegate&&this.delegate.onRefresh&&this.delegate.onRefresh(e)}onTerminated(){this.delegate&&this.delegate.onTerminated&&this.delegate.onTerminated()}refreshTimerClear(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=void 0)}refreshTimerSet(){if(this.refreshTimerClear(),this.autoRefresh&&this.subscriptionExpires>0){const e=this.subscriptionExpires*900;this._subscriptionRefresh=Math.floor(e/1e3),this._subscriptionRefreshLastSet=Math.floor(Date.now()/1e3),this.refreshTimer=setTimeout(()=>{this.refreshTimer=void 0,this._subscriptionRefresh=void 0,this._subscriptionRefreshLastSet=void 0,this.onRefresh(this.refresh())},e)}}stateTransition(e,t){const s=()=>{this.logger.warn(`Invalid subscription state transition from ${this.subscriptionState} to ${e}`)};switch(e){case R.Initial:s();return;case R.NotifyWait:s();return;case R.Pending:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending){s();return}break;case R.Active:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active){s();return}break;case R.Terminated:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active){s();return}break;default:s();return}e===R.Pending&&t&&(this.subscriptionExpires=t),e===R.Active&&t&&(this.subscriptionExpires=t),e===R.Terminated&&this.dispose(),this._subscriptionState=e}timerN(){this.logger.warn("Timer N expired for SUBSCRIBE dialog. Timed out waiting for NOTIFY."),this.subscriptionState!==R.Terminated&&(this.stateTransition(R.Terminated),this.onTerminated())}}class Bt extends q{constructor(e,t,s){const i=t.getHeader("Event");if(!i)throw new Error("Event undefined");const r=t.getHeader("Expires");if(!r)throw new Error("Expires undefined");super(U,e,t,s),this.delegate=s,this.subscriberId=t.callId+t.fromTag+i,this.subscriptionExpiresRequested=this.subscriptionExpires=Number(r),this.subscriptionEvent=i,this.subscriptionState=R.NotifyWait,this.waitNotifyStart()}dispose(){super.dispose()}onNotify(e){const t=e.message.parseHeader("Event").event;if(!t||t!==this.subscriptionEvent){this.logger.warn("Failed to parse event."),e.reject({statusCode:489});return}const s=e.message.parseHeader("Subscription-State");if(!s||!s.state){this.logger.warn("Failed to parse subscription state."),e.reject({statusCode:489});return}const i=s.state;switch(i){case"pending":break;case"active":break;case"terminated":break;default:this.logger.warn(`Invalid subscription state ${i}`),e.reject({statusCode:489});return}if(i!=="terminated"&&!e.message.parseHeader("contact")){this.logger.warn("Failed to parse contact."),e.reject({statusCode:489});return}if(this.dialog)throw new Error("Dialog already created. This implementation only supports install of single subscriptions.");switch(this.waitNotifyStop(),this.subscriptionExpires=s.expires?Math.min(this.subscriptionExpires,Math.max(s.expires,0)):this.subscriptionExpires,i){case"pending":this.subscriptionState=R.Pending;break;case"active":this.subscriptionState=R.Active;break;case"terminated":this.subscriptionState=R.Terminated;break;default:throw new Error(`Unrecognized state ${i}.`)}if(this.subscriptionState!==R.Terminated){const r=tt.initialDialogStateForSubscription(this.message,e.message);this.dialog=new tt(this.subscriptionEvent,this.subscriptionExpires,this.subscriptionState,this.core,r)}if(this.delegate&&this.delegate.onNotify){const r=e,n=this.dialog;this.delegate.onNotify({request:r,subscription:n})}else e.accept()}waitNotifyStart(){this.N||(this.core.subscribers.set(this.subscriberId,this),this.N=setTimeout(()=>this.timerN(),H.TIMER_N))}waitNotifyStop(){this.N&&(this.core.subscribers.delete(this.subscriberId),clearTimeout(this.N),this.N=void 0)}receiveResponse(e){if(this.authenticationGuard(e)){if(e.statusCode&&e.statusCode>=200&&e.statusCode<300){const t=e.getHeader("Expires");if(!t)this.logger.warn("Expires header missing in a 200-class response to SUBSCRIBE");else{const s=Number(t);s>this.subscriptionExpiresRequested&&this.logger.warn("Expires header in a 200-class response to SUBSCRIBE with a higher value than the one in the request"),s<this.subscriptionExpires&&(this.subscriptionExpires=s)}this.dialog&&this.dialog.subscriptionExpires>this.subscriptionExpires&&(this.dialog.subscriptionExpires=this.subscriptionExpires)}e.statusCode&&e.statusCode>=300&&e.statusCode<700&&this.waitNotifyStop(),super.receiveResponse(e)}}timerN(){this.logger.warn("Timer N expired for SUBSCRIBE user agent client. Timed out waiting for NOTIFY."),this.waitNotifyStop(),this.delegate&&this.delegate.onNotifyTimeout&&this.delegate.onNotifyTimeout()}}class Lt extends z{constructor(e,t,s){super(B,e,t,s),this.core=e}}const st=["application/sdp","application/dtmf-relay"];class jt{constructor(e,t={}){this.userAgentClients=new Map,this.userAgentServers=new Map,this.configuration=e,this.delegate=t,this.dialogs=new Map,this.subscribers=new Map,this.logger=e.loggerFactory.getLogger("sip.user-agent-core")}dispose(){this.reset()}reset(){this.dialogs.forEach(e=>e.dispose()),this.dialogs.clear(),this.subscribers.forEach(e=>e.dispose()),this.subscribers.clear(),this.userAgentClients.forEach(e=>e.dispose()),this.userAgentClients.clear(),this.userAgentServers.forEach(e=>e.dispose()),this.userAgentServers.clear()}get loggerFactory(){return this.configuration.loggerFactory}get transport(){const e=this.configuration.transportAccessor();if(!e)throw new Error("Transport undefined.");return e}invite(e,t){return new qt(this,e,t)}message(e,t){return new Xe(this,e,t)}publish(e,t){return new Ft(this,e,t)}register(e,t){return new Ot(this,e,t)}subscribe(e,t){return new Bt(this,e,t)}request(e,t){return new q(U,this,e,t)}makeOutgoingRequestMessage(e,t,s,i,r,n,o){const d=this.configuration.sipjsId,p=this.configuration.displayName,g=this.configuration.viaForceRport,w=this.configuration.hackViaTcp,S=this.configuration.supportedOptionTags.slice();e===y.REGISTER&&S.push("path","gruu"),e===y.INVITE&&(this.configuration.contact.pubGruu||this.configuration.contact.tempGruu)&&S.push("gruu");const I=this.configuration.routeSet,A=this.configuration.userAgentHeaderFieldValue,C=this.configuration.viaHost,f=Object.assign(Object.assign({},{callIdPrefix:d,forceRport:g,fromDisplayName:p,hackViaTcp:w,optionTags:S,routeSet:I,userAgentString:A,viaHost:C}),r);return new ae(e,t,s,i,f,n,o)}receiveIncomingRequestFromTransport(e){this.receiveRequestFromTransport(e)}receiveIncomingResponseFromTransport(e){this.receiveResponseFromTransport(e)}replyStateless(e,t){const s=this.configuration.userAgentHeaderFieldValue,i=this.configuration.supportedOptionTagsResponse;t=Object.assign(Object.assign({},t),{userAgent:s,supported:i});const r=ze(e,t);return this.transport.send(r.message).catch(n=>{n instanceof Error&&this.logger.error(n.message),this.logger.error(`Transport error occurred sending stateless reply to ${e.method} request.`)}),r}receiveRequestFromTransport(e){const t=e.viaBranch,s=this.userAgentServers.get(t);if(e.method===y.ACK&&s&&s.transaction.state===u.Accepted&&s instanceof Me){this.logger.warn(`Discarding out of dialog ACK after 2xx response sent on transaction ${t}.`);return}if(e.method===y.CANCEL){s?(this.replyStateless(e,{statusCode:200}),s.transaction instanceof N&&s.transaction.state===u.Proceeding&&s instanceof Me&&s.receiveCancel(e)):this.replyStateless(e,{statusCode:481});return}if(s){s.transaction.receiveRequest(e);return}this.receiveRequest(e)}receiveRequest(e){if(!te.includes(e.method)){const i="Allow: "+te.toString();this.replyStateless(e,{statusCode:405,extraHeaders:[i]});return}if(!e.ruri)throw new Error("Request-URI undefined.");if(e.ruri.scheme!=="sip"){this.replyStateless(e,{statusCode:416});return}const t=e.ruri,s=i=>!!i&&i.user===t.user;if(!s(this.configuration.aor)&&!(s(this.configuration.contact.uri)||s(this.configuration.contact.pubGruu)||s(this.configuration.contact.tempGruu))){this.logger.warn("Request-URI does not point to us."),e.method!==y.ACK&&this.replyStateless(e,{statusCode:404});return}if(e.method===y.INVITE&&!e.hasHeader("Contact")){this.replyStateless(e,{statusCode:400,reasonPhrase:"Missing Contact Header"});return}if(!e.toTag){const i=e.viaBranch;if(!this.userAgentServers.has(i)&&Array.from(this.userAgentServers.values()).some(n=>n.transaction.request.fromTag===e.fromTag&&n.transaction.request.callId===e.callId&&n.transaction.request.cseq===e.cseq)){this.replyStateless(e,{statusCode:482});return}}e.toTag?this.receiveInsideDialogRequest(e):this.receiveOutsideDialogRequest(e)}receiveInsideDialogRequest(e){if(e.method===y.NOTIFY){const i=e.parseHeader("Event");if(!i||!i.event){this.replyStateless(e,{statusCode:489});return}const r=e.callId+e.toTag+i.event,n=this.subscribers.get(r);if(n){const o=new Ie(this,e);n.onNotify(o);return}}const t=e.callId+e.toTag+e.fromTag,s=this.dialogs.get(t);if(s){if(e.method===y.OPTIONS){const i="Allow: "+te.toString(),r="Accept: "+st.toString();this.replyStateless(e,{statusCode:200,extraHeaders:[i,r]});return}s.receiveRequest(e);return}e.method!==y.ACK&&this.replyStateless(e,{statusCode:481})}receiveOutsideDialogRequest(e){switch(e.method){case y.ACK:break;case y.BYE:this.replyStateless(e,{statusCode:481});break;case y.CANCEL:throw new Error(`Unexpected out of dialog request method ${e.method}.`);case y.INFO:this.replyStateless(e,{statusCode:405});break;case y.INVITE:{const t=new Me(this,e);this.delegate.onInvite?this.delegate.onInvite(t):t.reject()}break;case y.MESSAGE:{const t=new Qe(this,e);this.delegate.onMessage?this.delegate.onMessage(t):t.accept()}break;case y.NOTIFY:{const t=new Ie(this,e);this.delegate.onNotify?this.delegate.onNotify(t):t.reject({statusCode:405})}break;case y.OPTIONS:{const t="Allow: "+te.toString(),s="Accept: "+st.toString();this.replyStateless(e,{statusCode:200,extraHeaders:[t,s]})}break;case y.REFER:{const t=new et(this,e);this.delegate.onRefer?this.delegate.onRefer(t):t.reject({statusCode:405})}break;case y.REGISTER:{const t=new Nt(this,e);this.delegate.onRegister?this.delegate.onRegister(t):t.reject({statusCode:405})}break;case y.SUBSCRIBE:{const t=new Lt(this,e);this.delegate.onSubscribe?this.delegate.onSubscribe(t):t.reject({statusCode:480})}break;default:throw new Error(`Unexpected out of dialog request method ${e.method}.`)}}receiveResponseFromTransport(e){if(e.getHeaders("via").length>1){this.logger.warn("More than one Via header field present in the response, dropping");return}const t=e.viaBranch+e.method,s=this.userAgentClients.get(t);s?s.transaction.receiveResponse(e):this.logger.warn(`Discarding unmatched ${e.statusCode} response to ${e.method} ${t}.`)}}function Gt(){return a=>!a.audio&&!a.video?Promise.resolve(new MediaStream):navigator.mediaDevices===void 0?Promise.reject(new Error("Media devices not available in insecure contexts.")):navigator.mediaDevices.getUserMedia.call(navigator.mediaDevices,a)}function Vt(){return{bundlePolicy:"balanced",certificates:void 0,iceCandidatePoolSize:0,iceServers:[{urls:"stun:stun.l.google.com:19302"}],iceTransportPolicy:"all",rtcpMuxPolicy:"require"}}class F{constructor(e,t,s){e.debug("SessionDescriptionHandler.constructor"),this.logger=e,this.mediaStreamFactory=t,this.sessionDescriptionHandlerConfiguration=s,this._localMediaStream=new MediaStream,this._remoteMediaStream=new MediaStream,this._peerConnection=new RTCPeerConnection(s?.peerConnectionConfiguration),this.initPeerConnectionEventHandlers()}get localMediaStream(){return this._localMediaStream}get remoteMediaStream(){return this._remoteMediaStream}get dataChannel(){return this._dataChannel}get peerConnection(){return this._peerConnection}get peerConnectionDelegate(){return this._peerConnectionDelegate}set peerConnectionDelegate(e){this._peerConnectionDelegate=e}static dispatchAddTrackEvent(e,t){e.dispatchEvent(new MediaStreamTrackEvent("addtrack",{track:t}))}static dispatchRemoveTrackEvent(e,t){e.dispatchEvent(new MediaStreamTrackEvent("removetrack",{track:t}))}close(){this.logger.debug("SessionDescriptionHandler.close"),this._peerConnection!==void 0&&(this._peerConnection.getReceivers().forEach(e=>{e.track&&e.track.stop()}),this._peerConnection.getSenders().forEach(e=>{e.track&&e.track.stop()}),this._dataChannel&&this._dataChannel.close(),this._peerConnection.close(),this._peerConnection=void 0)}enableReceiverTracks(e){const t=this.peerConnection;if(!t)throw new Error("Peer connection closed.");t.getReceivers().forEach(s=>{s.track&&(s.track.enabled=e)})}enableSenderTracks(e){const t=this.peerConnection;if(!t)throw new Error("Peer connection closed.");t.getSenders().forEach(s=>{s.track&&(s.track.enabled=e)})}getDescription(e,t){var s,i;if(this.logger.debug("SessionDescriptionHandler.getDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));this.onDataChannel=e?.onDataChannel;const r=(s=e?.offerOptions)===null||s===void 0?void 0:s.iceRestart,n=e?.iceGatheringTimeout===void 0?(i=this.sessionDescriptionHandlerConfiguration)===null||i===void 0?void 0:i.iceGatheringTimeout:e?.iceGatheringTimeout;return this.getLocalMediaStream(e).then(()=>this.updateDirection(e)).then(()=>this.createDataChannel(e)).then(()=>this.createLocalOfferOrAnswer(e)).then(o=>this.applyModifiers(o,t)).then(o=>this.setLocalSessionDescription(o)).then(()=>this.waitForIceGatheringComplete(r,n)).then(()=>this.getLocalSessionDescription()).then(o=>({body:o.sdp,contentType:"application/sdp"})).catch(o=>{throw this.logger.error("SessionDescriptionHandler.getDescription failed - "+o),o})}hasDescription(e){return this.logger.debug("SessionDescriptionHandler.hasDescription"),e==="application/sdp"}iceGatheringComplete(){this.logger.debug("SessionDescriptionHandler.iceGatheringComplete"),this.iceGatheringCompleteTimeoutId!==void 0&&(this.logger.debug("SessionDescriptionHandler.iceGatheringComplete - clearing timeout"),clearTimeout(this.iceGatheringCompleteTimeoutId),this.iceGatheringCompleteTimeoutId=void 0),this.iceGatheringCompletePromise!==void 0&&(this.logger.debug("SessionDescriptionHandler.iceGatheringComplete - resolving promise"),this.iceGatheringCompleteResolve&&this.iceGatheringCompleteResolve(),this.iceGatheringCompletePromise=void 0,this.iceGatheringCompleteResolve=void 0,this.iceGatheringCompleteReject=void 0)}sendDtmf(e,t){if(this.logger.debug("SessionDescriptionHandler.sendDtmf"),this._peerConnection===void 0)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - peer connection closed"),!1;const s=this._peerConnection.getSenders();if(s.length===0)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - no senders"),!1;const i=s[0].dtmf;if(!i)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - no DTMF sender"),!1;const r=t?.duration,n=t?.interToneGap;try{i.insertDTMF(e,r,n)}catch(o){return this.logger.error(o.toString()),!1}return this.logger.log("SessionDescriptionHandler.sendDtmf sent via RTP: "+e.toString()),!0}setDescription(e,t,s){if(this.logger.debug("SessionDescriptionHandler.setDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));this.onDataChannel=t?.onDataChannel;const i=this._peerConnection.signalingState==="have-local-offer"?"answer":"offer";return this.getLocalMediaStream(t).then(()=>this.applyModifiers({sdp:e,type:i},s)).then(r=>this.setRemoteSessionDescription(r)).catch(r=>{throw this.logger.error("SessionDescriptionHandler.setDescription failed - "+r),r})}applyModifiers(e,t){return this.logger.debug("SessionDescriptionHandler.applyModifiers"),!t||t.length===0?Promise.resolve(e):t.reduce((s,i)=>s.then(i),Promise.resolve(e)).then(s=>{if(this.logger.debug("SessionDescriptionHandler.applyModifiers - modified sdp"),!s.sdp||!s.type)throw new Error("Invalid SDP.");return{sdp:s.sdp,type:s.type}})}createDataChannel(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));if(e?.dataChannel!==!0||this._dataChannel)return Promise.resolve();switch(this._peerConnection.signalingState){case"stable":this.logger.debug("SessionDescriptionHandler.createDataChannel - creating data channel");try{return this._dataChannel=this._peerConnection.createDataChannel(e?.dataChannelLabel||"",e?.dataChannelOptions),this.onDataChannel&&this.onDataChannel(this._dataChannel),Promise.resolve()}catch(t){return Promise.reject(t)}case"have-remote-offer":return Promise.resolve();default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}}createLocalOfferOrAnswer(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));switch(this._peerConnection.signalingState){case"stable":return this.logger.debug("SessionDescriptionHandler.createLocalOfferOrAnswer - creating SDP offer"),this._peerConnection.createOffer(e?.offerOptions);case"have-remote-offer":return this.logger.debug("SessionDescriptionHandler.createLocalOfferOrAnswer - creating SDP answer"),this._peerConnection.createAnswer(e?.answerOptions);default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}}getLocalMediaStream(e){if(this.logger.debug("SessionDescriptionHandler.getLocalMediaStream"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));let t=Object.assign({},e?.constraints);if(this.localMediaStreamConstraints){if(t.audio=t.audio||this.localMediaStreamConstraints.audio,t.video=t.video||this.localMediaStreamConstraints.video,JSON.stringify(this.localMediaStreamConstraints.audio)===JSON.stringify(t.audio)&&JSON.stringify(this.localMediaStreamConstraints.video)===JSON.stringify(t.video))return Promise.resolve()}else t.audio===void 0&&t.video===void 0&&(t={audio:!0});return this.localMediaStreamConstraints=t,this.mediaStreamFactory(t,this,e).then(s=>this.setLocalMediaStream(s))}setLocalMediaStream(e){if(this.logger.debug("SessionDescriptionHandler.setLocalMediaStream"),!this._peerConnection)throw new Error("Peer connection undefined.");const t=this._peerConnection,s=this._localMediaStream,i=[],r=d=>{const p=d.kind;if(p!=="audio"&&p!=="video")throw new Error(`Unknown new track kind ${p}.`);const g=t.getSenders().find(w=>w.track&&w.track.kind===p);g?i.push(new Promise(w=>{this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${p} track`),w()}).then(()=>g.replaceTrack(d).then(()=>{const w=s.getTracks().find(S=>S.kind===p);w&&(w.stop(),s.removeTrack(w),F.dispatchRemoveTrackEvent(s,w)),s.addTrack(d),F.dispatchAddTrackEvent(s,d)}).catch(w=>{throw this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to replace sender ${p} track`),w}))):i.push(new Promise(w=>{this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - adding sender ${p} track`),w()}).then(()=>{try{t.addTrack(d,s)}catch(w){throw this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${p} track`),w}s.addTrack(d),F.dispatchAddTrackEvent(s,d)}))},n=e.getAudioTracks();n.length&&r(n[0]);const o=e.getVideoTracks();return o.length&&r(o[0]),i.reduce((d,p)=>d.then(()=>p),Promise.resolve())}getLocalSessionDescription(){if(this.logger.debug("SessionDescriptionHandler.getLocalSessionDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));const e=this._peerConnection.localDescription;return e?Promise.resolve(e):Promise.reject(new Error("Failed to get local session description"))}setLocalSessionDescription(e){return this.logger.debug("SessionDescriptionHandler.setLocalSessionDescription"),this._peerConnection===void 0?Promise.reject(new Error("Peer connection closed.")):this._peerConnection.setLocalDescription(e)}setRemoteSessionDescription(e){if(this.logger.debug("SessionDescriptionHandler.setRemoteSessionDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));const t=e.sdp;let s;switch(this._peerConnection.signalingState){case"stable":s="offer";break;case"have-local-offer":s="answer";break;default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}return t?this._peerConnection.setRemoteDescription({sdp:t,type:s}):(this.logger.error("SessionDescriptionHandler.setRemoteSessionDescription failed - cannot set null sdp"),Promise.reject(new Error("SDP is undefined")))}setRemoteTrack(e){this.logger.debug("SessionDescriptionHandler.setRemoteTrack");const t=this._remoteMediaStream;t.getTrackById(e.id)?this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - have remote ${e.kind} track`):e.kind==="audio"?(this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - adding remote ${e.kind} track`),t.getAudioTracks().forEach(s=>{s.stop(),t.removeTrack(s),F.dispatchRemoveTrackEvent(t,s)}),t.addTrack(e),F.dispatchAddTrackEvent(t,e)):e.kind==="video"&&(this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - adding remote ${e.kind} track`),t.getVideoTracks().forEach(s=>{s.stop(),t.removeTrack(s),F.dispatchRemoveTrackEvent(t,s)}),t.addTrack(e),F.dispatchAddTrackEvent(t,e))}updateDirection(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));switch(this._peerConnection.signalingState){case"stable":this.logger.debug("SessionDescriptionHandler.updateDirection - setting offer direction");{const t=s=>{switch(s){case"inactive":return e?.hold?"inactive":"recvonly";case"recvonly":return e?.hold?"inactive":"recvonly";case"sendonly":return e?.hold?"sendonly":"sendrecv";case"sendrecv":return e?.hold?"sendonly":"sendrecv";case"stopped":return"stopped";default:throw new Error("Should never happen")}};this._peerConnection.getTransceivers().forEach(s=>{if(s.direction){const i=t(s.direction);s.direction!==i&&(s.direction=i)}})}break;case"have-remote-offer":this.logger.debug("SessionDescriptionHandler.updateDirection - setting answer direction");{const t=(()=>{const i=this._peerConnection.remoteDescription;if(!i)throw new Error("Failed to read remote offer");const r=/a=sendrecv\r\n|a=sendonly\r\n|a=recvonly\r\n|a=inactive\r\n/.exec(i.sdp);if(r)switch(r[0]){case`a=inactive\r
48
+ `,this.send(p).catch(g=>{this.logTransportError(g,"Failed to send ACK to non-2xx response.")})}stateTransition(e,t=!1){const s=()=>{throw new Error(`Invalid state transition from ${this.state} to ${e}`)};switch(e){case u.Calling:s();break;case u.Proceeding:this.state!==u.Calling&&s();break;case u.Accepted:case u.Completed:this.state!==u.Calling&&this.state!==u.Proceeding&&s();break;case u.Terminated:this.state!==u.Calling&&this.state!==u.Accepted&&this.state!==u.Completed&&(t||s());break;default:s()}this.B&&(clearTimeout(this.B),this.B=void 0),u.Proceeding,e===u.Completed&&(this.D=setTimeout(()=>this.timerD(),H.TIMER_D)),e===u.Accepted&&(this.M=setTimeout(()=>this.timerM(),H.TIMER_M)),e===u.Terminated&&this.dispose(),this.setState(e)}timerA(){}timerB(){this.logger.debug(`Timer B expired for INVITE client transaction ${this.id}.`),this.state===u.Calling&&(this.onRequestTimeout(),this.stateTransition(u.Terminated))}timerD(){this.logger.debug(`Timer D expired for INVITE client transaction ${this.id}.`),this.state===u.Completed&&this.stateTransition(u.Terminated)}timerM(){this.logger.debug(`Timer M expired for INVITE client transaction ${this.id}.`),this.state===u.Accepted&&this.stateTransition(u.Terminated)}}class q{constructor(e,t,s,i){this.transactionConstructor=e,this.core=t,this.message=s,this.delegate=i,this.challenged=!1,this.stale=!1,this.logger=this.loggerFactory.getLogger("sip.user-agent-client"),this.init()}dispose(){this.transaction.dispose()}get loggerFactory(){return this.core.loggerFactory}get transaction(){if(!this._transaction)throw new Error("Transaction undefined.");return this._transaction}cancel(e,t={}){if(!this.transaction)throw new Error("Transaction undefined.");if(!this.message.to)throw new Error("To undefined.");if(!this.message.from)throw new Error("From undefined.");const s=this.core.makeOutgoingRequestMessage(y.CANCEL,this.message.ruri,this.message.from.uri,this.message.to.uri,{toTag:this.message.toTag,fromTag:this.message.fromTag,callId:this.message.callId,cseq:this.message.cseq},t.extraHeaders);return s.branch=this.message.branch,this.message.headers.Route&&(s.headers.Route=this.message.headers.Route),e&&s.setHeader("Reason",e),this.transaction.state===u.Proceeding?new q(U,this.core,s):this.transaction.addStateChangeListener(()=>{this.transaction&&this.transaction.state===u.Proceeding&&new q(U,this.core,s)},{once:!0}),s}authenticationGuard(e,t){const s=e.statusCode;if(!s)throw new Error("Response status code undefined.");if(s!==401&&s!==407)return!0;let i,r;if(s===401?(i=e.parseHeader("www-authenticate"),r="authorization"):(i=e.parseHeader("proxy-authenticate"),r="proxy-authorization"),!i)return this.logger.warn(s+" with wrong or missing challenge, cannot authenticate"),!0;if(this.challenged&&(this.stale||i.stale!==!0))return this.logger.warn(s+" apparently in authentication loop, cannot authenticate"),!0;if(!this.credentials&&(this.credentials=this.core.configuration.authenticationFactory(),!this.credentials))return this.logger.warn("Unable to obtain credentials, cannot authenticate"),!0;if(!this.credentials.authenticate(this.message,i))return!0;this.challenged=!0,i.stale&&(this.stale=!0);let n=this.message.cseq+=1;return t&&t.localSequenceNumber&&(t.incrementLocalSequenceNumber(),n=this.message.cseq=t.localSequenceNumber),this.message.setHeader("cseq",n+" "+this.message.method),this.message.setHeader(r,this.credentials.toString()),this.init(),!1}onRequestTimeout(){this.logger.warn("User agent client request timed out. Generating internal 408 Request Timeout.");const e=new Q;e.statusCode=408,e.reasonPhrase="Request Timeout",this.receiveResponse(e)}onTransportError(e){this.logger.error(e.message),this.logger.error("User agent client request transport error. Generating internal 503 Service Unavailable.");const t=new Q;t.statusCode=503,t.reasonPhrase="Service Unavailable",this.receiveResponse(t)}receiveResponse(e){if(!this.authenticationGuard(e))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});break;case/^1[0-9]{2}$/.test(t):this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e});break;case/^2[0-9]{2}$/.test(t):this.delegate&&this.delegate.onAccept&&this.delegate.onAccept({message:e});break;case/^3[0-9]{2}$/.test(t):this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});break;case/^[4-6][0-9]{2}$/.test(t):this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});break;default:throw new Error(`Invalid status code ${t}`)}}init(){const e={loggerFactory:this.loggerFactory,onRequestTimeout:()=>this.onRequestTimeout(),onStateChange:i=>{i===u.Terminated&&(this.core.userAgentClients.delete(s),t===this._transaction&&this.dispose())},onTransportError:i=>this.onTransportError(i),receiveResponse:i=>this.receiveResponse(i)},t=new this.transactionConstructor(this.message,this.core.transport,e);this._transaction=t;const s=t.id+t.request.method;this.core.userAgentClients.set(s,this)}}class Ct extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.BYE,s);super(U,e.userAgentCore,i,t),e.dispose()}}class L extends Ze{constructor(e,t,s){super(e,t,s,u.Trying,"sip.transaction.nist")}dispose(){this.J&&(clearTimeout(this.J),this.J=void 0),super.dispose()}get kind(){return"nist"}receiveRequest(e){switch(this.state){case u.Trying:break;case u.Proceeding:if(!this.lastResponse)throw new Error("Last response undefined.");this.send(this.lastResponse).catch(t=>{this.logTransportError(t,"Failed to send retransmission of provisional response.")});break;case u.Completed:if(!this.lastResponse)throw new Error("Last response undefined.");this.send(this.lastResponse).catch(t=>{this.logTransportError(t,"Failed to send retransmission of final response.")});break;case u.Terminated:break;default:throw new Error(`Invalid state ${this.state}`)}}receiveResponse(e,t){if(e<100||e>699)throw new Error(`Invalid status code ${e}`);if(e>100&&e<=199)throw new Error("Provisional response other than 100 not allowed.");switch(this.state){case u.Trying:if(this.lastResponse=t,e>=100&&e<200){this.stateTransition(u.Proceeding),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send provisional response.")});return}if(e>=200&&e<=699){this.stateTransition(u.Completed),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send final response.")});return}break;case u.Proceeding:if(this.lastResponse=t,e>=200&&e<=699){this.stateTransition(u.Completed),this.send(t).catch(i=>{this.logTransportError(i,"Failed to send final response.")});return}break;case u.Completed:return;case u.Terminated:break;default:throw new Error(`Invalid state ${this.state}`)}const s=`Non-INVITE server transaction received unexpected ${e} response from TU while in state ${this.state}.`;throw this.logger.error(s),new Error(s)}onTransportError(e){this.user.onTransportError&&this.user.onTransportError(e),this.stateTransition(u.Terminated,!0)}typeToString(){return"non-INVITE server transaction"}stateTransition(e,t=!1){const s=()=>{throw new Error(`Invalid state transition from ${this.state} to ${e}`)};switch(e){case u.Trying:s();break;case u.Proceeding:this.state!==u.Trying&&s();break;case u.Completed:this.state!==u.Trying&&this.state!==u.Proceeding&&s();break;case u.Terminated:this.state!==u.Proceeding&&this.state!==u.Completed&&(t||s());break;default:s()}e===u.Completed&&(this.J=setTimeout(()=>this.timerJ(),H.TIMER_J)),e===u.Terminated&&this.dispose(),this.setState(e)}timerJ(){this.logger.debug(`Timer J expired for NON-INVITE server transaction ${this.id}.`),this.state===u.Completed&&this.stateTransition(u.Terminated)}}class z{constructor(e,t,s,i){this.transactionConstructor=e,this.core=t,this.message=s,this.delegate=i,this.logger=this.loggerFactory.getLogger("sip.user-agent-server"),this.toTag=s.toTag?s.toTag:Te(),this.init()}dispose(){this.transaction.dispose()}get loggerFactory(){return this.core.loggerFactory}get transaction(){if(!this._transaction)throw new Error("Transaction undefined.");return this._transaction}accept(e={statusCode:200}){if(!this.acceptable)throw new ee(`${this.message.method} not acceptable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<200||t>299)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}progress(e={statusCode:180}){if(!this.progressable)throw new ee(`${this.message.method} not progressable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<101||t>199)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}redirect(e,t={statusCode:302}){if(!this.redirectable)throw new ee(`${this.message.method} not redirectable in state ${this.transaction.state}.`);const s=t.statusCode;if(s<300||s>399)throw new TypeError(`Invalid statusCode: ${s}`);const i=new Array;return e.forEach(n=>i.push(`Contact: ${n.toString()}`)),t.extraHeaders=(t.extraHeaders||[]).concat(i),this.reply(t)}reject(e={statusCode:480}){if(!this.rejectable)throw new ee(`${this.message.method} not rejectable in state ${this.transaction.state}.`);const t=e.statusCode;if(t<400||t>699)throw new TypeError(`Invalid statusCode: ${t}`);return this.reply(e)}trying(e){if(!this.tryingable)throw new ee(`${this.message.method} not tryingable in state ${this.transaction.state}.`);return this.reply({statusCode:100})}receiveCancel(e){this.delegate&&this.delegate.onCancel&&this.delegate.onCancel(e)}get acceptable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding||this.transaction.state===u.Accepted;if(this.transaction instanceof L)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get progressable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof L)return!1;throw new Error("Unknown transaction type.")}get redirectable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof L)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get rejectable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof L)return this.transaction.state===u.Trying||this.transaction.state===u.Proceeding;throw new Error("Unknown transaction type.")}get tryingable(){if(this.transaction instanceof N)return this.transaction.state===u.Proceeding;if(this.transaction instanceof L)return this.transaction.state===u.Trying;throw new Error("Unknown transaction type.")}reply(e){!e.toTag&&e.statusCode!==100&&(e.toTag=this.toTag),e.userAgent=e.userAgent||this.core.configuration.userAgentHeaderFieldValue,e.supported=e.supported||this.core.configuration.supportedOptionTagsResponse;const t=ze(this.message,e);return this.transaction.receiveResponse(e.statusCode,t.message),t}init(){const e={loggerFactory:this.loggerFactory,onStateChange:i=>{i===u.Terminated&&(this.core.userAgentServers.delete(s),this.dispose())},onTransportError:i=>{this.logger.error(i.message),this.delegate&&this.delegate.onTransportError?this.delegate.onTransportError(i):this.logger.error("User agent server response transport error.")}},t=new this.transactionConstructor(this.message,this.core.transport,e);this._transaction=t;const s=t.id;this.core.userAgentServers.set(t.id,this)}}class xt extends z{constructor(e,t,s){super(L,e.userAgentCore,t,s)}}class Rt extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.INFO,s);super(U,e.userAgentCore,i,t)}}class It extends z{constructor(e,t,s){super(L,e.userAgentCore,t,s)}}class Xe extends q{constructor(e,t,s){super(U,e,t,s)}}class Qe extends z{constructor(e,t,s){super(L,e,t,s)}}class At extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.NOTIFY,s);super(U,e.userAgentCore,i,t)}}function $t(a){return a.userAgentCore!==void 0}class Ie extends z{constructor(e,t,s){const i=$t(e)?e.userAgentCore:e;super(L,i,t,s)}}class _t extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.PRACK,s);super(U,e.userAgentCore,i,t),e.signalingStateTransition(i)}}class Dt extends z{constructor(e,t,s){super(L,e.userAgentCore,t,s),e.signalingStateTransition(t),this.dialog=e}accept(e={statusCode:200}){return e.body&&this.dialog.signalingStateTransition(e.body),super.accept(e)}}class kt extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.INVITE,s);super(ie,e.userAgentCore,i,t),this.delegate=t,e.signalingStateTransition(i),e.reinviteUserAgentClient=this,this.dialog=e}receiveResponse(e){if(!this.authenticationGuard(e,this.dialog))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});break;case/^1[0-9]{2}$/.test(t):this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e,session:this.dialog,prack:s=>{throw new Error("Unimplemented.")}});break;case/^2[0-9]{2}$/.test(t):this.dialog.signalingStateTransition(e),this.delegate&&this.delegate.onAccept&&this.delegate.onAccept({message:e,session:this.dialog,ack:s=>this.dialog.ack(s)});break;case/^3[0-9]{2}$/.test(t):this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentClient=void 0,this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});break;case/^[4-6][0-9]{2}$/.test(t):this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentClient=void 0,this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});break;default:throw new Error(`Invalid status code ${t}`)}}}class Pt extends z{constructor(e,t,s){super(N,e.userAgentCore,t,s),e.reinviteUserAgentServer=this,this.dialog=e}accept(e={statusCode:200}){e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(this.dialog.routeSet.map(r=>`Record-Route: ${r}`));const t=super.accept(e),s=this.dialog,i=Object.assign(Object.assign({},t),{session:s});return e.body&&this.dialog.signalingStateTransition(e.body),this.dialog.reConfirm(),i}progress(e={statusCode:180}){const t=super.progress(e),s=this.dialog,i=Object.assign(Object.assign({},t),{session:s});return e.body&&this.dialog.signalingStateTransition(e.body),i}redirect(e,t={statusCode:302}){throw this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentServer=void 0,new Error("Unimplemented.")}reject(e={statusCode:488}){return this.dialog.signalingStateRollback(),this.dialog.reinviteUserAgentServer=void 0,super.reject(e)}}class Ht extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.REFER,s);super(U,e.userAgentCore,i,t)}}function Mt(a){return a.userAgentCore!==void 0}class et extends z{constructor(e,t,s){const i=Mt(e)?e.userAgentCore:e;super(L,i,t,s)}}class Ae extends ge{constructor(e,t,s,i){super(t,s),this.initialTransaction=e,this._signalingState=v.Initial,this.ackWait=!1,this.ackProcessing=!1,this.delegate=i,e instanceof N&&(this.ackWait=!0),this.early||this.start2xxRetransmissionTimer(),this.signalingStateTransition(e.request),this.logger=t.loggerFactory.getLogger("sip.invite-dialog"),this.logger.log(`INVITE dialog ${this.id} constructed`)}dispose(){super.dispose(),this._signalingState=v.Closed,this._offer=void 0,this._answer=void 0,this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.logger.log(`INVITE dialog ${this.id} destroyed`)}get sessionState(){return this.early?B.Early:this.ackWait?B.AckWait:this._signalingState===v.Closed?B.Terminated:B.Confirmed}get signalingState(){return this._signalingState}get offer(){return this._offer}get answer(){return this._answer}confirm(){this.early&&this.start2xxRetransmissionTimer(),super.confirm()}reConfirm(){this.reinviteUserAgentServer&&this.startReInvite2xxRetransmissionTimer()}ack(e={}){this.logger.log(`INVITE dialog ${this.id} sending ACK request`);let t;if(this.reinviteUserAgentClient){if(!(this.reinviteUserAgentClient.transaction instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");t=this.reinviteUserAgentClient.transaction,this.reinviteUserAgentClient=void 0}else{if(!(this.initialTransaction instanceof ie))throw new Error("Initial transaction not instance of InviteClientTransaction.");t=this.initialTransaction}const s=this.createOutgoingRequestMessage(y.ACK,{cseq:t.request.cseq,extraHeaders:e.extraHeaders,body:e.body});return t.ackResponse(s),this.signalingStateTransition(s),{message:s}}bye(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending BYE request`),this.initialTransaction instanceof N){if(this.early)throw new Error("UAS MUST NOT send a BYE on early dialogs.");if(this.ackWait&&this.initialTransaction.state!==u.Terminated)throw new Error("UAS MUST NOT send a BYE on a confirmed dialog until it has received an ACK for its 2xx response or until the server transaction times out.")}return new Ct(this,e,t)}info(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending INFO request`),this.early)throw new Error("Dialog not confirmed.");return new Rt(this,e,t)}invite(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending INVITE request`),this.early)throw new Error("Dialog not confirmed.");if(this.reinviteUserAgentClient)throw new Error("There is an ongoing re-INVITE client transaction.");if(this.reinviteUserAgentServer)throw new Error("There is an ongoing re-INVITE server transaction.");return new kt(this,e,t)}message(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending MESSAGE request`),this.early)throw new Error("Dialog not confirmed.");const s=this.createOutgoingRequestMessage(y.MESSAGE,t);return new Xe(this.core,s,e)}notify(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending NOTIFY request`),this.early)throw new Error("Dialog not confirmed.");return new At(this,e,t)}prack(e,t){return this.logger.log(`INVITE dialog ${this.id} sending PRACK request`),new _t(this,e,t)}refer(e,t){if(this.logger.log(`INVITE dialog ${this.id} sending REFER request`),this.early)throw new Error("Dialog not confirmed.");return new Ht(this,e,t)}receiveRequest(e){if(this.logger.log(`INVITE dialog ${this.id} received ${e.method} request`),e.method===y.ACK){if(this.ackWait){if(this.initialTransaction instanceof ie){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}if(this.initialTransaction.request.cseq!==e.cseq){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}this.ackWait=!1}else{if(!this.reinviteUserAgentServer){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}if(this.reinviteUserAgentServer.transaction.request.cseq!==e.cseq){this.logger.warn(`INVITE dialog ${this.id} received unexpected ${e.method} request, dropping.`);return}this.reinviteUserAgentServer=void 0}if(this.signalingStateTransition(e),this.delegate&&this.delegate.onAck){const t=this.delegate.onAck({message:e});t instanceof Promise&&(this.ackProcessing=!0,t.then(()=>this.ackProcessing=!1).catch(()=>this.ackProcessing=!1))}return}if(!this.sequenceGuard(e)){this.logger.log(`INVITE dialog ${this.id} rejected out of order ${e.method} request.`);return}if(super.receiveRequest(e),e.method===y.INVITE){const t=()=>{const r=this.ackWait?"waiting for initial ACK":"processing initial ACK";this.logger.warn(`INVITE dialog ${this.id} received re-INVITE while ${r}`);let n="RFC 5407 suggests the following to avoid this race condition... ";n+=" Note: Implementation issues are outside the scope of this document,",n+=" but the following tip is provided for avoiding race conditions of",n+=" this type. The caller can delay sending re-INVITE F6 for some period",n+=" of time (2 seconds, perhaps), after which the caller can reasonably",n+=" assume that its ACK has been received. Implementors can decouple the",n+=" actions of the user (e.g., pressing the hold button) from the actions",n+=" of the protocol (the sending of re-INVITE F6), so that the UA can",n+=" behave like this. In this case, it is the implementor's choice as to",n+=" how long to wait. In most cases, such an implementation may be",n+=" useful to prevent the type of race condition shown in this section.",n+=" This document expresses no preference about whether or not they",n+=" should wait for an ACK to be delivered. After considering the impact",n+=" on user experience, implementors should decide whether or not to wait",n+=" for a while, because the user experience depends on the",n+=" implementation and has no direct bearing on protocol behavior.",this.logger.warn(n)},i=[`Retry-After: ${Math.floor(Math.random()*10)+1}`];if(this.ackProcessing){this.core.replyStateless(e,{statusCode:500,extraHeaders:i}),t();return}if(this.ackWait&&this.signalingState!==v.Stable){this.core.replyStateless(e,{statusCode:500,extraHeaders:i}),t();return}if(this.reinviteUserAgentServer){this.core.replyStateless(e,{statusCode:500,extraHeaders:i});return}if(this.reinviteUserAgentClient){this.core.replyStateless(e,{statusCode:491});return}}if(e.method===y.INVITE){const t=e.parseHeader("contact");if(!t)throw new Error("Contact undefined.");if(!(t instanceof O))throw new Error("Contact not instance of NameAddrHeader.");this.dialogState.remoteTarget=t.uri}switch(e.method){case y.BYE:{const t=new xt(this,e);this.delegate&&this.delegate.onBye?this.delegate.onBye(t):t.accept(),this.dispose()}break;case y.INFO:{const t=new It(this,e);this.delegate&&this.delegate.onInfo?this.delegate.onInfo(t):t.reject({statusCode:469,extraHeaders:["Recv-Info:"]})}break;case y.INVITE:{const t=new Pt(this,e);this.signalingStateTransition(e),this.delegate&&this.delegate.onInvite?this.delegate.onInvite(t):t.reject({statusCode:488})}break;case y.MESSAGE:{const t=new Qe(this.core,e);this.delegate&&this.delegate.onMessage?this.delegate.onMessage(t):t.accept()}break;case y.NOTIFY:{const t=new Ie(this,e);this.delegate&&this.delegate.onNotify?this.delegate.onNotify(t):t.accept()}break;case y.PRACK:{const t=new Dt(this,e);this.delegate&&this.delegate.onPrack?this.delegate.onPrack(t):t.accept()}break;case y.REFER:{const t=new et(this,e);this.delegate&&this.delegate.onRefer?this.delegate.onRefer(t):t.reject()}break;default:this.logger.log(`INVITE dialog ${this.id} received unimplemented ${e.method} request`),this.core.replyStateless(e,{statusCode:501});break}}reliableSequenceGuard(e){const t=e.statusCode;if(!t)throw new Error("Status code undefined");if(t>100&&t<200){const s=e.getHeader("require"),i=e.getHeader("rseq"),r=s&&s.includes("100rel")&&i?Number(i):void 0;if(r){if(this.rseq&&this.rseq+1!==r)return!1;this.rseq=this.rseq?this.rseq+1:r}}return!0}signalingStateRollback(){(this._signalingState===v.HaveLocalOffer||this.signalingState===v.HaveRemoteOffer)&&this._rollbackOffer&&this._rollbackAnswer&&(this._signalingState=v.Stable,this._offer=this._rollbackOffer,this._answer=this._rollbackAnswer)}signalingStateTransition(e){const t=be(e);if(!(!t||t.contentDisposition!=="session")){if(this._signalingState===v.Stable&&(this._rollbackOffer=this._offer,this._rollbackAnswer=this._answer),e instanceof he)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveRemoteOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:this._signalingState=v.Stable,this._answer=t;break;case v.HaveRemoteOffer:break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(e instanceof Q)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveRemoteOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:this._signalingState=v.Stable,this._answer=t;break;case v.HaveRemoteOffer:break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(e instanceof ae)switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveLocalOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:break;case v.HaveRemoteOffer:this._signalingState=v.Stable,this._answer=t;break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}if(Ve(e))switch(this._signalingState){case v.Initial:case v.Stable:this._signalingState=v.HaveLocalOffer,this._offer=t,this._answer=void 0;break;case v.HaveLocalOffer:break;case v.HaveRemoteOffer:this._signalingState=v.Stable,this._answer=t;break;case v.Closed:break;default:throw new Error("Unexpected signaling state.")}}}start2xxRetransmissionTimer(){if(this.initialTransaction instanceof N){const e=this.initialTransaction;let t=H.T1;const s=()=>{if(!this.ackWait){this.invite2xxTimer=void 0;return}this.logger.log("No ACK for 2xx response received, attempting retransmission"),e.retransmitAcceptedResponse(),t=Math.min(t*2,H.T2),this.invite2xxTimer=setTimeout(s,t)};this.invite2xxTimer=setTimeout(s,t);const i=()=>{e.state===u.Terminated&&(e.removeStateChangeListener(i),this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.ackWait&&(this.delegate&&this.delegate.onAckTimeout?this.delegate.onAckTimeout():this.bye()))};e.addStateChangeListener(i)}}startReInvite2xxRetransmissionTimer(){if(this.reinviteUserAgentServer&&this.reinviteUserAgentServer.transaction instanceof N){const e=this.reinviteUserAgentServer.transaction;let t=H.T1;const s=()=>{if(!this.reinviteUserAgentServer){this.invite2xxTimer=void 0;return}this.logger.log("No ACK for 2xx response received, attempting retransmission"),e.retransmitAcceptedResponse(),t=Math.min(t*2,H.T2),this.invite2xxTimer=setTimeout(s,t)};this.invite2xxTimer=setTimeout(s,t);const i=()=>{e.state===u.Terminated&&(e.removeStateChangeListener(i),this.invite2xxTimer&&(clearTimeout(this.invite2xxTimer),this.invite2xxTimer=void 0),this.reinviteUserAgentServer)};e.addStateChangeListener(i)}}}class qt extends q{constructor(e,t,s){super(ie,e,t,s),this.confirmedDialogAcks=new Map,this.confirmedDialogs=new Map,this.earlyDialogs=new Map,this.delegate=s}dispose(){this.earlyDialogs.forEach(e=>e.dispose()),this.earlyDialogs.clear(),super.dispose()}onTransportError(e){if(this.transaction.state===u.Calling)return super.onTransportError(e);this.logger.error(e.message),this.logger.error("User agent client request transport error while sending ACK.")}receiveResponse(e){if(!this.authenticationGuard(e))return;const t=e.statusCode?e.statusCode.toString():"";if(!t)throw new Error("Response status code undefined.");switch(!0){case/^100$/.test(t):this.delegate&&this.delegate.onTrying&&this.delegate.onTrying({message:e});return;case/^1[0-9]{2}$/.test(t):{if(!e.toTag){this.logger.warn("Non-100 1xx INVITE response received without a to tag, dropping.");return}if(!e.parseHeader("contact")){this.logger.error("Non-100 1xx INVITE response received without a Contact header field, dropping.");return}const i=ge.initialDialogStateForUserAgentClient(this.message,e);let r=this.earlyDialogs.get(i.id);if(!r){const o=this.transaction;if(!(o instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");r=new Ae(o,this.core,i),this.earlyDialogs.set(r.id,r)}if(!r.reliableSequenceGuard(e)){this.logger.warn("1xx INVITE reliable response received out of order or is a retransmission, dropping.");return}(r.signalingState===v.Initial||r.signalingState===v.HaveLocalOffer)&&r.signalingStateTransition(e);const n=r;this.delegate&&this.delegate.onProgress&&this.delegate.onProgress({message:e,session:n,prack:o=>n.prack(void 0,o)})}return;case/^2[0-9]{2}$/.test(t):{if(!e.toTag){this.logger.error("2xx INVITE response received without a to tag, dropping.");return}if(!e.parseHeader("contact")){this.logger.error("2xx INVITE response received without a Contact header field, dropping.");return}const i=ge.initialDialogStateForUserAgentClient(this.message,e);let r=this.confirmedDialogs.get(i.id);if(r){const o=this.confirmedDialogAcks.get(i.id);if(o){const d=this.transaction;if(!(d instanceof ie))throw new Error("Client transaction not instance of InviteClientTransaction.");d.ackResponse(o.message)}return}if(r=this.earlyDialogs.get(i.id),r)r.confirm(),r.recomputeRouteSet(e),this.earlyDialogs.delete(r.id),this.confirmedDialogs.set(r.id,r);else{const o=this.transaction;if(!(o instanceof ie))throw new Error("Transaction not instance of InviteClientTransaction.");r=new Ae(o,this.core,i),this.confirmedDialogs.set(r.id,r)}(r.signalingState===v.Initial||r.signalingState===v.HaveLocalOffer)&&r.signalingStateTransition(e);const n=r;if(this.delegate&&this.delegate.onAccept)this.delegate.onAccept({message:e,session:n,ack:o=>{const d=n.ack(o);return this.confirmedDialogAcks.set(n.id,d),d}});else{const o=n.ack();this.confirmedDialogAcks.set(n.id,o)}}return;case/^3[0-9]{2}$/.test(t):this.earlyDialogs.forEach(s=>s.dispose()),this.earlyDialogs.clear(),this.delegate&&this.delegate.onRedirect&&this.delegate.onRedirect({message:e});return;case/^[4-6][0-9]{2}$/.test(t):this.earlyDialogs.forEach(s=>s.dispose()),this.earlyDialogs.clear(),this.delegate&&this.delegate.onReject&&this.delegate.onReject({message:e});return;default:throw new Error(`Invalid status code ${t}`)}}}class Me extends z{constructor(e,t,s){super(N,e,t,s),this.core=e}dispose(){this.earlyDialog&&this.earlyDialog.dispose(),super.dispose()}accept(e={statusCode:200}){if(!this.acceptable)throw new ee(`${this.message.method} not acceptable in state ${this.transaction.state}.`);if(!this.confirmedDialog)if(this.earlyDialog)this.earlyDialog.confirm(),this.confirmedDialog=this.earlyDialog,this.earlyDialog=void 0;else{const d=this.transaction;if(!(d instanceof N))throw new Error("Transaction not instance of InviteClientTransaction.");const p=ge.initialDialogStateForUserAgentServer(this.message,this.toTag);this.confirmedDialog=new Ae(d,this.core,p)}const t=this.message.getHeaders("record-route").map(d=>`Record-Route: ${d}`),s=`Contact: ${this.core.configuration.contact.toString()}`,i="Allow: "+te.toString();if(!e.body){if(this.confirmedDialog.signalingState===v.Stable)e.body=this.confirmedDialog.answer;else if(this.confirmedDialog.signalingState===v.Initial||this.confirmedDialog.signalingState===v.HaveRemoteOffer)throw new Error("Response must have a body.")}e.statusCode=e.statusCode||200,e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(t),e.extraHeaders.push(i),e.extraHeaders.push(s);const r=super.accept(e),n=this.confirmedDialog,o=Object.assign(Object.assign({},r),{session:n});return e.body&&this.confirmedDialog.signalingState!==v.Stable&&this.confirmedDialog.signalingStateTransition(e.body),o}progress(e={statusCode:180}){if(!this.progressable)throw new ee(`${this.message.method} not progressable in state ${this.transaction.state}.`);if(!this.earlyDialog){const o=this.transaction;if(!(o instanceof N))throw new Error("Transaction not instance of InviteClientTransaction.");const d=ge.initialDialogStateForUserAgentServer(this.message,this.toTag,!0);this.earlyDialog=new Ae(o,this.core,d)}const t=this.message.getHeaders("record-route").map(o=>`Record-Route: ${o}`),s=`Contact: ${this.core.configuration.contact}`;e.extraHeaders=e.extraHeaders||[],e.extraHeaders=e.extraHeaders.concat(t),e.extraHeaders.push(s);const i=super.progress(e),r=this.earlyDialog,n=Object.assign(Object.assign({},i),{session:r});return e.body&&this.earlyDialog.signalingState!==v.Stable&&this.earlyDialog.signalingStateTransition(e.body),n}redirect(e,t={statusCode:302}){return super.redirect(e,t)}reject(e={statusCode:486}){return super.reject(e)}}class Ft extends q{constructor(e,t,s){super(U,e,t,s)}}class Ot extends q{constructor(e,t,s){super(U,e,t,s)}}class Nt extends z{constructor(e,t,s){super(L,e,t,s),this.core=e}}class Ut extends q{constructor(e,t,s){const i=e.createOutgoingRequestMessage(y.SUBSCRIBE,s);super(U,e.userAgentCore,i,t),this.dialog=e}waitNotifyStop(){}receiveResponse(e){if(e.statusCode&&e.statusCode>=200&&e.statusCode<300){const t=e.getHeader("Expires");if(!t)this.logger.warn("Expires header missing in a 200-class response to SUBSCRIBE");else{const s=Number(t);this.dialog.subscriptionExpires>s&&(this.dialog.subscriptionExpires=s)}}e.statusCode&&e.statusCode>=400&&e.statusCode<700&&[404,405,410,416,480,481,482,483,484,485,489,501,604].includes(e.statusCode)&&this.dialog.terminate(),super.receiveResponse(e)}}class tt extends ge{constructor(e,t,s,i,r,n){super(i,r),this.delegate=n,this._autoRefresh=!1,this._subscriptionEvent=e,this._subscriptionExpires=t,this._subscriptionExpiresInitial=t,this._subscriptionExpiresLastSet=Math.floor(Date.now()/1e3),this._subscriptionRefresh=void 0,this._subscriptionRefreshLastSet=void 0,this._subscriptionState=s,this.logger=i.loggerFactory.getLogger("sip.subscribe-dialog"),this.logger.log(`SUBSCRIBE dialog ${this.id} constructed`)}static initialDialogStateForSubscription(e,t){const i=t.getHeaders("record-route"),r=t.parseHeader("contact");if(!r)throw new Error("Contact undefined.");if(!(r instanceof O))throw new Error("Contact not instance of NameAddrHeader.");const n=r.uri,o=e.cseq,d=void 0,p=e.callId,g=e.fromTag,w=t.fromTag;if(!p)throw new Error("Call id undefined.");if(!g)throw new Error("From tag undefined.");if(!w)throw new Error("To tag undefined.");if(!e.from)throw new Error("From undefined.");if(!e.to)throw new Error("To undefined.");const S=e.from.uri,I=e.to.uri;return{id:p+g+w,early:!1,callId:p,localTag:g,remoteTag:w,localSequenceNumber:o,remoteSequenceNumber:d,localURI:S,remoteURI:I,remoteTarget:n,routeSet:i,secure:!1}}dispose(){super.dispose(),this.N&&(clearTimeout(this.N),this.N=void 0),this.refreshTimerClear(),this.logger.log(`SUBSCRIBE dialog ${this.id} destroyed`)}get autoRefresh(){return this._autoRefresh}set autoRefresh(e){this._autoRefresh=!0,this.refreshTimerSet()}get subscriptionEvent(){return this._subscriptionEvent}get subscriptionExpires(){const e=Math.floor(Date.now()/1e3)-this._subscriptionExpiresLastSet,t=this._subscriptionExpires-e;return Math.max(t,0)}set subscriptionExpires(e){if(e<0)throw new Error("Expires must be greater than or equal to zero.");if(this._subscriptionExpires=e,this._subscriptionExpiresLastSet=Math.floor(Date.now()/1e3),this.autoRefresh){const t=this.subscriptionRefresh;(t===void 0||t>=e)&&this.refreshTimerSet()}}get subscriptionExpiresInitial(){return this._subscriptionExpiresInitial}get subscriptionRefresh(){if(this._subscriptionRefresh===void 0||this._subscriptionRefreshLastSet===void 0)return;const e=Math.floor(Date.now()/1e3)-this._subscriptionRefreshLastSet,t=this._subscriptionRefresh-e;return Math.max(t,0)}get subscriptionState(){return this._subscriptionState}receiveRequest(e){if(this.logger.log(`SUBSCRIBE dialog ${this.id} received ${e.method} request`),!this.sequenceGuard(e)){this.logger.log(`SUBSCRIBE dialog ${this.id} rejected out of order ${e.method} request.`);return}super.receiveRequest(e),e.method===y.NOTIFY?this.onNotify(e):(this.logger.log(`SUBSCRIBE dialog ${this.id} received unimplemented ${e.method} request`),this.core.replyStateless(e,{statusCode:501}))}refresh(){const e="Allow: "+te.toString(),t={};return t.extraHeaders=(t.extraHeaders||[]).slice(),t.extraHeaders.push(e),t.extraHeaders.push("Event: "+this.subscriptionEvent),t.extraHeaders.push("Expires: "+this.subscriptionExpiresInitial),t.extraHeaders.push("Contact: "+this.core.configuration.contact.toString()),this.subscribe(void 0,t)}subscribe(e,t={}){var s;if(this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active)throw new Error(`Invalid state ${this.subscriptionState}. May only re-subscribe while in state "pending" or "active".`);this.logger.log(`SUBSCRIBE dialog ${this.id} sending SUBSCRIBE request`);const i=new Ut(this,e,t);return this.N&&(clearTimeout(this.N),this.N=void 0),!((s=t.extraHeaders)===null||s===void 0)&&s.includes("Expires: 0")||(this.N=setTimeout(()=>this.timerN(),H.TIMER_N)),i}terminate(){this.stateTransition(R.Terminated),this.onTerminated()}unsubscribe(){const e="Allow: "+te.toString(),t={};return t.extraHeaders=(t.extraHeaders||[]).slice(),t.extraHeaders.push(e),t.extraHeaders.push("Event: "+this.subscriptionEvent),t.extraHeaders.push("Expires: 0"),t.extraHeaders.push("Contact: "+this.core.configuration.contact.toString()),this.subscribe(void 0,t)}onNotify(e){const t=e.parseHeader("Event").event;if(!t||t!==this.subscriptionEvent){this.core.replyStateless(e,{statusCode:489});return}this.N&&(clearTimeout(this.N),this.N=void 0);const s=e.parseHeader("Subscription-State");if(!s||!s.state){this.core.replyStateless(e,{statusCode:489});return}const i=s.state,r=s.expires?Math.max(s.expires,0):void 0;switch(i){case"pending":this.stateTransition(R.Pending,r);break;case"active":this.stateTransition(R.Active,r);break;case"terminated":this.stateTransition(R.Terminated,r);break;default:this.logger.warn("Unrecognized subscription state.");break}const n=new Ie(this,e);this.delegate&&this.delegate.onNotify?this.delegate.onNotify(n):n.accept()}onRefresh(e){this.delegate&&this.delegate.onRefresh&&this.delegate.onRefresh(e)}onTerminated(){this.delegate&&this.delegate.onTerminated&&this.delegate.onTerminated()}refreshTimerClear(){this.refreshTimer&&(clearTimeout(this.refreshTimer),this.refreshTimer=void 0)}refreshTimerSet(){if(this.refreshTimerClear(),this.autoRefresh&&this.subscriptionExpires>0){const e=this.subscriptionExpires*900;this._subscriptionRefresh=Math.floor(e/1e3),this._subscriptionRefreshLastSet=Math.floor(Date.now()/1e3),this.refreshTimer=setTimeout(()=>{this.refreshTimer=void 0,this._subscriptionRefresh=void 0,this._subscriptionRefreshLastSet=void 0,this.onRefresh(this.refresh())},e)}}stateTransition(e,t){const s=()=>{this.logger.warn(`Invalid subscription state transition from ${this.subscriptionState} to ${e}`)};switch(e){case R.Initial:s();return;case R.NotifyWait:s();return;case R.Pending:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending){s();return}break;case R.Active:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active){s();return}break;case R.Terminated:if(this.subscriptionState!==R.NotifyWait&&this.subscriptionState!==R.Pending&&this.subscriptionState!==R.Active){s();return}break;default:s();return}e===R.Pending&&t&&(this.subscriptionExpires=t),e===R.Active&&t&&(this.subscriptionExpires=t),e===R.Terminated&&this.dispose(),this._subscriptionState=e}timerN(){this.logger.warn("Timer N expired for SUBSCRIBE dialog. Timed out waiting for NOTIFY."),this.subscriptionState!==R.Terminated&&(this.stateTransition(R.Terminated),this.onTerminated())}}class Lt extends q{constructor(e,t,s){const i=t.getHeader("Event");if(!i)throw new Error("Event undefined");const r=t.getHeader("Expires");if(!r)throw new Error("Expires undefined");super(U,e,t,s),this.delegate=s,this.subscriberId=t.callId+t.fromTag+i,this.subscriptionExpiresRequested=this.subscriptionExpires=Number(r),this.subscriptionEvent=i,this.subscriptionState=R.NotifyWait,this.waitNotifyStart()}dispose(){super.dispose()}onNotify(e){const t=e.message.parseHeader("Event").event;if(!t||t!==this.subscriptionEvent){this.logger.warn("Failed to parse event."),e.reject({statusCode:489});return}const s=e.message.parseHeader("Subscription-State");if(!s||!s.state){this.logger.warn("Failed to parse subscription state."),e.reject({statusCode:489});return}const i=s.state;switch(i){case"pending":break;case"active":break;case"terminated":break;default:this.logger.warn(`Invalid subscription state ${i}`),e.reject({statusCode:489});return}if(i!=="terminated"&&!e.message.parseHeader("contact")){this.logger.warn("Failed to parse contact."),e.reject({statusCode:489});return}if(this.dialog)throw new Error("Dialog already created. This implementation only supports install of single subscriptions.");switch(this.waitNotifyStop(),this.subscriptionExpires=s.expires?Math.min(this.subscriptionExpires,Math.max(s.expires,0)):this.subscriptionExpires,i){case"pending":this.subscriptionState=R.Pending;break;case"active":this.subscriptionState=R.Active;break;case"terminated":this.subscriptionState=R.Terminated;break;default:throw new Error(`Unrecognized state ${i}.`)}if(this.subscriptionState!==R.Terminated){const r=tt.initialDialogStateForSubscription(this.message,e.message);this.dialog=new tt(this.subscriptionEvent,this.subscriptionExpires,this.subscriptionState,this.core,r)}if(this.delegate&&this.delegate.onNotify){const r=e,n=this.dialog;this.delegate.onNotify({request:r,subscription:n})}else e.accept()}waitNotifyStart(){this.N||(this.core.subscribers.set(this.subscriberId,this),this.N=setTimeout(()=>this.timerN(),H.TIMER_N))}waitNotifyStop(){this.N&&(this.core.subscribers.delete(this.subscriberId),clearTimeout(this.N),this.N=void 0)}receiveResponse(e){if(this.authenticationGuard(e)){if(e.statusCode&&e.statusCode>=200&&e.statusCode<300){const t=e.getHeader("Expires");if(!t)this.logger.warn("Expires header missing in a 200-class response to SUBSCRIBE");else{const s=Number(t);s>this.subscriptionExpiresRequested&&this.logger.warn("Expires header in a 200-class response to SUBSCRIBE with a higher value than the one in the request"),s<this.subscriptionExpires&&(this.subscriptionExpires=s)}this.dialog&&this.dialog.subscriptionExpires>this.subscriptionExpires&&(this.dialog.subscriptionExpires=this.subscriptionExpires)}e.statusCode&&e.statusCode>=300&&e.statusCode<700&&this.waitNotifyStop(),super.receiveResponse(e)}}timerN(){this.logger.warn("Timer N expired for SUBSCRIBE user agent client. Timed out waiting for NOTIFY."),this.waitNotifyStop(),this.delegate&&this.delegate.onNotifyTimeout&&this.delegate.onNotifyTimeout()}}class Bt extends z{constructor(e,t,s){super(L,e,t,s),this.core=e}}const st=["application/sdp","application/dtmf-relay"];class jt{constructor(e,t={}){this.userAgentClients=new Map,this.userAgentServers=new Map,this.configuration=e,this.delegate=t,this.dialogs=new Map,this.subscribers=new Map,this.logger=e.loggerFactory.getLogger("sip.user-agent-core")}dispose(){this.reset()}reset(){this.dialogs.forEach(e=>e.dispose()),this.dialogs.clear(),this.subscribers.forEach(e=>e.dispose()),this.subscribers.clear(),this.userAgentClients.forEach(e=>e.dispose()),this.userAgentClients.clear(),this.userAgentServers.forEach(e=>e.dispose()),this.userAgentServers.clear()}get loggerFactory(){return this.configuration.loggerFactory}get transport(){const e=this.configuration.transportAccessor();if(!e)throw new Error("Transport undefined.");return e}invite(e,t){return new qt(this,e,t)}message(e,t){return new Xe(this,e,t)}publish(e,t){return new Ft(this,e,t)}register(e,t){return new Ot(this,e,t)}subscribe(e,t){return new Lt(this,e,t)}request(e,t){return new q(U,this,e,t)}makeOutgoingRequestMessage(e,t,s,i,r,n,o){const d=this.configuration.sipjsId,p=this.configuration.displayName,g=this.configuration.viaForceRport,w=this.configuration.hackViaTcp,S=this.configuration.supportedOptionTags.slice();e===y.REGISTER&&S.push("path","gruu"),e===y.INVITE&&(this.configuration.contact.pubGruu||this.configuration.contact.tempGruu)&&S.push("gruu");const I=this.configuration.routeSet,A=this.configuration.userAgentHeaderFieldValue,C=this.configuration.viaHost,f=Object.assign(Object.assign({},{callIdPrefix:d,forceRport:g,fromDisplayName:p,hackViaTcp:w,optionTags:S,routeSet:I,userAgentString:A,viaHost:C}),r);return new ae(e,t,s,i,f,n,o)}receiveIncomingRequestFromTransport(e){this.receiveRequestFromTransport(e)}receiveIncomingResponseFromTransport(e){this.receiveResponseFromTransport(e)}replyStateless(e,t){const s=this.configuration.userAgentHeaderFieldValue,i=this.configuration.supportedOptionTagsResponse;t=Object.assign(Object.assign({},t),{userAgent:s,supported:i});const r=ze(e,t);return this.transport.send(r.message).catch(n=>{n instanceof Error&&this.logger.error(n.message),this.logger.error(`Transport error occurred sending stateless reply to ${e.method} request.`)}),r}receiveRequestFromTransport(e){const t=e.viaBranch,s=this.userAgentServers.get(t);if(e.method===y.ACK&&s&&s.transaction.state===u.Accepted&&s instanceof Me){this.logger.warn(`Discarding out of dialog ACK after 2xx response sent on transaction ${t}.`);return}if(e.method===y.CANCEL){s?(this.replyStateless(e,{statusCode:200}),s.transaction instanceof N&&s.transaction.state===u.Proceeding&&s instanceof Me&&s.receiveCancel(e)):this.replyStateless(e,{statusCode:481});return}if(s){s.transaction.receiveRequest(e);return}this.receiveRequest(e)}receiveRequest(e){if(!te.includes(e.method)){const i="Allow: "+te.toString();this.replyStateless(e,{statusCode:405,extraHeaders:[i]});return}if(!e.ruri)throw new Error("Request-URI undefined.");if(e.ruri.scheme!=="sip"){this.replyStateless(e,{statusCode:416});return}const t=e.ruri,s=i=>!!i&&i.user===t.user;if(!s(this.configuration.aor)&&!(s(this.configuration.contact.uri)||s(this.configuration.contact.pubGruu)||s(this.configuration.contact.tempGruu))){this.logger.warn("Request-URI does not point to us."),e.method!==y.ACK&&this.replyStateless(e,{statusCode:404});return}if(e.method===y.INVITE&&!e.hasHeader("Contact")){this.replyStateless(e,{statusCode:400,reasonPhrase:"Missing Contact Header"});return}if(!e.toTag){const i=e.viaBranch;if(!this.userAgentServers.has(i)&&Array.from(this.userAgentServers.values()).some(n=>n.transaction.request.fromTag===e.fromTag&&n.transaction.request.callId===e.callId&&n.transaction.request.cseq===e.cseq)){this.replyStateless(e,{statusCode:482});return}}e.toTag?this.receiveInsideDialogRequest(e):this.receiveOutsideDialogRequest(e)}receiveInsideDialogRequest(e){if(e.method===y.NOTIFY){const i=e.parseHeader("Event");if(!i||!i.event){this.replyStateless(e,{statusCode:489});return}const r=e.callId+e.toTag+i.event,n=this.subscribers.get(r);if(n){const o=new Ie(this,e);n.onNotify(o);return}}const t=e.callId+e.toTag+e.fromTag,s=this.dialogs.get(t);if(s){if(e.method===y.OPTIONS){const i="Allow: "+te.toString(),r="Accept: "+st.toString();this.replyStateless(e,{statusCode:200,extraHeaders:[i,r]});return}s.receiveRequest(e);return}e.method!==y.ACK&&this.replyStateless(e,{statusCode:481})}receiveOutsideDialogRequest(e){switch(e.method){case y.ACK:break;case y.BYE:this.replyStateless(e,{statusCode:481});break;case y.CANCEL:throw new Error(`Unexpected out of dialog request method ${e.method}.`);case y.INFO:this.replyStateless(e,{statusCode:405});break;case y.INVITE:{const t=new Me(this,e);this.delegate.onInvite?this.delegate.onInvite(t):t.reject()}break;case y.MESSAGE:{const t=new Qe(this,e);this.delegate.onMessage?this.delegate.onMessage(t):t.accept()}break;case y.NOTIFY:{const t=new Ie(this,e);this.delegate.onNotify?this.delegate.onNotify(t):t.reject({statusCode:405})}break;case y.OPTIONS:{const t="Allow: "+te.toString(),s="Accept: "+st.toString();this.replyStateless(e,{statusCode:200,extraHeaders:[t,s]})}break;case y.REFER:{const t=new et(this,e);this.delegate.onRefer?this.delegate.onRefer(t):t.reject({statusCode:405})}break;case y.REGISTER:{const t=new Nt(this,e);this.delegate.onRegister?this.delegate.onRegister(t):t.reject({statusCode:405})}break;case y.SUBSCRIBE:{const t=new Bt(this,e);this.delegate.onSubscribe?this.delegate.onSubscribe(t):t.reject({statusCode:480})}break;default:throw new Error(`Unexpected out of dialog request method ${e.method}.`)}}receiveResponseFromTransport(e){if(e.getHeaders("via").length>1){this.logger.warn("More than one Via header field present in the response, dropping");return}const t=e.viaBranch+e.method,s=this.userAgentClients.get(t);s?s.transaction.receiveResponse(e):this.logger.warn(`Discarding unmatched ${e.statusCode} response to ${e.method} ${t}.`)}}function Gt(){return a=>!a.audio&&!a.video?Promise.resolve(new MediaStream):navigator.mediaDevices===void 0?Promise.reject(new Error("Media devices not available in insecure contexts.")):navigator.mediaDevices.getUserMedia.call(navigator.mediaDevices,a)}function Vt(){return{bundlePolicy:"balanced",certificates:void 0,iceCandidatePoolSize:0,iceServers:[{urls:"stun:stun.l.google.com:19302"}],iceTransportPolicy:"all",rtcpMuxPolicy:"require"}}class F{constructor(e,t,s){e.debug("SessionDescriptionHandler.constructor"),this.logger=e,this.mediaStreamFactory=t,this.sessionDescriptionHandlerConfiguration=s,this._localMediaStream=new MediaStream,this._remoteMediaStream=new MediaStream,this._peerConnection=new RTCPeerConnection(s?.peerConnectionConfiguration),this.initPeerConnectionEventHandlers()}get localMediaStream(){return this._localMediaStream}get remoteMediaStream(){return this._remoteMediaStream}get dataChannel(){return this._dataChannel}get peerConnection(){return this._peerConnection}get peerConnectionDelegate(){return this._peerConnectionDelegate}set peerConnectionDelegate(e){this._peerConnectionDelegate=e}static dispatchAddTrackEvent(e,t){e.dispatchEvent(new MediaStreamTrackEvent("addtrack",{track:t}))}static dispatchRemoveTrackEvent(e,t){e.dispatchEvent(new MediaStreamTrackEvent("removetrack",{track:t}))}close(){this.logger.debug("SessionDescriptionHandler.close"),this._peerConnection!==void 0&&(this._peerConnection.getReceivers().forEach(e=>{e.track&&e.track.stop()}),this._peerConnection.getSenders().forEach(e=>{e.track&&e.track.stop()}),this._dataChannel&&this._dataChannel.close(),this._peerConnection.close(),this._peerConnection=void 0)}enableReceiverTracks(e){const t=this.peerConnection;if(!t)throw new Error("Peer connection closed.");t.getReceivers().forEach(s=>{s.track&&(s.track.enabled=e)})}enableSenderTracks(e){const t=this.peerConnection;if(!t)throw new Error("Peer connection closed.");t.getSenders().forEach(s=>{s.track&&(s.track.enabled=e)})}getDescription(e,t){var s,i;if(this.logger.debug("SessionDescriptionHandler.getDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));this.onDataChannel=e?.onDataChannel;const r=(s=e?.offerOptions)===null||s===void 0?void 0:s.iceRestart,n=e?.iceGatheringTimeout===void 0?(i=this.sessionDescriptionHandlerConfiguration)===null||i===void 0?void 0:i.iceGatheringTimeout:e?.iceGatheringTimeout;return this.getLocalMediaStream(e).then(()=>this.updateDirection(e)).then(()=>this.createDataChannel(e)).then(()=>this.createLocalOfferOrAnswer(e)).then(o=>this.applyModifiers(o,t)).then(o=>this.setLocalSessionDescription(o)).then(()=>this.waitForIceGatheringComplete(r,n)).then(()=>this.getLocalSessionDescription()).then(o=>({body:o.sdp,contentType:"application/sdp"})).catch(o=>{throw this.logger.error("SessionDescriptionHandler.getDescription failed - "+o),o})}hasDescription(e){return this.logger.debug("SessionDescriptionHandler.hasDescription"),e==="application/sdp"}iceGatheringComplete(){this.logger.debug("SessionDescriptionHandler.iceGatheringComplete"),this.iceGatheringCompleteTimeoutId!==void 0&&(this.logger.debug("SessionDescriptionHandler.iceGatheringComplete - clearing timeout"),clearTimeout(this.iceGatheringCompleteTimeoutId),this.iceGatheringCompleteTimeoutId=void 0),this.iceGatheringCompletePromise!==void 0&&(this.logger.debug("SessionDescriptionHandler.iceGatheringComplete - resolving promise"),this.iceGatheringCompleteResolve&&this.iceGatheringCompleteResolve(),this.iceGatheringCompletePromise=void 0,this.iceGatheringCompleteResolve=void 0,this.iceGatheringCompleteReject=void 0)}sendDtmf(e,t){if(this.logger.debug("SessionDescriptionHandler.sendDtmf"),this._peerConnection===void 0)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - peer connection closed"),!1;const s=this._peerConnection.getSenders();if(s.length===0)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - no senders"),!1;const i=s[0].dtmf;if(!i)return this.logger.error("SessionDescriptionHandler.sendDtmf failed - no DTMF sender"),!1;const r=t?.duration,n=t?.interToneGap;try{i.insertDTMF(e,r,n)}catch(o){return this.logger.error(o.toString()),!1}return this.logger.log("SessionDescriptionHandler.sendDtmf sent via RTP: "+e.toString()),!0}setDescription(e,t,s){if(this.logger.debug("SessionDescriptionHandler.setDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));this.onDataChannel=t?.onDataChannel;const i=this._peerConnection.signalingState==="have-local-offer"?"answer":"offer";return this.getLocalMediaStream(t).then(()=>this.applyModifiers({sdp:e,type:i},s)).then(r=>this.setRemoteSessionDescription(r)).catch(r=>{throw this.logger.error("SessionDescriptionHandler.setDescription failed - "+r),r})}applyModifiers(e,t){return this.logger.debug("SessionDescriptionHandler.applyModifiers"),!t||t.length===0?Promise.resolve(e):t.reduce((s,i)=>s.then(i),Promise.resolve(e)).then(s=>{if(this.logger.debug("SessionDescriptionHandler.applyModifiers - modified sdp"),!s.sdp||!s.type)throw new Error("Invalid SDP.");return{sdp:s.sdp,type:s.type}})}createDataChannel(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));if(e?.dataChannel!==!0||this._dataChannel)return Promise.resolve();switch(this._peerConnection.signalingState){case"stable":this.logger.debug("SessionDescriptionHandler.createDataChannel - creating data channel");try{return this._dataChannel=this._peerConnection.createDataChannel(e?.dataChannelLabel||"",e?.dataChannelOptions),this.onDataChannel&&this.onDataChannel(this._dataChannel),Promise.resolve()}catch(t){return Promise.reject(t)}case"have-remote-offer":return Promise.resolve();default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}}createLocalOfferOrAnswer(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));switch(this._peerConnection.signalingState){case"stable":return this.logger.debug("SessionDescriptionHandler.createLocalOfferOrAnswer - creating SDP offer"),this._peerConnection.createOffer(e?.offerOptions);case"have-remote-offer":return this.logger.debug("SessionDescriptionHandler.createLocalOfferOrAnswer - creating SDP answer"),this._peerConnection.createAnswer(e?.answerOptions);default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}}getLocalMediaStream(e){if(this.logger.debug("SessionDescriptionHandler.getLocalMediaStream"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));let t=Object.assign({},e?.constraints);if(this.localMediaStreamConstraints){if(t.audio=t.audio||this.localMediaStreamConstraints.audio,t.video=t.video||this.localMediaStreamConstraints.video,JSON.stringify(this.localMediaStreamConstraints.audio)===JSON.stringify(t.audio)&&JSON.stringify(this.localMediaStreamConstraints.video)===JSON.stringify(t.video))return Promise.resolve()}else t.audio===void 0&&t.video===void 0&&(t={audio:!0});return this.localMediaStreamConstraints=t,this.mediaStreamFactory(t,this,e).then(s=>this.setLocalMediaStream(s))}setLocalMediaStream(e){if(this.logger.debug("SessionDescriptionHandler.setLocalMediaStream"),!this._peerConnection)throw new Error("Peer connection undefined.");const t=this._peerConnection,s=this._localMediaStream,i=[],r=d=>{const p=d.kind;if(p!=="audio"&&p!=="video")throw new Error(`Unknown new track kind ${p}.`);const g=t.getSenders().find(w=>w.track&&w.track.kind===p);g?i.push(new Promise(w=>{this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${p} track`),w()}).then(()=>g.replaceTrack(d).then(()=>{const w=s.getTracks().find(S=>S.kind===p);w&&(w.stop(),s.removeTrack(w),F.dispatchRemoveTrackEvent(s,w)),s.addTrack(d),F.dispatchAddTrackEvent(s,d)}).catch(w=>{throw this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to replace sender ${p} track`),w}))):i.push(new Promise(w=>{this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - adding sender ${p} track`),w()}).then(()=>{try{t.addTrack(d,s)}catch(w){throw this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${p} track`),w}s.addTrack(d),F.dispatchAddTrackEvent(s,d)}))},n=e.getAudioTracks();n.length&&r(n[0]);const o=e.getVideoTracks();return o.length&&r(o[0]),i.reduce((d,p)=>d.then(()=>p),Promise.resolve())}getLocalSessionDescription(){if(this.logger.debug("SessionDescriptionHandler.getLocalSessionDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));const e=this._peerConnection.localDescription;return e?Promise.resolve(e):Promise.reject(new Error("Failed to get local session description"))}setLocalSessionDescription(e){return this.logger.debug("SessionDescriptionHandler.setLocalSessionDescription"),this._peerConnection===void 0?Promise.reject(new Error("Peer connection closed.")):this._peerConnection.setLocalDescription(e)}setRemoteSessionDescription(e){if(this.logger.debug("SessionDescriptionHandler.setRemoteSessionDescription"),this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));const t=e.sdp;let s;switch(this._peerConnection.signalingState){case"stable":s="offer";break;case"have-local-offer":s="answer";break;default:return Promise.reject(new Error("Invalid signaling state "+this._peerConnection.signalingState))}return t?this._peerConnection.setRemoteDescription({sdp:t,type:s}):(this.logger.error("SessionDescriptionHandler.setRemoteSessionDescription failed - cannot set null sdp"),Promise.reject(new Error("SDP is undefined")))}setRemoteTrack(e){this.logger.debug("SessionDescriptionHandler.setRemoteTrack");const t=this._remoteMediaStream;t.getTrackById(e.id)?this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - have remote ${e.kind} track`):e.kind==="audio"?(this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - adding remote ${e.kind} track`),t.getAudioTracks().forEach(s=>{s.stop(),t.removeTrack(s),F.dispatchRemoveTrackEvent(t,s)}),t.addTrack(e),F.dispatchAddTrackEvent(t,e)):e.kind==="video"&&(this.logger.debug(`SessionDescriptionHandler.setRemoteTrack - adding remote ${e.kind} track`),t.getVideoTracks().forEach(s=>{s.stop(),t.removeTrack(s),F.dispatchRemoveTrackEvent(t,s)}),t.addTrack(e),F.dispatchAddTrackEvent(t,e))}updateDirection(e){if(this._peerConnection===void 0)return Promise.reject(new Error("Peer connection closed."));switch(this._peerConnection.signalingState){case"stable":this.logger.debug("SessionDescriptionHandler.updateDirection - setting offer direction");{const t=s=>{switch(s){case"inactive":return e?.hold?"inactive":"recvonly";case"recvonly":return e?.hold?"inactive":"recvonly";case"sendonly":return e?.hold?"sendonly":"sendrecv";case"sendrecv":return e?.hold?"sendonly":"sendrecv";case"stopped":return"stopped";default:throw new Error("Should never happen")}};this._peerConnection.getTransceivers().forEach(s=>{if(s.direction){const i=t(s.direction);s.direction!==i&&(s.direction=i)}})}break;case"have-remote-offer":this.logger.debug("SessionDescriptionHandler.updateDirection - setting answer direction");{const t=(()=>{const i=this._peerConnection.remoteDescription;if(!i)throw new Error("Failed to read remote offer");const r=/a=sendrecv\r\n|a=sendonly\r\n|a=recvonly\r\n|a=inactive\r\n/.exec(i.sdp);if(r)switch(r[0]){case`a=inactive\r
49
49
  `:return"inactive";case`a=recvonly\r
50
50
  `:return"recvonly";case`a=sendonly\r
51
51
  `:return"sendonly";case`a=sendrecv\r
@@ -89,8 +89,8 @@ Duration=`+2e3}};return e.info({requestOptions:n}).then(()=>{})}}async transfer(
89
89
  .btn { min-height: 44px; font-size: 15px; }
90
90
  .logs { max-height: 140px; padding: 0 16px 16px; }
91
91
  }
92
- `,X={idle:"准备就绪,可进入待机或发起呼叫。",requesting:"正在向服务端申请网页通话会话。",standbyRequesting:"正在向服务端申请 widget 待机会话。",registering:"临时账号已拿到,正在连接并执行 REGISTER。",standby:"REGISTER 已完成,widget 正在等待来电。",incoming:"收到新的来电,请选择接听或拒接。",calling:"已发起呼叫,正在等待对端振铃或接听。",connected:"通话已接通,媒体链路正在运行。",ended:"通话已结束,组件已回到可再次呼叫状态。",rejected:"本次来电已拒接,widget 仍保持待机。",missed:"本次来电未接听,widget 仍保持待机。",failed:"本次呼叫失败,请先看下方日志。"},Xt="手机网页首次接入时,请允许麦克风权限;若切到后台后再回来,先确认页面仍保持前台活跃。",it=15e3,ye=it*2;function re(a,e){return new URL(e,String(a||window.location.origin)).href}function Qt(a,e){return e?`${a}
93
- ${JSON.stringify(e,null,2)}`:a}function es(a){return a==="standby"?"standby":"outbound"}function ts(a){return typeof a=="function"}function ss(){return typeof window>"u"?!1:new URLSearchParams(window.location.search).get("embeddedCallWidgetE2E")==="1"}class is{constructor({mount:e,shadowRoot:t,options:s}){this.mountNode=e,this.shadowRoot=t,this.options=s,this.mode=es(s.mode),this.apiBaseUrl=s.apiBaseUrl||window.location.origin,this.client=null,this.issuedSession=null,this.bootstrap=null,this.turnIceServers=[],this.state="idle",this.finalizing=!1,this.isMobileViewport=!1,this.pendingIncomingCall=null,this.visibilityHandler=null,this.sessionTouchTimer=null,this.transportDisconnectTimer=null,this.transportDisconnectContext=null,this.e2eBridgeEnabled=ss(),this.terminalFailureOverride="",this.refs={}}async mount(){this.isMobileViewport=typeof window<"u"&&window.matchMedia("(max-width: 480px)").matches,this.shadowRoot.innerHTML=`
92
+ `,X={idle:"网页电话已加载,正在准备待机能力。",requesting:"正在向服务端申请网页通话会话。",standbyRequesting:"正在向服务端申请 widget 待机会话。",registering:"临时账号已拿到,正在连接并执行 REGISTER。",standby:"REGISTER 已完成,widget 正在等待来电。",incoming:"收到新的来电,请选择接听或拒接。",calling:"已发起呼叫,正在等待对端振铃或接听。",connected:"通话已接通,媒体链路正在运行。",ended:"通话已结束,网页电话正在恢复待机。",rejected:"本次来电已拒接,widget 仍保持待机。",missed:"本次来电未接听,widget 仍保持待机。",failed:"本次呼叫失败,请先看下方日志。"},Xt="手机网页首次接入时,请允许麦克风权限;若切到后台后再回来,先确认页面仍保持前台活跃。",it=15e3,ye=it*2;function re(a,e){return new URL(e,String(a||window.location.origin)).href}function Qt(a,e){return e?`${a}
93
+ ${JSON.stringify(e,null,2)}`:a}function es(a){return a==="outbound"?"outbound":"terminal"}function ts(a){return typeof a=="function"}function ss(){return typeof window>"u"?!1:new URLSearchParams(window.location.search).get("embeddedCallWidgetE2E")==="1"}class is{constructor({mount:e,shadowRoot:t,options:s}){this.mountNode=e,this.shadowRoot=t,this.options=s,this.mode=es(s.mode),this.legacyOutboundOnly=this.mode==="outbound",this.apiBaseUrl=s.apiBaseUrl||window.location.origin,this.client=null,this.issuedSession=null,this.bootstrap=null,this.turnIceServers=[],this.state="idle",this.finalizing=!1,this.isMobileViewport=!1,this.pendingIncomingCall=null,this.visibilityHandler=null,this.sessionTouchTimer=null,this.transportDisconnectTimer=null,this.transportDisconnectContext=null,this.e2eBridgeEnabled=ss(),this.terminalFailureOverride="",this.refs={}}async mount(){this.isMobileViewport=typeof window<"u"&&window.matchMedia("(max-width: 480px)").matches,this.shadowRoot.innerHTML=`
94
94
  <style>${Zt}</style>
95
95
  <section class="widget">
96
96
  <div class="panel">
@@ -100,13 +100,13 @@ ${JSON.stringify(e,null,2)}`:a}function es(a){return a==="standby"?"standby":"ou
100
100
  <div class="status" data-role="status">${X.idle}</div>
101
101
  <div class="hint" data-role="hint"></div>
102
102
  </div>
103
- <div class="meta" data-role="meta">入站规则:${this.options.businessKey||"自动读取默认值"};站点键:${this.options.siteKey||"自动读取默认值"}</div>
103
+ <div class="meta" data-role="meta">站点键:${this.options.siteKey||"自动读取默认值"};访客主动呼叫默认规则:${this.options.businessKey||"自动读取默认值"}</div>
104
104
  <div class="actions">
105
- <button class="btn btn-primary" data-role="primary" type="button">连接并呼叫</button>
105
+ <button class="btn btn-primary" data-role="primary" type="button">恢复网页电话待机</button>
106
106
  <button class="btn btn-secondary" data-role="secondary" type="button" disabled>断开并清理</button>
107
107
  </div>
108
108
  <div class="logs" data-role="logs"></div>
109
109
  <audio class="audio" data-role="audio" autoplay playsinline></audio>
110
110
  </div>
111
111
  </section>
112
- `,this.refs.status=this.shadowRoot.querySelector('[data-role="status"]'),this.refs.hint=this.shadowRoot.querySelector('[data-role="hint"]'),this.refs.meta=this.shadowRoot.querySelector('[data-role="meta"]'),this.refs.primary=this.shadowRoot.querySelector('[data-role="primary"]'),this.refs.secondary=this.shadowRoot.querySelector('[data-role="secondary"]'),this.refs.logs=this.shadowRoot.querySelector('[data-role="logs"]'),this.refs.audio=this.shadowRoot.querySelector('[data-role="audio"]'),this.refs.primary.addEventListener("click",()=>{this.handlePrimaryAction()}),this.refs.secondary.addEventListener("click",()=>{this.handleSecondaryAction()}),this.bindPageLifecycle(),this.registerE2EBridge(),this.render()}bindPageLifecycle(){typeof document>"u"||(this.visibilityHandler=()=>{if(document.visibilityState==="hidden"){this.reportIssuedSessionEvent("visibility-hidden",{visible:!1}),this.appendLog("页面已切到后台",{state:this.state,advice:"回到前台后请先确认页面仍保持活动,再继续观察通话状态。"}),this.isMobileViewport&&["requesting","registering","calling","connected"].includes(this.state)&&(this.refs.status.textContent="页面已切到后台;手机网页回到前台后请确认通话仍在继续。");return}this.isMobileViewport&&(this.appendLog("页面已回到前台",{state:this.state}),["requesting","registering","calling","connected"].includes(this.state)&&(this.refs.status.textContent=X[this.state]||X.idle)),this.reportIssuedSessionEvent("visibility-visible",{visible:!0}),this.render()},document.addEventListener("visibilitychange",this.visibilityHandler))}open(){this.mountNode.scrollIntoView({block:"nearest",inline:"nearest"})}emitHostCallback(e,t){const s=this.options?.[e];if(ts(s))try{s(t)}catch(i){this.appendLog("宿主回调执行失败",{callback:e,message:i?.message||String(i)})}}getSnapshot(){return{mode:this.mode,state:this.state,sessionMode:this.issuedSession?.session_mode||null,sessionId:this.issuedSession?.session_id||null,siteKey:this.options.siteKey||this.bootstrap?.default_site_key||null,businessKey:this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||null,standbyMode:this.issuedSession?.standby_mode||null,standbyState:this.issuedSession?.standby_state||this.options.standbyState||null,widgetSipNumber:this.issuedSession?.widget_anchor_number||null,browserSipUsername:this.issuedSession?.browser_sip_username||this.issuedSession?.sip_username||null,routeNote:this.issuedSession?.route_note||null,incomingAnchors:Array.isArray(this.issuedSession?.incoming_anchors)?this.issuedSession.incoming_anchors:[],hasClient:!!this.client,hasIssuedSession:!!this.issuedSession?.session_id,primaryText:this.refs.primary?.textContent?.trim()||"",secondaryText:this.refs.secondary?.textContent?.trim()||"",statusText:this.refs.status?.textContent?.trim()||"",pendingIncomingCall:this.pendingIncomingCall}}registerE2EBridge(){!this.e2eBridgeEnabled||typeof window>"u"||(window.__embeddedCallWidgetE2E__={getSnapshot:()=>this.getSnapshot(),simulateIncomingCall:(e={})=>(this.pendingIncomingCall={displayName:e.displayName||"测试来电",user:e.user||"2001",host:e.host||"call.shenyin.eu",direction:"inbound",uri:e.uri||`sip:${e.user||"2001"}@${e.host||"call.shenyin.eu"}`},this.setState("incoming"),this.emitHostCallback("onIncomingCall",this.pendingIncomingCall),this.getSnapshot()),answerIncomingCall:async()=>(await this.answerIncomingCall(),this.getSnapshot()),declineIncomingCall:async()=>(await this.declineIncomingCall(),this.getSnapshot()),hangupCall:async()=>(await this.hangupCall(),this.getSnapshot())})}async handlePrimaryAction(){if(this.state==="incoming"){await this.answerIncomingCall();return}if(this.mode==="standby"){await this.startStandby();return}await this.connectAndCall()}async handleSecondaryAction(){if(this.state==="incoming"){await this.declineIncomingCall();return}if(this.state==="connected"&&this.client){await this.hangupCall();return}await this.disconnectAndCleanup("manual-disconnect")}async connectAndCall(){if(!["requesting","registering","calling","connected"].includes(this.state))try{this.terminalFailureOverride="",this.setState("requesting"),await this.loadBootstrap(),this.turnIceServers=await this.fetchTurnIceServers();const e=await this.fetchIssuedSession();await this.ensureClient(e),this.setState("registering"),await this.client.ensureReady(),this.setState("calling"),await this.client.call(e.target),this.appendLog("已发起呼叫",{target:e.target,route_note:e.routeNote||null})}catch(e){const t=e?.message||String(e);this.terminalFailureOverride=t,this.setState("failed",t),this.appendLog("连接并呼叫失败",{message:t}),await this.releaseIssuedSession("failed","connect-and-call-failed"),this.setState("failed",t)}}async startStandby(){if(this.mode!=="standby")throw new Error("当前 widget 未启用 standby 模式");if(!["standbyRequesting","registering","incoming","connected"].includes(this.state))try{this.terminalFailureOverride="",this.setState("standbyRequesting"),await this.loadBootstrap(),this.turnIceServers=await this.fetchTurnIceServers();const e=await this.fetchStandbySession();await this.ensureClient(e),this.setState("registering","待机会话已拿到,正在连接并执行 REGISTER。"),await this.client.ensureReady(),this.setState("standby"),this.appendLog("widget 已进入待机",{session_id:this.issuedSession?.session_id||null,route_business_key:this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||null,standby_mode:this.issuedSession?.standby_mode||null,widget_anchor_number:this.issuedSession?.widget_anchor_number||null,browser_sip_username:this.issuedSession?.browser_sip_username||this.issuedSession?.sip_username||null}),this.emitHostCallback("onStandbyReady",this.getSnapshot())}catch(e){const t=e?.message||String(e);this.terminalFailureOverride=t,this.setState("failed",t),this.appendLog("进入待机失败",{message:t}),await this.releaseIssuedSession("failed","standby-start-failed"),this.setState("failed",t)}}async ensureClient(e){const t={sip_username:e.sipUsername,sip_password:e.password,sip_domain:e.sipDomain,webrtc_url:e.transport,ice_servers:this.turnIceServers};this.client?.matchesAccount(t)||(this.client&&await this.client.destroy(),this.client=new Jt(t,{remoteAudioElement:this.refs.audio,onStateChange:(s,i)=>{this.handleClientState(s,i)},onError:s=>this.appendLog("SIP 客户端错误",{message:s?.message||String(s)})}))}async handleClientState(e,t={}){if(this.syncSessionTouch(e),this.reportIssuedSessionEvent(e,t,e),(e==="connected"||e==="registered"||e==="ringing"||e==="dialing"||e==="answered")&&await this.clearTransportDisconnectGrace(!0),e==="registered"){this.issuedSession?.session_mode==="widget_standby"?this.setState("standby"):this.setState("registering","REGISTER 已完成,正在准备发起呼叫。");return}if(e==="incoming"){this.pendingIncomingCall=t&&typeof t=="object"?{...t}:null,this.setState("incoming"),this.appendLog("收到新的来电",this.pendingIncomingCall),this.emitHostCallback("onIncomingCall",this.pendingIncomingCall);return}if(e==="ringing"||e==="dialing"){this.setState("calling",t?.message||X.calling);return}if(e==="answered"){this.terminalFailureOverride="";const s=this.pendingIncomingCall||t||null;this.setState("connected"),this.emitHostCallback("onCallAnswered",s);return}if(e==="terminated"){if(this.issuedSession?.session_mode==="widget_standby"){await this.handleStandbyTermination(t);return}t&&typeof t=="object"&&(t.source==="invite-response"||t.source==="invite-exception"||t.code||t.status||t.stage)&&(this.terminalFailureOverride=t?.message||X.failed,this.setState("failed",this.terminalFailureOverride)),await this.finalizeAfterTermination(t?.hangupSource||"terminated");return}if(e==="failed"){await this.clearTransportDisconnectGrace(!1),this.stopSessionTouch(),this.terminalFailureOverride=t?.message||X.failed,this.setState("failed",this.terminalFailureOverride),await this.releaseIssuedSession("failed","sip-client-failed");return}if(e==="disconnected"||e==="unregistered"){if(this.stopSessionTouch(),["calling","connected"].includes(this.state)){this.setState("connected","SIP 信令短暂中断,正在等待恢复。"),this.scheduleTransportDisconnectGrace(e);return}const i=this.terminalFailureOverride||this.client?.lastFailureMeta?.message||null;if(i){this.terminalFailureOverride=i,this.setState("failed",i);return}if(this.state==="failed")return;this.state!=="idle"&&this.state!=="ended"&&this.setState("ended")}}stopTransportDisconnectGrace(){this.transportDisconnectTimer&&(window.clearTimeout(this.transportDisconnectTimer),this.transportDisconnectTimer=null),this.transportDisconnectContext=null}sameTransportDisconnectContext(e){return!e||!this.issuedSession?.session_id?!1:e.sessionId===this.issuedSession.session_id}async clearTransportDisconnectGrace(e){const t=this.transportDisconnectContext,s=!!(e&&t?.reported&&this.sameTransportDisconnectContext(t));this.stopTransportDisconnectGrace(),s&&(await this.reportIssuedSessionEvent("transport-restored",{disconnectDurationMs:Date.now()-(t.startedAt||Date.now()),graceMs:ye},this.state),this.appendLog("网页通话信令已恢复",{disconnectDurationMs:Date.now()-(t.startedAt||Date.now()),graceMs:ye}))}scheduleTransportDisconnectGrace(e){if(!this.issuedSession?.session_id)return;this.stopTransportDisconnectGrace();const t={sessionId:this.issuedSession.session_id,startedAt:Date.now(),reported:!1,state:e};this.transportDisconnectContext=t,this.transportDisconnectTimer=window.setTimeout(()=>{this.transportDisconnectTimer=null,this.sameTransportDisconnectContext(t)&&(t.reported=!0,this.reportIssuedSessionEvent("transport-disconnected",{state:e,graceMs:ye},this.state),this.appendLog("网页通话信令断开超过宽限窗口",{graceMs:ye,state:e}))},ye)}async finalizeAfterTermination(e){if(!this.finalizing){this.finalizing=!0;try{this.stopSessionTouch(),this.stopTransportDisconnectGrace(),await this.releaseIssuedSession("released",e),this.client&&(await this.client.destroy(),this.client=null);const t=this.terminalFailureOverride||(this.state==="failed"?this.refs.status?.textContent?.trim()||X.failed:"");t?this.setState("failed",t):this.setState("ended"),this.appendLog("通话已结束并完成清理",{reason:e})}finally{this.finalizing=!1}}}async handleStandbyTermination(e={}){this.stopTransportDisconnectGrace();const t=this.state,s=e?.hangupSource||"terminated";t==="incoming"?s==="local"?(this.setState("rejected"),this.emitHostCallback("onCallRejected",this.pendingIncomingCall||e||null)):(this.setState("missed"),this.emitHostCallback("onCallMissed",this.pendingIncomingCall||e||null)):this.setState("standby","上一通来电已结束,继续等待下一通来电。"),this.appendLog("待机会话中的来电已结束",{hangupSource:s,previousState:t}),this.pendingIncomingCall=null}async answerIncomingCall(){if(this.state==="incoming"){if(!this.client&&this.e2eBridgeEnabled){this.setState("connected","测试桥已模拟接听当前来电。"),this.emitHostCallback("onCallAnswered",this.pendingIncomingCall);return}if(!this.client)throw new Error("当前没有可接听的 SIP 会话");await this.client.answer()}}async declineIncomingCall(){if(this.state==="incoming"){if(!this.client&&this.e2eBridgeEnabled){this.setState("rejected"),this.emitHostCallback("onCallRejected",this.pendingIncomingCall),this.pendingIncomingCall=null;return}if(!this.client)throw new Error("当前没有可拒接的 SIP 会话");await this.client.decline()}}async hangupCall(){if(!this.client&&this.e2eBridgeEnabled){this.mode==="standby"?this.setState("standby","测试桥已模拟挂断,继续等待下一通来电。"):this.setState("ended"),this.pendingIncomingCall=null;return}this.client&&await this.client.hangup()}async disconnectAndCleanup(e){this.stopSessionTouch(),this.stopTransportDisconnectGrace(),this.reportIssuedSessionEvent("manual-disconnect",{reason:e},this.state),this.pendingIncomingCall=null,this.terminalFailureOverride="",this.client&&(await this.client.destroy(),this.client=null),await this.releaseIssuedSession("released",e),this.setState("idle"),this.appendLog("连接已断开",{reason:e})}async loadBootstrap(){if(this.bootstrap)return this.bootstrap;const e=await fetch(re(this.apiBaseUrl,"/api/sip/embedded-call-demo-bootstrap"),{credentials:"include",cache:"no-store"});if(!e.ok)throw new Error(`默认模式读取失败:${e.status}`);return this.bootstrap=await e.json(),this.bootstrap}async fetchTurnIceServers(){const e=await fetch(re(this.apiBaseUrl,"/api/sip/webrtc-turn-credentials"),{credentials:"include",cache:"no-store"});if(!e.ok)return this.appendLog("TURN 凭证获取失败,继续尝试直连",{status:e.status}),[];const t=await e.json();return Array.isArray(t?.ice_servers)?t.ice_servers:[]}async fetchIssuedSession(){const e=this.options.siteKey||this.bootstrap?.default_site_key||"",t=this.options.businessKey||this.bootstrap?.default_business_key||"admin-duty";if(!e)throw new Error("当前 SDK 模式必须明确提供 siteKey,或让服务端下发默认站点键");const s=await fetch(re(this.apiBaseUrl,"/api/sip/issue-call-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify({site_key:e,business_key:t,standby_state:this.options.standbyState||void 0,selected_primary_account:this.options.selectedPrimaryAccount||void 0,selected_middle_layer_account:this.options.selectedMiddleLayerAccount||void 0,display_name:this.options.displayName||void 0,page_url:window.location.href,access_token:this.options.accessToken||void 0})});if(!s.ok){const r=await s.json().catch(()=>({}));throw new Error(r?.detail||`会话签发失败:${s.status}`)}const i=await s.json();return this.issuedSession=i,this.reportIssuedSessionEvent("issued-session-fetched",{sessionId:i.session_id,targetExtension:i.target_extension,dialTargetExtension:i.dial_target_extension||i.target_extension,resolvedTargetInternalNumbers:i.resolved_target_internal_numbers||[],resolvedBusinessKey:i.resolved_business_key||null},"requesting"),this.appendLog("已获取服务端签发会话",{session_id:i.session_id,target_extension:i.target_extension,dial_target_extension:i.dial_target_extension||i.target_extension||null,resolved_target_internal_numbers:i.resolved_target_internal_numbers||[],resolved_business_key:i.resolved_business_key||null,resolved_route_mode:i.resolved_route_mode||null,route_note:i.route_note||null}),{sessionMode:i.session_mode||"outbound",sipUsername:i.sip_username,sipDomain:i.sip_domain,password:i.sip_password,transport:i.ws_server,target:i.dial_target_extension||i.target_extension,routeNote:i.route_note||""}}async fetchStandbySession(){const e=this.options.siteKey||this.bootstrap?.default_site_key||"",t=String(this.options.businessKey||"").trim()||null;if(!e)throw new Error("当前 SDK 待机模式必须明确提供 siteKey,或让服务端下发默认站点键");const s={site_key:e,standby_state:this.options.standbyState||void 0,selected_primary_account:this.options.selectedPrimaryAccount||void 0,selected_middle_layer_account:this.options.selectedMiddleLayerAccount||void 0,display_name:this.options.displayName||void 0,page_url:window.location.href,access_token:this.options.accessToken||void 0};t&&(s.business_key=t);const i=await fetch(re(this.apiBaseUrl,"/api/sip/issue-widget-standby-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok){const n=await i.json().catch(()=>({}));throw new Error(n?.detail||`待机会话签发失败:${i.status}`)}const r=await i.json();return this.issuedSession=r,this.reportIssuedSessionEvent("standby-session-fetched",{sessionId:r.session_id,resolvedBusinessKey:r.resolved_business_key||null,standbyMode:r.standby_mode||null},"standbyRequesting"),this.appendLog("已获取 widget 待机会话",{session_id:r.session_id,resolved_business_key:r.resolved_business_key||null,standby_mode:r.standby_mode||null,standby_state:r.standby_state||null,widget_anchor_number:r.widget_anchor_number||null,browser_sip_username:r.browser_sip_username||r.sip_username||null,route_note:r.route_note||null}),{sessionMode:r.session_mode||"widget_standby",sipUsername:r.sip_username,sipDomain:r.sip_domain,password:r.sip_password,transport:r.ws_server,target:null,routeNote:r.route_note||""}}async releaseIssuedSession(e,t){if(!this.issuedSession?.session_id)return;const s=this.issuedSession.session_id;this.issuedSession=null,await fetch(re(this.apiBaseUrl,"/api/sip/release-call-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:s,status:e,reason:t,client_summary:this.buildClientEvidenceSummary(e,{releaseReason:t})})}).catch(()=>{})}buildClientEvidenceSummary(e=null,t=null){const s={runtimeMode:"embedded-widget-runtime",widgetVersion:"2026-03-29-runtime-evidence",widgetMode:this.mode,sessionMode:this.issuedSession?.session_mode||null,state:e||this.state,visible:typeof document>"u"?!0:document.visibilityState==="visible",pageUrl:typeof window>"u"?null:window.location.href,connectionSnapshot:this.client?.getConnectionSnapshot?.()||null};return t&&typeof t=="object"&&(s.eventDetail=t),s}async touchIssuedSession(e,t=null){if(!this.issuedSession?.session_id)return;const s=this.issuedSession.session_id;try{const i=await fetch(re(this.apiBaseUrl,"/api/sip/touch-call-session"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:s,state:e,client_summary:this.buildClientEvidenceSummary(e,t)})});if(!i.ok)throw new Error(`会话心跳失败:${i.status}`)}catch(i){this.appendLog("网页通话会话心跳失败",{session_id:s,state:e,message:i?.message||String(i)})}}async reportIssuedSessionEvent(e,t=null,s=null){if(!this.issuedSession?.session_id)return;const i=this.issuedSession.session_id,r=s||this.state;let n=null,o="";try{const d=await fetch(re(this.apiBaseUrl,"/api/sip/report-call-session-event"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:i,source:"widget-runtime",event:e,state:r,detail:this.buildClientEvidenceSummary(r,t)})});if(!d.ok){n=d.status;const p=await d.json().catch(()=>({}));throw o=p?.detail?String(p.detail):"",new Error(o||`事件留证失败:${d.status}`)}}catch(d){await fetch(re(this.apiBaseUrl,"/api/sip/report-call-session-event-delivery-failure"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:i,source:"widget-runtime",event:e,state:r,detail:this.buildClientEvidenceSummary(r,t),delivery_error:{status:typeof n=="number"?n:null,detail:o||"",message:d?.message||String(d)}})}).catch(()=>{}),this.appendLog("网页通话事件留证失败",{session_id:i,event:e,state:r,message:d?.message||String(d)})}}stopSessionTouch(){this.sessionTouchTimer&&(window.clearInterval(this.sessionTouchTimer),this.sessionTouchTimer=null)}syncSessionTouch(e){if(!(!!this.issuedSession?.session_id&&["connected","registered","dialing","ringing","answered","standby","incoming"].includes(e))){this.stopSessionTouch();return}this.touchIssuedSession(e),this.sessionTouchTimer||(this.sessionTouchTimer=window.setInterval(()=>{this.touchIssuedSession(this.state)},it))}setState(e,t=""){this.state=e,this.refs.status.textContent=t||X[e]||X.idle,this.emitHostCallback("onStateChange",this.getSnapshot()),this.render()}appendLog(e,t){const s=document.createElement("div");for(s.className="log",s.textContent=Qt(e,t),this.refs.logs.prepend(s);this.refs.logs.children.length>8;)this.refs.logs.lastElementChild?.remove()}render(){const e=["requesting","standbyRequesting","registering","calling"].includes(this.state),t=["calling","connected"].includes(this.state),s=!!(this.client||this.issuedSession);this.mode==="standby"?(this.refs.primary.disabled=e||["standby","rejected","missed","connected"].includes(this.state),this.state==="incoming"?this.refs.primary.textContent="接听来电":this.state==="standby"?this.refs.primary.textContent="等待下一通来电":this.state==="rejected"||this.state==="missed"?this.refs.primary.textContent="仍在等待来电":e?this.refs.primary.textContent="正在进入待机":this.refs.primary.textContent="开始待机",this.refs.secondary.disabled=!s,this.refs.secondary.textContent=this.state==="incoming"?"拒接来电":this.state==="connected"?"挂断并清理":"断开并清理"):(this.refs.primary.disabled=e,this.refs.primary.textContent=t?"通话进行中":"连接并呼叫",this.refs.secondary.disabled=!t&&!s,this.refs.secondary.textContent=t?"挂断并清理":"断开并清理");const i=this.options.siteKey||this.bootstrap?.default_site_key||"等待服务端返回",r=this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||"等待服务端返回";this.mode==="standby"?this.refs.meta.textContent=`站点键:${i};待机身份会自动映射到 widget 锚点号码;访客主动呼叫默认规则:${r}`:this.refs.meta.textContent=`入站规则:${r};站点键:${i}`,this.refs.hint.textContent=this.isMobileViewport?Xt:"桌面网页可直接使用;若宿主站点启用了来源白名单或接入令牌,请按站点配置提供对应参数。"}async destroy(){await this.disconnectAndCleanup("destroy-widget"),typeof document<"u"&&this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.stopSessionTouch(),this.stopTransportDisconnectGrace(),this.pendingIncomingCall=null,this.e2eBridgeEnabled&&typeof window<"u"&&window.__embeddedCallWidgetE2E__&&delete window.__embeddedCallWidgetE2E__,this.shadowRoot.innerHTML=""}}function rt(a){return new is(a)}return typeof window<"u"&&(window.__EmbeddedCallWidgetRuntime__={createEmbeddedCallWidgetRuntime:rt}),$e.createEmbeddedCallWidgetRuntime=rt,Object.defineProperty($e,Symbol.toStringTag,{value:"Module"}),$e})({});
112
+ `,this.refs.status=this.shadowRoot.querySelector('[data-role="status"]'),this.refs.hint=this.shadowRoot.querySelector('[data-role="hint"]'),this.refs.meta=this.shadowRoot.querySelector('[data-role="meta"]'),this.refs.primary=this.shadowRoot.querySelector('[data-role="primary"]'),this.refs.secondary=this.shadowRoot.querySelector('[data-role="secondary"]'),this.refs.logs=this.shadowRoot.querySelector('[data-role="logs"]'),this.refs.audio=this.shadowRoot.querySelector('[data-role="audio"]'),this.refs.primary.addEventListener("click",()=>{this.handlePrimaryAction()}),this.refs.secondary.addEventListener("click",()=>{this.handleSecondaryAction()}),this.bindPageLifecycle(),this.registerE2EBridge(),this.render()}bindPageLifecycle(){typeof document>"u"||(this.visibilityHandler=()=>{if(document.visibilityState==="hidden"){this.reportIssuedSessionEvent("visibility-hidden",{visible:!1}),this.appendLog("页面已切到后台",{state:this.state,advice:"回到前台后请先确认页面仍保持活动,再继续观察通话状态。"}),this.isMobileViewport&&["requesting","registering","calling","connected"].includes(this.state)&&(this.refs.status.textContent="页面已切到后台;手机网页回到前台后请确认通话仍在继续。");return}this.isMobileViewport&&(this.appendLog("页面已回到前台",{state:this.state}),["requesting","registering","calling","connected"].includes(this.state)&&(this.refs.status.textContent=X[this.state]||X.idle)),this.reportIssuedSessionEvent("visibility-visible",{visible:!0}),this.render()},document.addEventListener("visibilitychange",this.visibilityHandler))}open(){this.mountNode.scrollIntoView({block:"nearest",inline:"nearest"})}emitHostCallback(e,t){const s=this.options?.[e];if(ts(s))try{s(t)}catch(i){this.appendLog("宿主回调执行失败",{callback:e,message:i?.message||String(i)})}}getSnapshot(){return{mode:this.mode,state:this.state,sessionMode:this.issuedSession?.session_mode||null,sessionId:this.issuedSession?.session_id||null,siteKey:this.options.siteKey||this.bootstrap?.default_site_key||null,businessKey:this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||null,standbyMode:this.issuedSession?.standby_mode||null,standbyState:this.issuedSession?.standby_state||this.options.standbyState||null,widgetSipNumber:this.issuedSession?.widget_anchor_number||null,browserSipUsername:this.issuedSession?.browser_sip_username||this.issuedSession?.sip_username||null,routeNote:this.issuedSession?.route_note||null,incomingAnchors:Array.isArray(this.issuedSession?.incoming_anchors)?this.issuedSession.incoming_anchors:[],hasClient:!!this.client,hasIssuedSession:!!this.issuedSession?.session_id,primaryText:this.refs.primary?.textContent?.trim()||"",secondaryText:this.refs.secondary?.textContent?.trim()||"",statusText:this.refs.status?.textContent?.trim()||"",pendingIncomingCall:this.pendingIncomingCall}}registerE2EBridge(){!this.e2eBridgeEnabled||typeof window>"u"||(window.__embeddedCallWidgetE2E__={getSnapshot:()=>this.getSnapshot(),simulateIncomingCall:(e={})=>(this.pendingIncomingCall={displayName:e.displayName||"测试来电",user:e.user||"2001",host:e.host||"call.shenyin.eu",direction:"inbound",uri:e.uri||`sip:${e.user||"2001"}@${e.host||"call.shenyin.eu"}`},this.setState("incoming"),this.emitHostCallback("onIncomingCall",this.pendingIncomingCall),this.getSnapshot()),answerIncomingCall:async()=>(await this.answerIncomingCall(),this.getSnapshot()),declineIncomingCall:async()=>(await this.declineIncomingCall(),this.getSnapshot()),hangupCall:async()=>(await this.hangupCall(),this.getSnapshot())})}async handlePrimaryAction(){if(this.state==="incoming"){await this.answerIncomingCall();return}if(this.legacyOutboundOnly){await this.connectAndCall();return}if(!this.client&&!this.issuedSession){await this.startStandby();return}await this.connectAndCall()}async handleSecondaryAction(){if(this.state==="incoming"){await this.declineIncomingCall();return}if(this.state==="connected"&&this.client){await this.hangupCall();return}await this.disconnectAndCleanup("manual-disconnect")}async connectAndCall(){if(!["requesting","registering","calling","connected"].includes(this.state))try{this.terminalFailureOverride="",!this.legacyOutboundOnly&&this.issuedSession?.session_mode==="widget_standby"&&(this.appendLog("访客主动呼叫前,先释放当前待机会话并切换到呼叫链路。",{widget_anchor_number:this.issuedSession?.widget_anchor_number||null,resolved_business_key:this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||null}),await this.disconnectAndCleanup("switch-to-outbound-call")),this.setState("requesting"),await this.loadBootstrap(),this.turnIceServers=await this.fetchTurnIceServers();const e=await this.fetchIssuedSession();await this.ensureClient(e),this.setState("registering"),await this.client.ensureReady(),this.setState("calling"),await this.client.call(e.target),this.appendLog("已发起呼叫",{target:e.target,route_note:e.routeNote||null})}catch(e){const t=e?.message||String(e);if(this.terminalFailureOverride=t,this.setState("failed",t),this.appendLog("连接并呼叫失败",{message:t}),await this.releaseIssuedSession("failed","connect-and-call-failed"),!this.legacyOutboundOnly){this.appendLog("呼叫失败后,网页电话将恢复待机。",{message:t}),await this.startStandby({force:!0});return}this.setState("failed",t)}}async startStandby(e={}){if(this.legacyOutboundOnly)throw new Error("当前 widget 仍处于 legacy outbound 兼容模式");const{force:t=!1}=e;if(!(!t&&["standbyRequesting","registering","incoming","connected"].includes(this.state)))try{this.terminalFailureOverride="",this.setState("standbyRequesting"),await this.loadBootstrap(),this.turnIceServers=await this.fetchTurnIceServers();const s=await this.fetchStandbySession();await this.ensureClient(s),this.setState("registering","待机会话已拿到,正在连接并执行 REGISTER。"),await this.client.ensureReady(),this.setState("standby"),this.appendLog("widget 已进入待机",{session_id:this.issuedSession?.session_id||null,route_business_key:this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||null,standby_mode:this.issuedSession?.standby_mode||null,widget_anchor_number:this.issuedSession?.widget_anchor_number||null,browser_sip_username:this.issuedSession?.browser_sip_username||this.issuedSession?.sip_username||null}),this.emitHostCallback("onStandbyReady",this.getSnapshot())}catch(s){const i=s?.message||String(s);this.terminalFailureOverride=i,this.setState("failed",i),this.appendLog("进入待机失败",{message:i}),await this.releaseIssuedSession("failed","standby-start-failed"),this.setState("failed",i)}}async ensureClient(e){const t={sip_username:e.sipUsername,sip_password:e.password,sip_domain:e.sipDomain,webrtc_url:e.transport,ice_servers:this.turnIceServers};this.client?.matchesAccount(t)||(this.client&&await this.client.destroy(),this.client=new Jt(t,{remoteAudioElement:this.refs.audio,onStateChange:(s,i)=>{this.handleClientState(s,i)},onError:s=>this.appendLog("SIP 客户端错误",{message:s?.message||String(s)})}))}async handleClientState(e,t={}){if(this.syncSessionTouch(e),this.reportIssuedSessionEvent(e,t,e),(e==="connected"||e==="registered"||e==="ringing"||e==="dialing"||e==="answered")&&await this.clearTransportDisconnectGrace(!0),e==="registered"){this.issuedSession?.session_mode==="widget_standby"?this.setState("standby"):this.setState("registering","REGISTER 已完成,正在准备发起呼叫。");return}if(e==="incoming"){this.pendingIncomingCall=t&&typeof t=="object"?{...t}:null,this.setState("incoming"),this.appendLog("收到新的来电",this.pendingIncomingCall),this.emitHostCallback("onIncomingCall",this.pendingIncomingCall);return}if(e==="ringing"||e==="dialing"){this.setState("calling",t?.message||X.calling);return}if(e==="answered"){this.terminalFailureOverride="";const s=this.pendingIncomingCall||t||null;this.setState("connected"),this.emitHostCallback("onCallAnswered",s);return}if(e==="terminated"){if(this.issuedSession?.session_mode==="widget_standby"){await this.handleStandbyTermination(t);return}t&&typeof t=="object"&&(t.source==="invite-response"||t.source==="invite-exception"||t.code||t.status||t.stage)&&(this.terminalFailureOverride=t?.message||X.failed,this.setState("failed",this.terminalFailureOverride)),await this.finalizeAfterTermination(t?.hangupSource||"terminated");return}if(e==="failed"){await this.clearTransportDisconnectGrace(!1),this.stopSessionTouch(),this.terminalFailureOverride=t?.message||X.failed,this.setState("failed",this.terminalFailureOverride),await this.releaseIssuedSession("failed","sip-client-failed");return}if(e==="disconnected"||e==="unregistered"){if(this.stopSessionTouch(),["calling","connected"].includes(this.state)){this.setState("connected","SIP 信令短暂中断,正在等待恢复。"),this.scheduleTransportDisconnectGrace(e);return}const i=this.terminalFailureOverride||this.client?.lastFailureMeta?.message||null;if(i){this.terminalFailureOverride=i,this.setState("failed",i);return}if(this.state==="failed")return;this.state!=="idle"&&this.state!=="ended"&&this.setState("ended")}}stopTransportDisconnectGrace(){this.transportDisconnectTimer&&(window.clearTimeout(this.transportDisconnectTimer),this.transportDisconnectTimer=null),this.transportDisconnectContext=null}sameTransportDisconnectContext(e){return!e||!this.issuedSession?.session_id?!1:e.sessionId===this.issuedSession.session_id}async clearTransportDisconnectGrace(e){const t=this.transportDisconnectContext,s=!!(e&&t?.reported&&this.sameTransportDisconnectContext(t));this.stopTransportDisconnectGrace(),s&&(await this.reportIssuedSessionEvent("transport-restored",{disconnectDurationMs:Date.now()-(t.startedAt||Date.now()),graceMs:ye},this.state),this.appendLog("网页通话信令已恢复",{disconnectDurationMs:Date.now()-(t.startedAt||Date.now()),graceMs:ye}))}scheduleTransportDisconnectGrace(e){if(!this.issuedSession?.session_id)return;this.stopTransportDisconnectGrace();const t={sessionId:this.issuedSession.session_id,startedAt:Date.now(),reported:!1,state:e};this.transportDisconnectContext=t,this.transportDisconnectTimer=window.setTimeout(()=>{this.transportDisconnectTimer=null,this.sameTransportDisconnectContext(t)&&(t.reported=!0,this.reportIssuedSessionEvent("transport-disconnected",{state:e,graceMs:ye},this.state),this.appendLog("网页通话信令断开超过宽限窗口",{graceMs:ye,state:e}))},ye)}async finalizeAfterTermination(e){if(!this.finalizing){this.finalizing=!0;try{if(this.stopSessionTouch(),this.stopTransportDisconnectGrace(),await this.releaseIssuedSession("released",e),this.client&&(await this.client.destroy(),this.client=null),!this.legacyOutboundOnly){this.setState("idle","上一通通话已结束,正在恢复网页电话待机。"),this.appendLog("通话已结束,网页电话正在恢复待机。",{reason:e}),await this.startStandby({force:!0});return}const t=this.terminalFailureOverride||(this.state==="failed"?this.refs.status?.textContent?.trim()||X.failed:"");t?this.setState("failed",t):this.setState("ended"),this.appendLog("通话已结束并完成清理",{reason:e})}finally{this.finalizing=!1}}}async handleStandbyTermination(e={}){this.stopTransportDisconnectGrace();const t=this.state,s=e?.hangupSource||"terminated";t==="incoming"?s==="local"?(this.setState("rejected"),this.emitHostCallback("onCallRejected",this.pendingIncomingCall||e||null)):(this.setState("missed"),this.emitHostCallback("onCallMissed",this.pendingIncomingCall||e||null)):this.setState("standby","上一通来电已结束,继续等待下一通来电。"),this.appendLog("待机会话中的来电已结束",{hangupSource:s,previousState:t}),this.pendingIncomingCall=null}async answerIncomingCall(){if(this.state==="incoming"){if(!this.client&&this.e2eBridgeEnabled){this.setState("connected","测试桥已模拟接听当前来电。"),this.emitHostCallback("onCallAnswered",this.pendingIncomingCall);return}if(!this.client)throw new Error("当前没有可接听的 SIP 会话");await this.client.answer()}}async declineIncomingCall(){if(this.state==="incoming"){if(!this.client&&this.e2eBridgeEnabled){this.setState("rejected"),this.emitHostCallback("onCallRejected",this.pendingIncomingCall),this.pendingIncomingCall=null;return}if(!this.client)throw new Error("当前没有可拒接的 SIP 会话");await this.client.decline()}}async hangupCall(){if(!this.client&&this.e2eBridgeEnabled){this.legacyOutboundOnly?this.setState("ended"):this.setState("standby","测试桥已模拟挂断,网页电话已恢复待机。"),this.pendingIncomingCall=null;return}this.client&&await this.client.hangup()}async disconnectAndCleanup(e){this.stopSessionTouch(),this.stopTransportDisconnectGrace(),this.reportIssuedSessionEvent("manual-disconnect",{reason:e},this.state),this.pendingIncomingCall=null,this.terminalFailureOverride="",this.client&&(await this.client.destroy(),this.client=null),await this.releaseIssuedSession("released",e),this.setState("idle"),this.appendLog("连接已断开",{reason:e})}async loadBootstrap(){if(this.bootstrap)return this.bootstrap;const e=await fetch(re(this.apiBaseUrl,"/api/sip/embedded-call-demo-bootstrap"),{credentials:"include",cache:"no-store"});if(!e.ok)throw new Error(`默认模式读取失败:${e.status}`);return this.bootstrap=await e.json(),this.bootstrap}async fetchTurnIceServers(){const e=await fetch(re(this.apiBaseUrl,"/api/sip/webrtc-turn-credentials"),{credentials:"include",cache:"no-store"});if(!e.ok)return this.appendLog("TURN 凭证获取失败,继续尝试直连",{status:e.status}),[];const t=await e.json();return Array.isArray(t?.ice_servers)?t.ice_servers:[]}async fetchIssuedSession(){const e=this.options.siteKey||this.bootstrap?.default_site_key||"",t=this.options.businessKey||this.bootstrap?.default_business_key||"admin-duty";if(!e)throw new Error("当前 SDK 模式必须明确提供 siteKey,或让服务端下发默认站点键");const s=await fetch(re(this.apiBaseUrl,"/api/sip/issue-call-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify({site_key:e,business_key:t,standby_state:this.options.standbyState||void 0,selected_primary_account:this.options.selectedPrimaryAccount||void 0,selected_middle_layer_account:this.options.selectedMiddleLayerAccount||void 0,display_name:this.options.displayName||void 0,page_url:window.location.href,access_token:this.options.accessToken||void 0})});if(!s.ok){const r=await s.json().catch(()=>({}));throw new Error(r?.detail||`会话签发失败:${s.status}`)}const i=await s.json();return this.issuedSession=i,this.reportIssuedSessionEvent("issued-session-fetched",{sessionId:i.session_id,targetExtension:i.target_extension,dialTargetExtension:i.dial_target_extension||i.target_extension,resolvedTargetInternalNumbers:i.resolved_target_internal_numbers||[],resolvedBusinessKey:i.resolved_business_key||null},"requesting"),this.appendLog("已获取服务端签发会话",{session_id:i.session_id,target_extension:i.target_extension,dial_target_extension:i.dial_target_extension||i.target_extension||null,resolved_target_internal_numbers:i.resolved_target_internal_numbers||[],resolved_business_key:i.resolved_business_key||null,resolved_route_mode:i.resolved_route_mode||null,route_note:i.route_note||null}),{sessionMode:i.session_mode||"outbound",sipUsername:i.sip_username,sipDomain:i.sip_domain,password:i.sip_password,transport:i.ws_server,target:i.dial_target_extension||i.target_extension,routeNote:i.route_note||""}}async fetchStandbySession(){const e=this.options.siteKey||this.bootstrap?.default_site_key||"",t=String(this.options.businessKey||"").trim()||null;if(!e)throw new Error("当前 SDK 待机模式必须明确提供 siteKey,或让服务端下发默认站点键");const s={site_key:e,standby_state:this.options.standbyState||void 0,selected_primary_account:this.options.selectedPrimaryAccount||void 0,selected_middle_layer_account:this.options.selectedMiddleLayerAccount||void 0,display_name:this.options.displayName||void 0,page_url:window.location.href,access_token:this.options.accessToken||void 0};t&&(s.business_key=t);const i=await fetch(re(this.apiBaseUrl,"/api/sip/issue-widget-standby-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok){const n=await i.json().catch(()=>({}));throw new Error(n?.detail||`待机会话签发失败:${i.status}`)}const r=await i.json();return this.issuedSession=r,this.reportIssuedSessionEvent("standby-session-fetched",{sessionId:r.session_id,resolvedBusinessKey:r.resolved_business_key||null,standbyMode:r.standby_mode||null},"standbyRequesting"),this.appendLog("已获取 widget 待机会话",{session_id:r.session_id,resolved_business_key:r.resolved_business_key||null,standby_mode:r.standby_mode||null,standby_state:r.standby_state||null,widget_anchor_number:r.widget_anchor_number||null,browser_sip_username:r.browser_sip_username||r.sip_username||null,route_note:r.route_note||null}),{sessionMode:r.session_mode||"widget_standby",sipUsername:r.sip_username,sipDomain:r.sip_domain,password:r.sip_password,transport:r.ws_server,target:null,routeNote:r.route_note||""}}async releaseIssuedSession(e,t){if(!this.issuedSession?.session_id)return;const s=this.issuedSession.session_id;this.issuedSession=null,await fetch(re(this.apiBaseUrl,"/api/sip/release-call-session"),{method:"POST",credentials:"include",cache:"no-store",headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:s,status:e,reason:t,client_summary:this.buildClientEvidenceSummary(e,{releaseReason:t})})}).catch(()=>{})}buildClientEvidenceSummary(e=null,t=null){const s={runtimeMode:"embedded-widget-runtime",widgetVersion:"2026-03-29-runtime-evidence",widgetMode:this.mode,sessionMode:this.issuedSession?.session_mode||null,state:e||this.state,visible:typeof document>"u"?!0:document.visibilityState==="visible",pageUrl:typeof window>"u"?null:window.location.href,connectionSnapshot:this.client?.getConnectionSnapshot?.()||null};return t&&typeof t=="object"&&(s.eventDetail=t),s}async touchIssuedSession(e,t=null){if(!this.issuedSession?.session_id)return;const s=this.issuedSession.session_id;try{const i=await fetch(re(this.apiBaseUrl,"/api/sip/touch-call-session"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:s,state:e,client_summary:this.buildClientEvidenceSummary(e,t)})});if(!i.ok)throw new Error(`会话心跳失败:${i.status}`)}catch(i){this.appendLog("网页通话会话心跳失败",{session_id:s,state:e,message:i?.message||String(i)})}}async reportIssuedSessionEvent(e,t=null,s=null){if(!this.issuedSession?.session_id)return;const i=this.issuedSession.session_id,r=s||this.state;let n=null,o="";try{const d=await fetch(re(this.apiBaseUrl,"/api/sip/report-call-session-event"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:i,source:"widget-runtime",event:e,state:r,detail:this.buildClientEvidenceSummary(r,t)})});if(!d.ok){n=d.status;const p=await d.json().catch(()=>({}));throw o=p?.detail?String(p.detail):"",new Error(o||`事件留证失败:${d.status}`)}}catch(d){await fetch(re(this.apiBaseUrl,"/api/sip/report-call-session-event-delivery-failure"),{method:"POST",credentials:"include",cache:"no-store",keepalive:!0,headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:i,source:"widget-runtime",event:e,state:r,detail:this.buildClientEvidenceSummary(r,t),delivery_error:{status:typeof n=="number"?n:null,detail:o||"",message:d?.message||String(d)}})}).catch(()=>{}),this.appendLog("网页通话事件留证失败",{session_id:i,event:e,state:r,message:d?.message||String(d)})}}stopSessionTouch(){this.sessionTouchTimer&&(window.clearInterval(this.sessionTouchTimer),this.sessionTouchTimer=null)}syncSessionTouch(e){if(!(!!this.issuedSession?.session_id&&["connected","registered","dialing","ringing","answered","standby","incoming"].includes(e))){this.stopSessionTouch();return}this.touchIssuedSession(e),this.sessionTouchTimer||(this.sessionTouchTimer=window.setInterval(()=>{this.touchIssuedSession(this.state)},it))}setState(e,t=""){this.state=e,this.refs.status.textContent=t||X[e]||X.idle,this.emitHostCallback("onStateChange",this.getSnapshot()),this.render()}appendLog(e,t){const s=document.createElement("div");for(s.className="log",s.textContent=Qt(e,t),this.refs.logs.prepend(s);this.refs.logs.children.length>8;)this.refs.logs.lastElementChild?.remove()}render(){const e=["requesting","standbyRequesting","registering","calling"].includes(this.state),t=["calling","connected"].includes(this.state),s=!!(this.client||this.issuedSession);this.legacyOutboundOnly?(this.refs.primary.disabled=e,this.refs.primary.textContent=t?"通话进行中":"连接并呼叫",this.refs.secondary.disabled=!t&&!s,this.refs.secondary.textContent=t?"挂断并清理":"断开并清理"):(this.refs.primary.disabled=e||this.state==="connected",this.state==="incoming"?this.refs.primary.textContent="接听来电":e?this.refs.primary.textContent=this.state==="calling"?"通话进行中":"正在恢复网页电话":!s||["idle","failed","ended"].includes(this.state)?this.refs.primary.textContent="恢复网页电话待机":this.refs.primary.textContent="呼叫管理员",this.refs.secondary.disabled=!s,this.refs.secondary.textContent=this.state==="incoming"?"拒接来电":this.state==="connected"?"挂断并恢复待机":"断开电话");const i=this.options.siteKey||this.bootstrap?.default_site_key||"等待服务端返回",r=this.issuedSession?.resolved_business_key||this.options.businessKey||this.bootstrap?.default_business_key||"等待服务端返回";this.legacyOutboundOnly?this.refs.meta.textContent=`入站规则:${r};站点键:${i}`:this.refs.meta.textContent=`站点键:${i};网页电话会先进入可被叫待机;访客主动呼叫默认规则:${r}`,this.refs.hint.textContent=this.isMobileViewport?Xt:"桌面网页可直接使用;若宿主站点启用了来源白名单或接入令牌,请按站点配置提供对应参数。"}async destroy(){await this.disconnectAndCleanup("destroy-widget"),typeof document<"u"&&this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.stopSessionTouch(),this.stopTransportDisconnectGrace(),this.pendingIncomingCall=null,this.e2eBridgeEnabled&&typeof window<"u"&&window.__embeddedCallWidgetE2E__&&delete window.__embeddedCallWidgetE2E__,this.shadowRoot.innerHTML=""}}function rt(a){return new is(a)}return typeof window<"u"&&(window.__EmbeddedCallWidgetRuntime__={createEmbeddedCallWidgetRuntime:rt}),$e.createEmbeddedCallWidgetRuntime=rt,Object.defineProperty($e,Symbol.toStringTag,{value:"Module"}),$e})({});