mie-webconf-app
Version:
This is a mediasoup based web conferencing app with socket.io for signalling
2 lines • 555 kB
JavaScript
/*! For license information please see main.5a147832.js.LICENSE.txt */
(()=>{var e={579:(e,t,r)=>{"use strict";e.exports=r(2799)},683:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getRtpEncodings=function(e){let{offerMediaObject:t}=e;const r=new Set;for(const s of t.ssrcs??[]){const e=s.id;r.add(e)}if(0===r.size)throw new Error("no a=ssrc lines found");const n=new Map;for(const s of t.ssrcGroups??[]){if("FID"!==s.semantics)continue;let[e,t]=s.ssrcs.split(/\s+/);e=Number(e),t=Number(t),r.has(e)&&(r.delete(e),r.delete(t),n.set(e,t))}for(const s of r)n.set(s,null);const i=[];for(const[s,a]of n){const e={ssrc:s};a&&(e.rtx={ssrc:a}),i.push(e)}return i},t.addLegacySimulcast=function(e){let{offerMediaObject:t,numStreams:r}=e;if(r<=1)throw new TypeError("numStreams must be greater than 1");const n=(t.ssrcs??[]).find((e=>"msid"===e.attribute));if(!n)throw new Error("a=ssrc line with msid information not found");const[i,s]=n.value.split(" "),a=Number(n.id);let o;(t.ssrcGroups??[]).some((e=>{if("FID"!==e.semantics)return!1;const t=e.ssrcs.split(/\s+/);return Number(t[0])===a&&(o=Number(t[1]),!0)}));const c=t.ssrcs.find((e=>"cname"===e.attribute));if(!c)throw new Error("a=ssrc line with cname information not found");const l=c.value,d=[],u=[];for(let p=0;p<r;++p)d.push(a+p),o&&u.push(o+p);t.ssrcGroups=[],t.ssrcs=[],t.ssrcGroups.push({semantics:"SIM",ssrcs:d.join(" ")});for(const p of d)t.ssrcs.push({id:p,attribute:"cname",value:l}),t.ssrcs.push({id:p,attribute:"msid",value:`${i} ${s}`});for(let p=0;p<u.length;++p){const e=d[p],r=u[p];t.ssrcs.push({id:r,attribute:"cname",value:l}),t.ssrcs.push({id:r,attribute:"msid",value:`${i} ${s}`}),t.ssrcGroups.push({semantics:"FID",ssrcs:`${e} ${r}`})}}},918:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getCapabilities=function(){const e=RTCRtpReceiver.getCapabilities(),t=n.clone(e);for(const r of t.codecs??[]){if(r.channels=r.numChannels,delete r.numChannels,r.mimeType=r.mimeType??`${r.kind}/${r.name}`,r.parameters){const e=r.parameters;e.apt&&(e.apt=Number(e.apt)),e["packetization-mode"]&&(e["packetization-mode"]=Number(e["packetization-mode"]))}for(const e of r.rtcpFeedback??[])e.parameter||(e.parameter="")}return t},t.mangleRtpParameters=function(e){const t=n.clone(e);t.mid&&(t.muxId=t.mid,delete t.mid);for(const r of t.codecs)r.channels&&(r.numChannels=r.channels,delete r.channels),r.mimeType&&!r.name&&(r.name=r.mimeType.split("/")[1]),delete r.mimeType;return t};const n=r(8988)},1194:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ReactNativeUnifiedPlan=void 0;const n=r(9640),i=r(2097),s=r(8988),a=r(5809),o=r(5467),c=r(683),l=r(1581),d=r(9398),u=r(2384),p=r(3054),h=r(3204),f=new i.Logger("ReactNativeUnifiedPlan"),m={OS:1024,MIS:1024};class g extends u.HandlerInterface{_closed=!1;_direction;_remoteSdp;_sendingRtpParametersByKind;_sendingRemoteRtpParametersByKind;_forcedLocalDtlsRole;_pc;_mapMidTransceiver=(()=>new Map)();_sendStream=(()=>new MediaStream)();_hasDataChannelMediaSection=!1;_nextSendSctpStreamId=0;_transportReady=!1;static createFactory(){return()=>new g}constructor(){super()}get name(){return"ReactNativeUnifiedPlan"}close(){if(f.debug("close()"),!this._closed){if(this._closed=!0,this._sendStream.release(!1),this._pc)try{this._pc.close()}catch(e){}this.emit("@close")}}async getNativeRtpCapabilities(){f.debug("getNativeRtpCapabilities()");const e=new RTCPeerConnection({iceServers:[],iceTransportPolicy:"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require",sdpSemantics:"unified-plan"});try{e.addTransceiver("audio"),e.addTransceiver("video");const r=await e.createOffer();try{e.close()}catch(t){}const i=n.parse(r.sdp),s=o.extractRtpCapabilities({sdpObject:i});return l.addNackSupportForOpus(s),s}catch(t){try{e.close()}catch(r){}throw t}}async getNativeSctpCapabilities(){return f.debug("getNativeSctpCapabilities()"),{numStreams:m}}run(e){let{direction:t,iceParameters:r,iceCandidates:n,dtlsParameters:i,sctpParameters:s,iceServers:o,iceTransportPolicy:c,additionalSettings:l,proprietaryConstraints:d,extendedRtpCapabilities:u}=e;this.assertNotClosed(),f.debug("run()"),this._direction=t,this._remoteSdp=new p.RemoteSdp({iceParameters:r,iceCandidates:n,dtlsParameters:i,sctpParameters:s}),this._sendingRtpParametersByKind={audio:a.getSendingRtpParameters("audio",u),video:a.getSendingRtpParameters("video",u)},this._sendingRemoteRtpParametersByKind={audio:a.getSendingRemoteRtpParameters("audio",u),video:a.getSendingRemoteRtpParameters("video",u)},i.role&&"auto"!==i.role&&(this._forcedLocalDtlsRole="server"===i.role?"client":"server"),this._pc=new RTCPeerConnection({iceServers:o??[],iceTransportPolicy:c??"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require",sdpSemantics:"unified-plan",...l},d),this._pc.addEventListener("icegatheringstatechange",(()=>{this.emit("@icegatheringstatechange",this._pc.iceGatheringState)})),this._pc.addEventListener("icecandidateerror",(e=>{this.emit("@icecandidateerror",e)})),this._pc.connectionState?this._pc.addEventListener("connectionstatechange",(()=>{this.emit("@connectionstatechange",this._pc.connectionState)})):this._pc.addEventListener("iceconnectionstatechange",(()=>{switch(f.warn("run() | pc.connectionState not supported, using pc.iceConnectionState"),this._pc.iceConnectionState){case"checking":this.emit("@connectionstatechange","connecting");break;case"connected":case"completed":this.emit("@connectionstatechange","connected");break;case"failed":this.emit("@connectionstatechange","failed");break;case"disconnected":this.emit("@connectionstatechange","disconnected");break;case"closed":this.emit("@connectionstatechange","closed")}}))}async updateIceServers(e){this.assertNotClosed(),f.debug("updateIceServers()");const t=this._pc.getConfiguration();t.iceServers=e,this._pc.setConfiguration(t)}async restartIce(e){if(this.assertNotClosed(),f.debug("restartIce()"),this._remoteSdp.updateIceParameters(e),this._transportReady)if("send"===this._direction){const e=await this._pc.createOffer({iceRestart:!0});f.debug("restartIce() | calling pc.setLocalDescription() [offer:%o]",e),await this._pc.setLocalDescription(e);const t={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("restartIce() | calling pc.setRemoteDescription() [answer:%o]",t),await this._pc.setRemoteDescription(t)}else{const e={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("restartIce() | calling pc.setRemoteDescription() [offer:%o]",e),await this._pc.setRemoteDescription(e);const t=await this._pc.createAnswer();f.debug("restartIce() | calling pc.setLocalDescription() [answer:%o]",t),await this._pc.setLocalDescription(t)}}async getTransportStats(){return this.assertNotClosed(),this._pc.getStats()}async send(e){let{track:t,encodings:r,codecOptions:i,codec:l,onRtpSender:d}=e;this.assertNotClosed(),this.assertSendDirection(),f.debug("send() [kind:%s, track.id:%s]",t.kind,t.id),r&&r.length>1&&r.forEach(((e,t)=>{e.rid=`r${t}`}));const u=s.clone(this._sendingRtpParametersByKind[t.kind]);u.codecs=a.reduceCodecs(u.codecs,l);const p=s.clone(this._sendingRemoteRtpParametersByKind[t.kind]);p.codecs=a.reduceCodecs(p.codecs,l);const m=this._remoteSdp.getNextMediaSectionIdx(),g=this._pc.addTransceiver(t,{direction:"sendonly",streams:[this._sendStream],sendEncodings:r});d&&d(g.sender);let y,b=await this._pc.createOffer(),v=n.parse(b.sdp);v.extmapAllowMixed&&this._remoteSdp.setSessionExtmapAllowMixed(),this._transportReady||await this.setupTransport({localDtlsRole:this._forcedLocalDtlsRole??"client",localSdpObject:v});let w=!1;const _=(0,h.parse)((r??[{}])[0].scalabilityMode);r&&1===r.length&&_.spatialLayers>1&&"video/vp9"===u.codecs[0].mimeType.toLowerCase()&&(f.debug("send() | enabling legacy simulcast for VP9 SVC"),w=!0,v=n.parse(b.sdp),y=v.media[m.idx],c.addLegacySimulcast({offerMediaObject:y,numStreams:_.spatialLayers}),b={type:"offer",sdp:n.write(v)}),f.debug("send() | calling pc.setLocalDescription() [offer:%o]",b),await this._pc.setLocalDescription(b);let S=g.mid??void 0;if(S||f.warn("send() | missing transceiver.mid (bug in react-native-webrtc, using a workaround"),u.mid=S,v=n.parse(this._pc.localDescription.sdp),y=v.media[m.idx],u.rtcp.cname=o.getCname({offerMediaObject:y}),r)if(1===r.length){let e=c.getRtpEncodings({offerMediaObject:y});Object.assign(e[0],r[0]),w&&(e=[e[0]]),u.encodings=e}else u.encodings=r;else u.encodings=c.getRtpEncodings({offerMediaObject:y});if(u.encodings.length>1&&("video/vp8"===u.codecs[0].mimeType.toLowerCase()||"video/h264"===u.codecs[0].mimeType.toLowerCase()))for(const n of u.encodings)n.scalabilityMode?n.scalabilityMode=`L1T${_.temporalLayers}`:n.scalabilityMode="L1T3";this._remoteSdp.send({offerMediaObject:y,reuseMid:m.reuseMid,offerRtpParameters:u,answerRtpParameters:p,codecOptions:i});const k={type:"answer",sdp:this._remoteSdp.getSdp()};return f.debug("send() | calling pc.setRemoteDescription() [answer:%o]",k),await this._pc.setRemoteDescription(k),S||(S=g.mid,u.mid=S),this._mapMidTransceiver.set(S,g),{localId:S,rtpParameters:u,rtpSender:g.sender}}async stopSending(e){if(this.assertSendDirection(),this._closed)return;f.debug("stopSending() [localId:%s]",e);const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");t.sender.replaceTrack(null),this._pc.removeTrack(t.sender);if(this._remoteSdp.closeMediaSection(t.mid))try{t.stop()}catch(i){}const r=await this._pc.createOffer();f.debug("stopSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("stopSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n),this._mapMidTransceiver.delete(e)}async pauseSending(e){this.assertNotClosed(),this.assertSendDirection(),f.debug("pauseSending() [localId:%s]",e);const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");t.direction="inactive",this._remoteSdp.pauseMediaSection(e);const r=await this._pc.createOffer();f.debug("pauseSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("pauseSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n)}async resumeSending(e){this.assertNotClosed(),this.assertSendDirection(),f.debug("resumeSending() [localId:%s]",e);const t=this._mapMidTransceiver.get(e);if(this._remoteSdp.resumeSendingMediaSection(e),!t)throw new Error("associated RTCRtpTransceiver not found");t.direction="sendonly";const r=await this._pc.createOffer();f.debug("resumeSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("resumeSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n)}async replaceTrack(e,t){this.assertNotClosed(),this.assertSendDirection(),t?f.debug("replaceTrack() [localId:%s, track.id:%s]",e,t.id):f.debug("replaceTrack() [localId:%s, no track]",e);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated RTCRtpTransceiver not found");await r.sender.replaceTrack(t)}async setMaxSpatialLayer(e,t){this.assertNotClosed(),this.assertSendDirection(),f.debug("setMaxSpatialLayer() [localId:%s, spatialLayer:%s]",e,t);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated RTCRtpTransceiver not found");const n=r.sender.getParameters();n.encodings.forEach(((e,r)=>{e.active=r<=t})),await r.sender.setParameters(n),this._remoteSdp.muxMediaSectionSimulcast(e,n.encodings);const i=await this._pc.createOffer();f.debug("setMaxSpatialLayer() | calling pc.setLocalDescription() [offer:%o]",i),await this._pc.setLocalDescription(i);const s={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("setMaxSpatialLayer() | calling pc.setRemoteDescription() [answer:%o]",s),await this._pc.setRemoteDescription(s)}async setRtpEncodingParameters(e,t){this.assertNotClosed(),this.assertSendDirection(),f.debug("setRtpEncodingParameters() [localId:%s, params:%o]",e,t);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated RTCRtpTransceiver not found");const n=r.sender.getParameters();n.encodings.forEach(((e,r)=>{n.encodings[r]={...e,...t}})),await r.sender.setParameters(n),this._remoteSdp.muxMediaSectionSimulcast(e,n.encodings);const i=await this._pc.createOffer();f.debug("setRtpEncodingParameters() | calling pc.setLocalDescription() [offer:%o]",i),await this._pc.setLocalDescription(i);const s={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("setRtpEncodingParameters() | calling pc.setRemoteDescription() [answer:%o]",s),await this._pc.setRemoteDescription(s)}async getSenderStats(e){this.assertNotClosed(),this.assertSendDirection();const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");return t.sender.getStats()}async sendDataChannel(e){let{ordered:t,maxPacketLifeTime:r,maxRetransmits:i,label:s,protocol:a}=e;this.assertNotClosed(),this.assertSendDirection();const o={negotiated:!0,id:this._nextSendSctpStreamId,ordered:t,maxPacketLifeTime:r,maxRetransmits:i,protocol:a};f.debug("sendDataChannel() [options:%o]",o);const c=this._pc.createDataChannel(s,o);if(this._nextSendSctpStreamId=++this._nextSendSctpStreamId%m.MIS,!this._hasDataChannelMediaSection){const e=await this._pc.createOffer(),t=n.parse(e.sdp),r=t.media.find((e=>"application"===e.type));this._transportReady||await this.setupTransport({localDtlsRole:this._forcedLocalDtlsRole??"client",localSdpObject:t}),f.debug("sendDataChannel() | calling pc.setLocalDescription() [offer:%o]",e),await this._pc.setLocalDescription(e),this._remoteSdp.sendSctpAssociation({offerMediaObject:r});const i={type:"answer",sdp:this._remoteSdp.getSdp()};f.debug("sendDataChannel() | calling pc.setRemoteDescription() [answer:%o]",i),await this._pc.setRemoteDescription(i),this._hasDataChannelMediaSection=!0}return{dataChannel:c,sctpStreamParameters:{streamId:o.id,ordered:o.ordered,maxPacketLifeTime:o.maxPacketLifeTime,maxRetransmits:o.maxRetransmits}}}async receive(e){this.assertNotClosed(),this.assertRecvDirection();const t=[],r=new Map;for(const n of e){const{trackId:e,kind:t,rtpParameters:i,streamId:s}=n;f.debug("receive() [trackId:%s, kind:%s]",e,t);const a=i.mid??String(this._mapMidTransceiver.size);r.set(e,a),this._remoteSdp.receive({mid:a,kind:t,offerRtpParameters:i,streamId:s??i.rtcp.cname,trackId:e})}const i={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("receive() | calling pc.setRemoteDescription() [offer:%o]",i),await this._pc.setRemoteDescription(i);for(const n of e){const{trackId:e,onRtpReceiver:t}=n;if(t){const n=r.get(e),i=this._pc.getTransceivers().find((e=>e.mid===n));if(!i)throw new Error("transceiver not found");t(i.receiver)}}let s=await this._pc.createAnswer();const a=n.parse(s.sdp);for(const n of e){const{trackId:e,rtpParameters:t}=n,i=r.get(e),s=a.media.find((e=>String(e.mid)===i));o.applyCodecParameters({offerRtpParameters:t,answerMediaObject:s})}s={type:"answer",sdp:n.write(a)},this._transportReady||await this.setupTransport({localDtlsRole:this._forcedLocalDtlsRole??"client",localSdpObject:a}),f.debug("receive() | calling pc.setLocalDescription() [answer:%o]",s),await this._pc.setLocalDescription(s);for(const n of e){const{trackId:e}=n,i=r.get(e),s=this._pc.getTransceivers().find((e=>e.mid===i));if(!s)throw new Error("new RTCRtpTransceiver not found");this._mapMidTransceiver.set(i,s),t.push({localId:i,track:s.receiver.track,rtpReceiver:s.receiver})}return t}async stopReceiving(e){if(this.assertRecvDirection(),this._closed)return;for(const n of e){f.debug("stopReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");this._remoteSdp.closeMediaSection(e.mid)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("stopReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();f.debug("stopReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r);for(const n of e)this._mapMidTransceiver.delete(n)}async pauseReceiving(e){this.assertNotClosed(),this.assertRecvDirection();for(const n of e){f.debug("pauseReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");e.direction="inactive",this._remoteSdp.pauseMediaSection(n)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("pauseReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();f.debug("pauseReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r)}async resumeReceiving(e){this.assertNotClosed(),this.assertRecvDirection();for(const n of e){f.debug("resumeReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");e.direction="recvonly",this._remoteSdp.resumeReceivingMediaSection(n)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("resumeReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();f.debug("resumeReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r)}async getReceiverStats(e){this.assertNotClosed(),this.assertRecvDirection();const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");return t.receiver.getStats()}async receiveDataChannel(e){let{sctpStreamParameters:t,label:r,protocol:i}=e;this.assertNotClosed(),this.assertRecvDirection();const{streamId:s,ordered:a,maxPacketLifeTime:o,maxRetransmits:c}=t,l={negotiated:!0,id:s,ordered:a,maxPacketLifeTime:o,maxRetransmits:c,protocol:i};f.debug("receiveDataChannel() [options:%o]",l);const d=this._pc.createDataChannel(r,l);if(!this._hasDataChannelMediaSection){this._remoteSdp.receiveSctpAssociation();const e={type:"offer",sdp:this._remoteSdp.getSdp()};f.debug("receiveDataChannel() | calling pc.setRemoteDescription() [offer:%o]",e),await this._pc.setRemoteDescription(e);const t=await this._pc.createAnswer();if(!this._transportReady){const e=n.parse(t.sdp);await this.setupTransport({localDtlsRole:this._forcedLocalDtlsRole??"client",localSdpObject:e})}f.debug("receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]",t),await this._pc.setLocalDescription(t),this._hasDataChannelMediaSection=!0}return{dataChannel:d}}async setupTransport(e){let{localDtlsRole:t,localSdpObject:r}=e;r||(r=n.parse(this._pc.localDescription.sdp));const i=o.extractDtlsParameters({sdpObject:r});i.role=t,this._remoteSdp.updateDtlsRole("client"===t?"server":"client"),await new Promise(((e,t)=>{this.safeEmit("@connect",{dtlsParameters:i},e,t)})),this._transportReady=!0}assertNotClosed(){if(this._closed)throw new d.InvalidStateError("method called in a closed handler")}assertSendDirection(){if("send"!==this._direction)throw new Error('method can just be called for handlers with "send" direction')}assertRecvDirection(){if("recv"!==this._direction)throw new Error('method can just be called for handlers with "recv" direction')}}t.ReactNativeUnifiedPlan=g},1313:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Firefox120=void 0;const n=r(9640),i=r(2097),s=r(9398),a=r(8988),o=r(5809),c=r(5467),l=r(683),d=r(2384),u=r(3054),p=r(3204),h=new i.Logger("Firefox120"),f={OS:16,MIS:2048};class m extends d.HandlerInterface{_closed=!1;_direction;_remoteSdp;_sendingRtpParametersByKind;_sendingRemoteRtpParametersByKind;_pc;_mapMidTransceiver=(()=>new Map)();_sendStream=(()=>new MediaStream)();_hasDataChannelMediaSection=!1;_nextSendSctpStreamId=0;_transportReady=!1;static createFactory(){return()=>new m}constructor(){super()}get name(){return"Firefox120"}close(){if(h.debug("close()"),!this._closed){if(this._closed=!0,this._pc)try{this._pc.close()}catch(e){}this.emit("@close")}}async getNativeRtpCapabilities(){h.debug("getNativeRtpCapabilities()");const e=new RTCPeerConnection({iceServers:[],iceTransportPolicy:"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"}),t=document.createElement("canvas");t.getContext("2d");const r=t.captureStream().getVideoTracks()[0];try{e.addTransceiver("audio",{direction:"sendrecv"}),e.addTransceiver(r,{direction:"sendrecv",sendEncodings:[{rid:"r0",maxBitrate:1e5},{rid:"r1",maxBitrate:5e5}]});const s=await e.createOffer();try{t.remove()}catch(i){}try{r.stop()}catch(i){}try{e.close()}catch(i){}const a=n.parse(s.sdp);return c.extractRtpCapabilities({sdpObject:a})}catch(i){try{t.remove()}catch(s){}try{r.stop()}catch(s){}try{e.close()}catch(s){}throw i}}async getNativeSctpCapabilities(){return h.debug("getNativeSctpCapabilities()"),{numStreams:f}}run(e){let{direction:t,iceParameters:r,iceCandidates:n,dtlsParameters:i,sctpParameters:s,iceServers:a,iceTransportPolicy:c,additionalSettings:l,proprietaryConstraints:d,extendedRtpCapabilities:p}=e;this.assertNotClosed(),h.debug("run()"),this._direction=t,this._remoteSdp=new u.RemoteSdp({iceParameters:r,iceCandidates:n,dtlsParameters:i,sctpParameters:s}),this._sendingRtpParametersByKind={audio:o.getSendingRtpParameters("audio",p),video:o.getSendingRtpParameters("video",p)},this._sendingRemoteRtpParametersByKind={audio:o.getSendingRemoteRtpParameters("audio",p),video:o.getSendingRemoteRtpParameters("video",p)},this._pc=new RTCPeerConnection({iceServers:a??[],iceTransportPolicy:c??"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require",...l},d),this._pc.addEventListener("icegatheringstatechange",(()=>{this.emit("@icegatheringstatechange",this._pc.iceGatheringState)})),this._pc.addEventListener("icecandidateerror",(e=>{this.emit("@icecandidateerror",e)})),this._pc.connectionState?this._pc.addEventListener("connectionstatechange",(()=>{this.emit("@connectionstatechange",this._pc.connectionState)})):this._pc.addEventListener("iceconnectionstatechange",(()=>{switch(h.warn("run() | pc.connectionState not supported, using pc.iceConnectionState"),this._pc.iceConnectionState){case"checking":this.emit("@connectionstatechange","connecting");break;case"connected":case"completed":this.emit("@connectionstatechange","connected");break;case"failed":this.emit("@connectionstatechange","failed");break;case"disconnected":this.emit("@connectionstatechange","disconnected");break;case"closed":this.emit("@connectionstatechange","closed")}}))}async updateIceServers(e){throw this.assertNotClosed(),new s.UnsupportedError("not supported")}async restartIce(e){if(this.assertNotClosed(),h.debug("restartIce()"),this._remoteSdp.updateIceParameters(e),this._transportReady)if("send"===this._direction){const e=await this._pc.createOffer({iceRestart:!0});h.debug("restartIce() | calling pc.setLocalDescription() [offer:%o]",e),await this._pc.setLocalDescription(e);const t={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("restartIce() | calling pc.setRemoteDescription() [answer:%o]",t),await this._pc.setRemoteDescription(t)}else{const e={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("restartIce() | calling pc.setRemoteDescription() [offer:%o]",e),await this._pc.setRemoteDescription(e);const t=await this._pc.createAnswer();h.debug("restartIce() | calling pc.setLocalDescription() [answer:%o]",t),await this._pc.setLocalDescription(t)}}async getTransportStats(){return this.assertNotClosed(),this._pc.getStats()}async send(e){let{track:t,encodings:r,codecOptions:i,codec:s,onRtpSender:d}=e;this.assertNotClosed(),this.assertSendDirection(),h.debug("send() [kind:%s, track.id:%s]",t.kind,t.id),r&&r.length>1&&r.forEach(((e,t)=>{e.rid=`r${t}`}));const u=a.clone(this._sendingRtpParametersByKind[t.kind]);u.codecs=o.reduceCodecs(u.codecs,s);const f=a.clone(this._sendingRemoteRtpParametersByKind[t.kind]);f.codecs=o.reduceCodecs(f.codecs,s);const m=this._pc.addTransceiver(t,{direction:"sendonly",streams:[this._sendStream],sendEncodings:r});d&&d(m.sender);const g=await this._pc.createOffer();let y=n.parse(g.sdp);y.extmapAllowMixed&&this._remoteSdp.setSessionExtmapAllowMixed(),this._transportReady||await this.setupTransport({localDtlsRole:"client",localSdpObject:y});const b=(0,p.parse)((r??[{}])[0].scalabilityMode);h.debug("send() | calling pc.setLocalDescription() [offer:%o]",g),await this._pc.setLocalDescription(g);const v=m.mid;u.mid=v,y=n.parse(this._pc.localDescription.sdp);const w=y.media[y.media.length-1];if(u.rtcp.cname=c.getCname({offerMediaObject:w}),r)if(1===r.length){const e=l.getRtpEncodings({offerMediaObject:w});Object.assign(e[0],r[0]),u.encodings=e}else u.encodings=r;else u.encodings=l.getRtpEncodings({offerMediaObject:w});if(u.encodings.length>1&&("video/vp8"===u.codecs[0].mimeType.toLowerCase()||"video/h264"===u.codecs[0].mimeType.toLowerCase()))for(const n of u.encodings)n.scalabilityMode?n.scalabilityMode=`L1T${b.temporalLayers}`:n.scalabilityMode="L1T3";this._remoteSdp.send({offerMediaObject:w,offerRtpParameters:u,answerRtpParameters:f,codecOptions:i});const _={type:"answer",sdp:this._remoteSdp.getSdp()};return h.debug("send() | calling pc.setRemoteDescription() [answer:%o]",_),await this._pc.setRemoteDescription(_),this._mapMidTransceiver.set(v,m),{localId:v,rtpParameters:u,rtpSender:m.sender}}async stopSending(e){if(this.assertSendDirection(),h.debug("stopSending() [localId:%s]",e),this._closed)return;const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated transceiver not found");t.sender.replaceTrack(null),this._pc.removeTrack(t.sender),this._remoteSdp.disableMediaSection(t.mid);const r=await this._pc.createOffer();h.debug("stopSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("stopSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n),this._mapMidTransceiver.delete(e)}async pauseSending(e){this.assertNotClosed(),this.assertSendDirection(),h.debug("pauseSending() [localId:%s]",e);const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");t.direction="inactive",this._remoteSdp.pauseMediaSection(e);const r=await this._pc.createOffer();h.debug("pauseSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("pauseSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n)}async resumeSending(e){this.assertNotClosed(),this.assertSendDirection(),h.debug("resumeSending() [localId:%s]",e);const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");t.direction="sendonly",this._remoteSdp.resumeSendingMediaSection(e);const r=await this._pc.createOffer();h.debug("resumeSending() | calling pc.setLocalDescription() [offer:%o]",r),await this._pc.setLocalDescription(r);const n={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("resumeSending() | calling pc.setRemoteDescription() [answer:%o]",n),await this._pc.setRemoteDescription(n)}async replaceTrack(e,t){this.assertNotClosed(),this.assertSendDirection(),t?h.debug("replaceTrack() [localId:%s, track.id:%s]",e,t.id):h.debug("replaceTrack() [localId:%s, no track]",e);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated RTCRtpTransceiver not found");await r.sender.replaceTrack(t)}async setMaxSpatialLayer(e,t){this.assertNotClosed(),this.assertSendDirection(),h.debug("setMaxSpatialLayer() [localId:%s, spatialLayer:%s]",e,t);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated transceiver not found");const n=r.sender.getParameters();n.encodings.forEach(((e,r)=>{e.active=r<=t})),await r.sender.setParameters(n),this._remoteSdp.muxMediaSectionSimulcast(e,n.encodings);const i=await this._pc.createOffer();h.debug("setMaxSpatialLayer() | calling pc.setLocalDescription() [offer:%o]",i),await this._pc.setLocalDescription(i);const s={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("setMaxSpatialLayer() | calling pc.setRemoteDescription() [answer:%o]",s),await this._pc.setRemoteDescription(s)}async setRtpEncodingParameters(e,t){this.assertNotClosed(),this.assertSendDirection(),h.debug("setRtpEncodingParameters() [localId:%s, params:%o]",e,t);const r=this._mapMidTransceiver.get(e);if(!r)throw new Error("associated RTCRtpTransceiver not found");const n=r.sender.getParameters();n.encodings.forEach(((e,r)=>{n.encodings[r]={...e,...t}})),await r.sender.setParameters(n),this._remoteSdp.muxMediaSectionSimulcast(e,n.encodings);const i=await this._pc.createOffer();h.debug("setRtpEncodingParameters() | calling pc.setLocalDescription() [offer:%o]",i),await this._pc.setLocalDescription(i);const s={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("setRtpEncodingParameters() | calling pc.setRemoteDescription() [answer:%o]",s),await this._pc.setRemoteDescription(s)}async getSenderStats(e){this.assertNotClosed(),this.assertSendDirection();const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");return t.sender.getStats()}async sendDataChannel(e){let{ordered:t,maxPacketLifeTime:r,maxRetransmits:i,label:s,protocol:a}=e;this.assertNotClosed(),this.assertSendDirection();const o={negotiated:!0,id:this._nextSendSctpStreamId,ordered:t,maxPacketLifeTime:r,maxRetransmits:i,protocol:a};h.debug("sendDataChannel() [options:%o]",o);const c=this._pc.createDataChannel(s,o);if(this._nextSendSctpStreamId=++this._nextSendSctpStreamId%f.MIS,!this._hasDataChannelMediaSection){const e=await this._pc.createOffer(),t=n.parse(e.sdp),r=t.media.find((e=>"application"===e.type));this._transportReady||await this.setupTransport({localDtlsRole:"client",localSdpObject:t}),h.debug("sendDataChannel() | calling pc.setLocalDescription() [offer:%o]",e),await this._pc.setLocalDescription(e),this._remoteSdp.sendSctpAssociation({offerMediaObject:r});const i={type:"answer",sdp:this._remoteSdp.getSdp()};h.debug("sendDataChannel() | calling pc.setRemoteDescription() [answer:%o]",i),await this._pc.setRemoteDescription(i),this._hasDataChannelMediaSection=!0}return{dataChannel:c,sctpStreamParameters:{streamId:o.id,ordered:o.ordered,maxPacketLifeTime:o.maxPacketLifeTime,maxRetransmits:o.maxRetransmits}}}async receive(e){this.assertNotClosed(),this.assertRecvDirection();const t=[],r=new Map;for(const n of e){const{trackId:e,kind:t,rtpParameters:i,streamId:s}=n;h.debug("receive() [trackId:%s, kind:%s]",e,t);const a=i.mid??String(this._mapMidTransceiver.size);r.set(e,a),this._remoteSdp.receive({mid:a,kind:t,offerRtpParameters:i,streamId:s??i.rtcp.cname,trackId:e})}const i={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("receive() | calling pc.setRemoteDescription() [offer:%o]",i),await this._pc.setRemoteDescription(i);for(const n of e){const{trackId:e,onRtpReceiver:t}=n;if(t){const n=r.get(e),i=this._pc.getTransceivers().find((e=>e.mid===n));if(!i)throw new Error("transceiver not found");t(i.receiver)}}let s=await this._pc.createAnswer();const a=n.parse(s.sdp);for(const o of e){const{trackId:e,rtpParameters:t}=o,i=r.get(e),l=a.media.find((e=>String(e.mid)===i));c.applyCodecParameters({offerRtpParameters:t,answerMediaObject:l}),s={type:"answer",sdp:n.write(a)}}this._transportReady||await this.setupTransport({localDtlsRole:"client",localSdpObject:a}),h.debug("receive() | calling pc.setLocalDescription() [answer:%o]",s),await this._pc.setLocalDescription(s);for(const n of e){const{trackId:e}=n,i=r.get(e),s=this._pc.getTransceivers().find((e=>e.mid===i));if(!s)throw new Error("new RTCRtpTransceiver not found");this._mapMidTransceiver.set(i,s),t.push({localId:i,track:s.receiver.track,rtpReceiver:s.receiver})}return t}async stopReceiving(e){if(this.assertRecvDirection(),this._closed)return;for(const n of e){h.debug("stopReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");this._remoteSdp.closeMediaSection(e.mid)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("stopReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();h.debug("stopReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r);for(const n of e)this._mapMidTransceiver.delete(n)}async pauseReceiving(e){this.assertNotClosed(),this.assertRecvDirection();for(const n of e){h.debug("pauseReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");e.direction="inactive",this._remoteSdp.pauseMediaSection(n)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("pauseReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();h.debug("pauseReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r)}async resumeReceiving(e){this.assertNotClosed(),this.assertRecvDirection();for(const n of e){h.debug("resumeReceiving() [localId:%s]",n);const e=this._mapMidTransceiver.get(n);if(!e)throw new Error("associated RTCRtpTransceiver not found");e.direction="recvonly",this._remoteSdp.resumeReceivingMediaSection(n)}const t={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("resumeReceiving() | calling pc.setRemoteDescription() [offer:%o]",t),await this._pc.setRemoteDescription(t);const r=await this._pc.createAnswer();h.debug("resumeReceiving() | calling pc.setLocalDescription() [answer:%o]",r),await this._pc.setLocalDescription(r)}async getReceiverStats(e){this.assertRecvDirection();const t=this._mapMidTransceiver.get(e);if(!t)throw new Error("associated RTCRtpTransceiver not found");return t.receiver.getStats()}async receiveDataChannel(e){let{sctpStreamParameters:t,label:r,protocol:i}=e;this.assertNotClosed(),this.assertRecvDirection();const{streamId:s,ordered:a,maxPacketLifeTime:o,maxRetransmits:c}=t,l={negotiated:!0,id:s,ordered:a,maxPacketLifeTime:o,maxRetransmits:c,protocol:i};h.debug("receiveDataChannel() [options:%o]",l);const d=this._pc.createDataChannel(r,l);if(!this._hasDataChannelMediaSection){this._remoteSdp.receiveSctpAssociation();const e={type:"offer",sdp:this._remoteSdp.getSdp()};h.debug("receiveDataChannel() | calling pc.setRemoteDescription() [offer:%o]",e),await this._pc.setRemoteDescription(e);const t=await this._pc.createAnswer();if(!this._transportReady){const e=n.parse(t.sdp);await this.setupTransport({localDtlsRole:"client",localSdpObject:e})}h.debug("receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]",t),await this._pc.setLocalDescription(t),this._hasDataChannelMediaSection=!0}return{dataChannel:d}}async setupTransport(e){let{localDtlsRole:t,localSdpObject:r}=e;r||(r=n.parse(this._pc.localDescription.sdp));const i=c.extractDtlsParameters({sdpObject:r});i.role=t,this._remoteSdp.updateDtlsRole("client"===t?"server":"client"),await new Promise(((e,t)=>{this.safeEmit("@connect",{dtlsParameters:i},e,t)})),this._transportReady=!0}assertNotClosed(){if(this._closed)throw new s.InvalidStateError("method called in a closed handler")}assertSendDirection(){if("send"!==this._direction)throw new Error('method can just be called for handlers with "send" direction')}assertRecvDirection(){if("recv"!==this._direction)throw new Error('method can just be called for handlers with "recv" direction')}}t.Firefox120=m},1518:function(e,t,r){var n;!function(i,s){"use strict";var a="user-agent",o="",c="function",l="undefined",d="object",u="string",p="browser",h="cpu",f="device",m="engine",g="os",y="result",b="name",v="type",w="vendor",_="version",S="architecture",k="major",R="model",C="console",P="mobile",T="tablet",x="smarttv",D="wearable",E="xr",L="embedded",I="inapp",O="brands",M="formFactors",N="fullVersionList",j="platform",A="platformVersion",F="bitness",z="sec-ch-ua",B=z+"-full-version-list",$=z+"-arch",U=z+"-"+F,H=z+"-form-factors",q=z+"-"+P,V=z+"-"+R,K=z+"-"+j,Q=K+"-version",W=[O,N,P,R,j,A,S,M,F],G="Amazon",Y="Apple",X="ASUS",J="BlackBerry",Z="Google",ee="Huawei",te="Lenovo",re="Honor",ne="LG",ie="Microsoft",se="Motorola",ae="Nvidia",oe="OnePlus",ce="OPPO",le="Samsung",de="Sharp",ue="Sony",pe="Xiaomi",he="Zebra",fe="Chrome",me="Chromium",ge="Chromecast",ye="Firefox",be="Opera",ve="Facebook",we="Sogou",_e="Mobile ",Se=" Browser",ke="Windows",Re=typeof i!==l,Ce=Re&&i.navigator?i.navigator:s,Pe=Ce&&Ce.userAgentData?Ce.userAgentData:s,Te=function(e){for(var t={},r=0;r<e.length;r++)t[e[r].toUpperCase()]=e[r];return t},xe=function(e,t){if(typeof e===d&&e.length>0){for(var r in e)if(Ie(e[r])==Ie(t))return!0;return!1}return!!Ee(e)&&-1!==Ie(t).indexOf(Ie(e))},De=function(e,t){for(var r in e)return/^(browser|cpu|device|engine|os)$/.test(r)||!!t&&De(e[r])},Ee=function(e){return typeof e===u},Le=function(e){if(!e)return s;for(var t=[],r=Ne(/\\?\"/g,e).split(","),n=0;n<r.length;n++)if(r[n].indexOf(";")>-1){var i=Ae(r[n]).split(";v=");t[n]={brand:i[0],version:i[1]}}else t[n]=Ae(r[n]);return t},Ie=function(e){return Ee(e)?e.toLowerCase():e},Oe=function(e){return Ee(e)?Ne(/[^\d\.]/g,e).split(".")[0]:s},Me=function(e){for(var t in e){var r=e[t];typeof r==d&&2==r.length?this[r[0]]=r[1]:this[r]=s}return this},Ne=function(e,t){return Ee(t)?t.replace(e,o):t},je=function(e){return Ne(/\\?\"/g,e)},Ae=function(e,t){if(Ee(e))return e=Ne(/^\s\s*/,e),typeof t===l?e:e.substring(0,500)},Fe=function(e,t){if(e&&t)for(var r,n,i,a,o,l,u=0;u<t.length&&!o;){var p=t[u],h=t[u+1];for(r=n=0;r<p.length&&!o&&p[r];)if(o=p[r++].exec(e))for(i=0;i<h.length;i++)l=o[++n],typeof(a=h[i])===d&&a.length>0?2===a.length?typeof a[1]==c?this[a[0]]=a[1].call(this,l):this[a[0]]=a[1]:3===a.length?typeof a[1]!==c||a[1].exec&&a[1].test?this[a[0]]=l?l.replace(a[1],a[2]):s:this[a[0]]=l?a[1].call(this,l,a[2]):s:4===a.length&&(this[a[0]]=l?a[3].call(this,l.replace(a[1],a[2])):s):this[a]=l||s;u+=2}},ze=function(e,t){for(var r in t)if(typeof t[r]===d&&t[r].length>0){for(var n=0;n<t[r].length;n++)if(xe(t[r][n],e))return"?"===r?s:r}else if(xe(t[r],e))return"?"===r?s:r;return t.hasOwnProperty("*")?t["*"]:e},Be={ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2e3:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",10:["NT 6.4","NT 10.0"],RT:"ARM"},$e={embedded:"Automotive",mobile:"Mobile",tablet:["Tablet","EInk"],smarttv:"TV",wearable:"Watch",xr:["VR","XR"],"?":["Desktop","Unknown"],"*":s},Ue={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[_,[b,_e+"Chrome"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[_,[b,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[b,_],[/opios[\/ ]+([\w\.]+)/i],[_,[b,be+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[_,[b,be+" GX"]],[/\bopr\/([\w\.]+)/i],[_,[b,be]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[_,[b,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[_,[b,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser)\/([-\w\.]+)/i,/(heytap|ovi|115|surf)browser\/([\d\.]+)/i,/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i],[b,_],[/quark(?:pc)?\/([-\w\.]+)/i],[_,[b,"Quark"]],[/\bddg\/([\w\.]+)/i],[_,[b,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[_,[b,"UCBrowser"]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[_,[b,"WeChat"]],[/konqueror\/([\w\.]+)/i],[_,[b,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[_,[b,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[_,[b,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[_,[b,"Smart "+te+Se]],[/(avast|avg)\/([\w\.]+)/i],[[b,/(.+)/,"$1 Secure"+Se],_],[/\bfocus\/([\w\.]+)/i],[_,[b,ye+" Focus"]],[/\bopt\/([\w\.]+)/i],[_,[b,be+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[_,[b,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[_,[b,"Dolphin"]],[/coast\/([\w\.]+)/i],[_,[b,be+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[_,[b,"MIUI"+Se]],[/fxios\/([\w\.-]+)/i],[_,[b,_e+ye]],[/\bqihoobrowser\/?([\w\.]*)/i],[_,[b,"360"]],[/\b(qq)\/([\w\.]+)/i],[[b,/(.+)/,"$1Browser"],_],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[b,/(.+)/,"$1"+Se],_],[/samsungbrowser\/([\w\.]+)/i],[_,[b,le+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[_,[b,we+" Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[b,we+" Mobile"],_],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[b,_],[/(lbbrowser|rekonq)/i],[b],[/ome\/([\w\.]+) \w* ?(iron) saf/i,/ome\/([\w\.]+).+qihu (360)[es]e/i],[_,b],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[b,ve],_,[v,I]],[/(Klarna)\/([\w\.]+)/i,/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(instagram|snapchat)[\/ ]([-\w\.]+)/i],[b,_,[v,I]],[/\bgsa\/([\w\.]+) .*safari\//i],[_,[b,"GSA"],[v,I]],[/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i],[_,[b,"TikTok"],[v,I]],[/\[(linkedin)app\]/i],[b,[v,I]],[/(chromium)[\/ ]([-\w\.]+)/i],[b,_],[/headlesschrome(?:\/([\w\.]+)| )/i],[_,[b,fe+" Headless"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[b,fe+" WebView"],_],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[_,[b,"Android"+Se]],[/chrome\/([\w\.]+) mobile/i],[_,[b,_e+"Chrome"]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[b,_],[/version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i],[_,[b,_e+"Safari"]],[/iphone .*mobile(?:\/\w+ | ?)safari/i],[[b,_e+"Safari"]],[/version\/([\w\.\,]+) .*(safari)/i],[_,b],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[b,[_,"1"]],[/(webkit|khtml)\/([\w\.]+)/i],[b,_],[/(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i],[[b,_e+ye],_],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[b,"Netscape"],_],[/(wolvic|librewolf)\/([\w\.]+)/i],[b,_],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[_,[b,ye+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[b,[_,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[b,[_,/[^\d\.]+./,o]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[S,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[S,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[S,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[S,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[S,"arm"]],[/((ppc|powerpc)(64)?)( mac|;|\))/i],[[S,/ower/,o,Ie]],[/ sun4\w[;\)]/i],[[S,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i],[[S,Ie]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[R,[w,le],[v,T]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr])[-\w]+)/i,/sec-(sgh\w+)/i],[R,[w,le],[v,P]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i],[R,[w,Y],[v,P]],[/\((ipad);[-\w\),; ]+apple/i,/applecoremedia\/[\w\.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i],[R,[w,Y],[v,T]],[/(macintosh);/i],[R,[w,Y]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[R,[w,de],[v,P]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[R,[w,re],[v,T]],[/honor([-\w ]+)[;\)]/i],[R,[w,re],[v,P]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[R,[w,ee],[v,T]],[/(?:huawei)([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i],[R,[w,ee],[v,P]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[R,/_/g," "],[w,pe],[v,T]],[/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[R,/_/g," "],[w,pe],[v,P]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[R,[w,ce],[v,P]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[R,[w,ze,{OnePlus:["304","403","203"],"*":ce}],[v,T]],[/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i],[R,[w,"BLU"],[v,P]],[/; vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[R,[w,"Vivo"],[v,P]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[R,[w,"Realme"],[v,P]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ](\w*)/i,/((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i],[R,[w,se],[v,P]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[R,[w,se],[v,T]],[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[R,[w,ne],[v,T]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i,/\blg-?([\d\w]+) bui/i],[R,[w,ne],[v,P]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[R,[w,te],[v,T]],[/(nokia) (t[12][01])/i],[w,R,[v,T]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*))/i],[[R,/_/g," "],[v,P],[w,"Nokia"]],[/(pixel (c|tablet))\b/i],[R,[w,Z],[v,T]],[/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i],[R,[w,Z],[v,P]],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[R,[w,ue],[v,P]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[R,"Xperia Tablet"],[w,ue],[v,T]],[/ (kb2005|in20[12]5|be20[12][59])\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[R,[w,oe],[v,P]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[R,[w,G],[v,T]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[R,/(.+)/g,"Fire Phone $1"],[w,G],[v,P]],[/(playbook);[-\w\),; ]+(rim)/i],[R,w,[v,T]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/\(bb10; (\w+)/i],[R,[w,J],[v,P]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[R,[w,X],[v,T]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[R,[w,X],[v,P]],[/(nexus 9)/i],[R,[w,"HTC"],[v,T]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[w,[R,/_/g," "],[v,P]],[/tcl (xess p17aa)/i,/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i],[R,[w,"TCL"],[v,T]],[/droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i],[R,[w,"TCL"],[v,P]],[/(itel) ((\w+))/i],[[w,Ie],R,[v,ze,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[R,[w,"Acer"],[v,T]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[R,[w,"Meizu"],[v,P]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[R,[w,"Ulefone"],[v,P]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[R,[w,"Energizer"],[v,P]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[R,[w,"Cat"],[v,P]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[R,[w,"Smartfren"],[v,P]],[/droid.+; (a(?:015|06[35]|142p?))/i],[R,[w,"Nothing"],[v,P]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[R,[w,"Archos"],[v,T]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[R,[w,"Archos"],[v,P]],[/(imo) (tab \w+)/i,/(infinix) (x1101b?)/i],[w,R,[v,T]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (blu|hmd|imo|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i,/(oppo) ?([\w ]+) bui/i],[w,R,[v,P]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i],[w,R,[v,T]],[/(surface duo)/i],[R,[w,ie],[v,T]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[R,[w,"Fairphone"],[v,P]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[R,[w,ae],[v,T]],[/(sprint) (\w+)/i],[w,R,[v,P]],[/(kin\.[onetw]{3})/i],[[R,/\./g," "],[w,ie],[v,P]],[/droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[R,[w,he],[v,T]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[R,[w,he],[v,P]],[/smart-tv.+(samsung)/i],[w,[v,x]],[/hbbtv.+maple;(\d+)/i],[[R,/^/,"SmartTV"],[w,le],[v,x]],[/tcast.+(lg)e?. ([-\w]+)/i],[w,R,[v,x]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[w,ne],[v,x]],[/(apple) ?tv/i],[w,[R,Y+" TV"],[v,x]],[/crkey.*devicetype\/chromecast/i],[[R,ge+" Third Generation"],[w,Z],[v,x]],[/crkey.*devicetype\/([^/]*)/i],[[R,/^/,"Chromec