!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.P2pEngineHls=t():e.P2pEngineHls=t()}(this,(()=>(()=>{var e={415:e=>{"use strict";var t,s="object"==typeof Reflect?Reflect:null,i=s&&"function"==typeof s.apply?s.apply:function(e,t,s){return Function.prototype.apply.call(e,t,s)};t=s&&"function"==typeof s.ownKeys?s.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var r=Number.isNaN||function(e){return e!=e};function n(){n.init.call(this)}e.exports=n,e.exports.once=function(e,t){return new Promise((function(s,i){function r(s){e.removeListener(t,n),i(s)}function n(){"function"==typeof e.removeListener&&e.removeListener("error",r),s([].slice.call(arguments))}p(e,t,n,{once:!0}),"error"!==t&&function(e,t,s){"function"==typeof e.on&&p(e,"error",t,s)}(e,r,{once:!0})}))},n.EventEmitter=n,n.prototype._events=void 0,n.prototype._eventsCount=0,n.prototype._maxListeners=void 0;var o=10;function a(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function h(e){return void 0===e._maxListeners?n.defaultMaxListeners:e._maxListeners}function l(e,t,s,i){var r,n,o,l;if(a(s),void 0===(n=e._events)?(n=e._events=Object.create(null),e._eventsCount=0):(void 0!==n.newListener&&(e.emit("newListener",t,s.listener?s.listener:s),n=e._events),o=n[t]),void 0===o)o=n[t]=s,++e._eventsCount;else if("function"==typeof o?o=n[t]=i?[s,o]:[o,s]:i?o.unshift(s):o.push(s),(r=h(e))>0&&o.length>r&&!o.warned){o.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=o.length,l=c,console&&console.warn&&console.warn(l)}return e}function c(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function d(e,t,s){var i={fired:!1,wrapFn:void 0,target:e,type:t,listener:s},r=c.bind(i);return r.listener=s,i.wrapFn=r,r}function u(e,t,s){var i=e._events;if(void 0===i)return[];var r=i[t];return void 0===r?[]:"function"==typeof r?s?[r.listener||r]:[r]:s?function(e){for(var t=new Array(e.length),s=0;s0&&(o=t[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var h=n[e];if(void 0===h)return!1;if("function"==typeof h)i(h,this,t);else{var l=h.length,c=f(h,l);for(s=0;s=0;n--)if(s[n]===t||s[n].listener===t){o=s[n].listener,r=n;break}if(r<0)return this;0===r?s.shift():function(e,t){for(;t+1=0;i--)this.removeListener(e,t[i]);return this},n.prototype.listeners=function(e){return u(this,e,!0)},n.prototype.rawListeners=function(e){return u(this,e,!1)},n.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):g.call(e,t)},n.prototype.listenerCount=g,n.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},558:function(e){!function(t){var s=/^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/,i=/^(?=([^\/?#]*))\1([^]*)$/,r=/(?:\/|^)\.(?=\/)/g,n=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,o={buildAbsoluteURL:function(e,t,s){if(s=s||{},e=e.trim(),!(t=t.trim())){if(!s.alwaysNormalize)return e;var r=o.parseURL(e);if(!r)throw new Error("Error trying to parse base URL.");return r.path=o.normalizePath(r.path),o.buildURLFromParts(r)}var n=o.parseURL(t);if(!n)throw new Error("Error trying to parse relative URL.");if(n.scheme)return s.alwaysNormalize?(n.path=o.normalizePath(n.path),o.buildURLFromParts(n)):t;var a=o.parseURL(e);if(!a)throw new Error("Error trying to parse base URL.");if(!a.netLoc&&a.path&&"/"!==a.path[0]){var h=i.exec(a.path);a.netLoc=h[1],a.path=h[2]}a.netLoc&&!a.path&&(a.path="/");var l={scheme:a.scheme,netLoc:n.netLoc,path:null,params:n.params,query:n.query,fragment:n.fragment};if(!n.netLoc&&(l.netLoc=a.netLoc,"/"!==n.path[0]))if(n.path){var c=a.path,d=c.substring(0,c.lastIndexOf("/")+1)+n.path;l.path=o.normalizePath(d)}else l.path=a.path,n.params||(l.params=a.params,n.query||(l.query=a.query));return null===l.path&&(l.path=s.alwaysNormalize?o.normalizePath(n.path):n.path),o.buildURLFromParts(l)},parseURL:function(e){var t=s.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(r,"");e.length!==(e=e.replace(n,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}};e.exports=o}()},424:(e,t)=>{"use strict";t.h=r;var s=2147483647;function i(e){if(e>s)throw new RangeError('The value "'+e+'" is invalid for option "size"');var t=new Uint8Array(e);return t.__proto__=r.prototype,t}function r(e,t,s){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return a(e)}return n(e,t,s)}function n(e,t,s){if("string"==typeof e)return function(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!r.isEncoding(t))throw new TypeError("Unknown encoding: "+t);var s=0|c(e,t),n=i(s),o=n.write(e,t);o!==s&&(n=n.slice(0,o));return n}(e,t);if(ArrayBuffer.isView(e))return h(e);if(null==e)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(_(e,ArrayBuffer)||e&&_(e.buffer,ArrayBuffer))return function(e,t,s){if(t<0||e.byteLength=s)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s.toString(16)+" bytes");return 0|e}function c(e,t){if(r.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||_(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);var s=e.length,i=arguments.length>2&&!0===arguments[2];if(!i&&0===s)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return s;case"utf8":case"utf-8":return m(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*s;case"hex":return s>>>1;default:if(n)return i?-1:m(e).length;t=(""+t).toLowerCase(),n=!0}}function d(e,t,s,i){s=Number(s)||0;const r=e.length-s;i?(i=Number(i))>r&&(i=r):i=r;const n=t.length;let o;for(i>n/2&&(i=n/2),o=0;o>8,r=s%256,n.push(r),n.push(i);return n}(t,e.length-s),e,s,i)}function p(e,t,s,i){let r;for(r=0;r=t.length||r>=e.length);++r)t[r+s]=e[r];return r}function m(e,t){var s;t=t||1/0;for(var i=e.length,r=null,n=[],o=0;o55295&&s<57344){if(!r){if(s>56319){(t-=3)>-1&&n.push(239,191,189);continue}if(o+1===i){(t-=3)>-1&&n.push(239,191,189);continue}r=s;continue}if(s<56320){(t-=3)>-1&&n.push(239,191,189),r=s;continue}s=65536+(r-55296<<10|s-56320)}else r&&(t-=3)>-1&&n.push(239,191,189);if(r=null,s<128){if((t-=1)<0)break;n.push(s)}else if(s<2048){if((t-=2)<0)break;n.push(s>>6|192,63&s|128)}else if(s<65536){if((t-=3)<0)break;n.push(s>>12|224,s>>6&63|128,63&s|128)}else{if(!(s<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;n.push(s>>18|240,s>>12&63|128,s>>6&63|128,63&s|128)}}return n}function _(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function S(e){return e!=e}"undefined"!=typeof Symbol&&null!=Symbol.species&&r[Symbol.species]===r&&Object.defineProperty(r,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),r.from=function(e,t,s){return n(e,t,s)},r.prototype.__proto__=Uint8Array.prototype,r.__proto__=Uint8Array,r.alloc=function(e,t,s){return function(e,t,s){return o(e),e<=0?i(e):void 0!==t?"string"==typeof s?i(e).fill(t,s):i(e).fill(t):i(e)}(e,t,s)},r.allocUnsafe=function(e){return a(e)},r.isBuffer=function(e){return null!=e&&!0===e._isBuffer&&e!==r.prototype},r.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},r.concat=function(e,t){if(!Array.isArray(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return r.alloc(0);var s;if(void 0===t)for(t=0,s=0;s=e.length&&(t=e.length),t||(t=0),i>0&&i=this.length)throw new RangeError("Index out of range");if(i<0)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t=0;--o)e[o+t]=this[o+s];else Uint8Array.prototype.set.call(e,this.subarray(s,i),t);return n},r.prototype.write=function(e,t,s,i){if(void 0===t)i="utf8",s=this.length,t=0;else if(void 0===s&&"string"==typeof t)i=t,s=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t>>>=0,isFinite(s)?(s>>>=0,void 0===i&&(i="utf8")):(i=s,s=void 0)}const r=this.length-t;if((void 0===s||s>r)&&(s=r),e.length>0&&(s<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");i||(i="utf8");let n=!1;for(;;)switch(i){case"hex":return d(this,e,t,s);case"utf8":case"utf-8":return u(this,e,t,s);case"ascii":case"latin1":case"binary":return g(this,e,t,s);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return f(this,e,t,s);default:if(n)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),n=!0}}},832:function(e,t,s){var i;!function(r){"use strict";function n(e,t){var s=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(s>>16)<<16|65535&s}function o(e,t,s,i,r,o){return n((a=n(n(t,e),n(i,o)))<<(h=r)|a>>>32-h,s);var a,h}function a(e,t,s,i,r,n,a){return o(t&s|~t&i,e,t,r,n,a)}function h(e,t,s,i,r,n,a){return o(t&i|s&~i,e,t,r,n,a)}function l(e,t,s,i,r,n,a){return o(t^s^i,e,t,r,n,a)}function c(e,t,s,i,r,n,a){return o(s^(t|~i),e,t,r,n,a)}function d(e,t){var s,i,r,o,d;e[t>>5]|=128<>>9<<4)]=t;var u=1732584193,g=-271733879,f=-1732584194,p=271733878;for(s=0;s>5]>>>t%32&255);return s}function g(e){var t,s=[];for(s[(e.length>>2)-1]=void 0,t=0;t>5]|=(255&e.charCodeAt(t/8))<>>4&15)+i.charAt(15&t);return r}function p(e){return unescape(encodeURIComponent(e))}function m(e){return function(e){return u(d(g(e),8*e.length))}(p(e))}function _(e,t){return function(e,t){var s,i,r=g(e),n=[],o=[];for(n[15]=o[15]=void 0,r.length>16&&(r=d(r,8*e.length)),s=0;s<16;s+=1)n[s]=909522486^r[s],o[s]=1549556828^r[s];return i=d(n.concat(g(t)),512+8*t.length),u(d(o.concat(i),640))}(p(e),p(t))}function S(e,t,s){return t?s?_(t,e):f(_(t,e)):s?m(e):f(m(e))}void 0===(i=function(){return S}.call(t,s,t,e))||(e.exports=i)}()},365:e=>{const t={ANDROID_WEB:"android-web",IOS_WEB:"iOS-web",PC_NATIVE:"PC-web",PC_WEB:"PC-web"};var s={getNetType:function(){let e=(new RegExp("nettype\\/(\\w*)").exec(i())||[,""])[1].toLowerCase();if(!e&&navigator.connection){switch(navigator.connection.type){case"ethernet":e="ethernet";break;case"cellular":e="cellular";break;default:e="wifi"}}return e},getPlatform:function(){return s.isAndroid()||s.isAndroidWebView()?t.ANDROID_WEB:s.isIOS()||s.isIpad()||s.isIOSWebView()?t.IOS_WEB:s.isElectron()?t.PC_NATIVE:t.PC_WEB},isX5:function(){return this.isAndroid()&&/\s(TBS|X5Core)\/[\w\.\-]+/i.test(i())},isPC:function(){return!n(r("os "))&&!n(r("android[/ ]"))},isIOS:function(){return n(r("os "))},isIpad:function(){return i().match(/(ipad)/)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1},isAndroid:function(){return n(r("android[/ ]"))},isIOSSafari:function(){return this.isIOS()&&this.isSafari()},isIpadSafari:function(){return this.isIpad()&&this.isSafari()},isElectron:function(){return/electron/i.test(i())},isMobile:function(){return s.isAndroid()||s.isIOS()},isSafari:function(){return/^((?!chrome|android).)*safari/i.test(i())},isFirefox:function(){return/firefox/i.test(i())},isChrome:function(){return/chrome/i.test(i())},isLocalHost:function(){return"localhost"===location.hostname},isAndroidWebView:function(){const e=i();return e.indexOf("wv")>-1&&e.indexOf("android")>-1},isIOSWebView:function(){const e=i();return/\b(ipad|iphone|macintosh).*applewebKit(?!.*safari)/i.test(e)},isWebView:function(){return s.isAndroidWebView()||s.isIOSWebView()},device:t,getBrowser:function(){return s.isX5()?"X5":s.isAndroidWebView()?"Android-WebView":s.isIOSWebView()?"iOS-WebView":s.isChrome()?"Chrome":s.isFirefox()?"Firefox":s.isIpadSafari()?"iPad-Safari":s.isIOSSafari()?"iPhone-Safari":s.isSafari()?"Mac-Safari":"Unknown"}};function i(){return navigator.userAgent.toLowerCase()}function r(e){return""+(new RegExp(e+"(\\d+((\\.|_)\\d+)*)").exec(i())||[,0])[1]||void 0}function n(e){return parseFloat((e||"").replace(/\_/g,"."))||0}e.exports=s}},t={};function s(i){var r=t[i];if(void 0!==r)return r.exports;var n=t[i]={exports:{}};return e[i].call(n.exports,n,n.exports,s),n.exports}s.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return s.d(t,{a:t}),t},s.d=(e,t)=>{for(var i in t)s.o(t,i)&&!s.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var i={};return(()=>{"use strict";s.d(i,{default:()=>Ds});const e={DC_SIGNAL:"SIGNAL",DC_SIGNAL_BATCH:"SIGNAL_BATCH",DC_OPEN:"OPEN",DC_REQUEST:"REQUEST",DC_PIECE_NOT_FOUND:"PIECE_NOT_FOUND",DC_PIECE_ABORT:"PIECE_ABORT",DC_PIECE_CANCEL:"PIECE_CANCEL",DC_CLOSE:"CLOSE",DC_DISCONNECT:"DISCONNECT",DC_RESPONSE:"RESPONSE",DC_ERROR:"ERROR",DC_PIECE:"PIECE",DC_PIECE_DATA:"PIECE_DATA",DC_TIMEOUT:"TIMEOUT",DC_PIECE_ACK:"PIECE_ACK",DC_METADATA:"METADATA",DC_PLAT_ANDROID:"ANDROID",DC_PLAT_IOS:"IOS",DC_PLAT_WEB:"WEB",DC_CHOKE:"CHOKE",DC_UNCHOKE:"UNCHOKE",DC_HAVE:"HAVE",DC_HAVE_REVERSE:"HAVE_REVERSE",DC_LOST:"LOST",DC_GET_PEERS:"GET_PEERS",DC_PEERS:"PEERS",DC_STATS:"STATS",DC_PEER_SIGNAL:"PEER_SIGNAL",DC_PLAYLIST:"PLAYLIST",BM_LOST:"lost",BM_ADDED_SEG_:"BM_ADDED_SEG_",BM_ADDED_SN_:"BM_ADDED_SN_",BM_SEG_ADDED:"BM_SEG_ADDED",BM_FATAL_ERROR:"BM_FATAL_ERROR",FRAG_CHANGED:"FRAG_CHANGED",FRAG_LOADED:"FRAG_LOADED",FRAG_LOADING:"FRAG_LOADING",RESTART_P2P:"RESTART_P2P",EXCEPTION:"exception",SYN_OUTPUT:"SYN_OUTPUT",SYN_ERROR:"SYN_ERROR",SYN_PROGRESS:"SYN_PROGRESS",MEDIA_REBUFFER:"MEDIA_REBUFFER"},t={...e,SW_PLAYLIST:"SW_PLAYLIST",SW_GET_PLAYLIST:"SW_GET_PLAYLIST",SW_GET_MEDIA:"SW_GET_MEDIA",SW_DEBUG:"SW_DEBUG",LEVEL_LOADED:"LEVEL_LOADED",MANIFEST_PARSED:"MANIFEST_PARSED"};var r=s(415),n=s.n(r),o=s(424),a=s(558),h=s.n(a);const l="__PROXY_IDENTIFIER__";const c=64e3;function d(){return!0}function u(e){return new URL(location.href).searchParams.get(e)}function g(e,t,s){const i=new URL(e);return i.searchParams.append(t,s),i.href}function f(){return Date.parse(new Date)/1e3}function p(e,t){return parseInt(Math.random()*(t-e+1)+e,10)}function m(e){return new Promise((t=>setTimeout(t,e)))}function _(){if("object"!=typeof self)return null;var e={RTCPeerConnection:self.RTCPeerConnection||self.mozRTCPeerConnection||self.webkitRTCPeerConnection,RTCSessionDescription:self.RTCSessionDescription||self.mozRTCSessionDescription||self.webkitRTCSessionDescription,RTCIceCandidate:self.RTCIceCandidate||self.mozRTCIceCandidate||self.webkitRTCIceCandidate};return e.RTCPeerConnection&&e.RTCPeerConnection.prototype?e:null}function S(e){const t=o.h.from(e),s=new o.h(e.byteLength);return t.copy(s),s}function y(){return location.protocol.startsWith("https")}function v(e,t,s){if(e.size<=t)return;const i=[...e.keys()];do{const t=i.shift();s&&s(e.get(t)),e.delete(t)}while(e.size>t)}function P(e,t){if(e.size<=t)return;const s=[...e.values()];do{e.delete(s.shift())}while(e.size>t)}function E(e){return e instanceof ArrayBuffer&&0!==e.byteLength}function b(e){if(!e)return{};const t=(e=e.substring(6)).split("-");if(2!==t.length)return{};const s=Number(t[0]),i=t[1]?Number(t[1]):-1;return{rangeStart:s,rangeEnd:i>=0?i+1:void 0}}function w(e){return e.split("?")[0]}function C(){let e=new Date,t=e.getHours(),s=e.getMinutes(),i=e.getSeconds(),r=e.getMilliseconds();return`${t.toString().padStart(2,"0")}:${s.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}.${r}`}function T(e){return e&&"function"==typeof e}function I(e,t,s,i,r,n){e.sendPartialBuffer(s,i,{from:r,incompletes:n})&&(i.length{i?t.sendMsgPieceAbort(r,s,!0):t.uploading&&t.send(r),n&&(t.uploading=!1)}))}(t,e,!!s.reverse):e.uploading=!1)}const L=e=>0===p(0,1)?[null,e]:[e,null];function R(e,t,s){return 1===e.length?t.length>=1&&s.length>=1?t[0].weight>s[0].weight?[t[0],e[0]]:[e[0],s[0]]:t.length>=1?[t[0],e[0]]:s.length>=1?[e[0],s[0]]:L(e[0]):[t.length>=1?t[0]:null,s.length>=1?s[0]:null]}function A(){const e=performance.now();return{trequest:e,tfirst:0,tload:0,aborted:!1,loaded:0,retry:0,total:0,chunkCount:0,bwEstimate:0,loading:{start:e,first:0,end:0},parsing:{start:0,end:0},buffering:{start:0,first:0,end:0}}}async function D(e){if(crypto.subtle)try{const t=await crypto.subtle.digest("SHA-256",e),s=String.fromCharCode.apply(null,new Uint8Array(t));return btoa(s)}catch(e){}}class M{constructor(e,t){this.target=t,this.type=e}}class k extends M{constructor(e,t){super("error",t),this.message=e.message,this.error=e}}class N extends M{constructor(e=1e3,t="",s){super("close",s),this.code=e,this.reason=t,this.wasClean=!0}}const O=()=>{if("undefined"!=typeof WebSocket)return WebSocket},$={maxReconnectionDelay:1e4,minReconnectionDelay:1e3+4e3*Math.random(),minUptime:5e3,reconnectionDelayGrowFactor:1.3,connectionTimeout:4e3,maxRetries:1/0,maxEnqueuedMessages:1/0,startClosed:!1};class B{constructor(e,t,s={}){this._listeners={error:[],message:[],open:[],close:[]},this.onclose=null,this.onerror=null,this.onmessage=null,this.onopen=null,this._messageQueue=[],this._closeCalled=!1,this._connectLock=!1,this._shouldReconnect=!0,this._retryCount=-1,this._binaryType="blob",this._url=e,this._protocols=t,this._options=s,this._options.startClosed&&(this._shouldReconnect=!1),this._connect(),this._handleOpen=this._handleOpen.bind(this),this._handleClose=this._handleClose.bind(this),this._handleMessage=this._handleMessage.bind(this),this._handleError=this._handleError.bind(this)}static get CONNECTING(){return 0}static get OPEN(){return 1}static get CLOSING(){return 2}static get CLOSED(){return 3}get CONNECTING(){return B.CONNECTING}get OPEN(){return B.OPEN}get CLOSING(){return B.CLOSING}get CLOSED(){return B.CLOSED}get readyState(){return this._ws?this._ws.readyState:this._options.startClosed?B.CLOSED:B.CONNECTING}get url(){return this._ws?this._ws.url:""}close(e=1e3,t){this._closeCalled=!0,this._shouldReconnect=!1,this._clearTimeouts(),this._ws&&this._ws.readyState!==this.CLOSED&&this._ws.close(e,t)}reconnect(e,t){this._shouldReconnect=!0,this._closeCalled=!1,this._retryCount=-1,this._ws&&this._ws.readyState!==this.CLOSED?(this._disconnect(e,t),this._connect()):this._connect()}send(e){if(this._ws&&this._ws.readyState===this.OPEN)this._ws.send(e);else{const{maxEnqueuedMessages:t=$.maxEnqueuedMessages}=this._options;this._messageQueue.lengthe!==t)))}_getNextDelay(){const{reconnectionDelayGrowFactor:e=$.reconnectionDelayGrowFactor,minReconnectionDelay:t=$.minReconnectionDelay,maxReconnectionDelay:s=$.maxReconnectionDelay}=this._options;let i=0;return this._retryCount>0&&(i=t*Math.pow(e,this._retryCount-1),i>s&&(i=s)),i}_wait(){return new Promise((e=>{setTimeout(e,this._getNextDelay())}))}_getNextUrl(e){if("string"==typeof e)return Promise.resolve(e);if("function"==typeof e){const t=e();if("string"==typeof t)return Promise.resolve(t);if(t.then)return t}throw Error("Invalid URL")}_connect(){if(this._connectLock||!this._shouldReconnect)return;this._connectLock=!0;const{maxRetries:e=$.maxRetries,connectionTimeout:t=$.connectionTimeout,WebSocket:s=O()}=this._options;if(!(this._retryCount>=e)){if(this._retryCount++,this._removeListeners(),void 0===(i=s)||!i||2!==i.CLOSING)throw Error("No valid WebSocket class provided");var i;this._wait().then((()=>this._getNextUrl(this._url))).then((e=>{this._closeCalled?this._connectLock=!1:(this._ws=this._protocols?new s(e,this._protocols):new s(e),this._ws.binaryType=this._binaryType,this._connectLock=!1,this._addListeners(),this._connectTimeout=setTimeout((()=>this._handleTimeout()),t))})).catch((e=>{this._connectLock=!1,this._handleError(new k(Error(e.message),this))}))}}_handleTimeout(){this._handleError(new k(Error("TIMEOUT"),this))}_disconnect(e=1e3,t){if(this._clearTimeouts(),this._ws){this._removeListeners();try{this._ws.close(e,t),this._handleClose(new N(e,t,this))}catch(e){}}}_acceptOpen(){this._retryCount=0}_callEventListener(e,t){"handleEvent"in t?t.handleEvent(e):t(e)}_handleOpen(e){const{minUptime:t=$.minUptime}=this._options;clearTimeout(this._connectTimeout),this._uptimeTimeout=setTimeout((()=>this._acceptOpen()),t),this._ws.binaryType=this._binaryType,this._messageQueue.forEach((e=>this._ws.send(e))),this._messageQueue=[],this.onopen&&this.onopen(e),this._listeners.open.forEach((t=>this._callEventListener(e,t)))}_handleMessage(e){this.onmessage&&this.onmessage(e),this._listeners.message.forEach((t=>this._callEventListener(e,t)))}_handleError(e){this._disconnect(void 0,"TIMEOUT"===e.message?"timeout":void 0),this.onerror&&this.onerror(e),this._listeners.error.forEach((t=>this._callEventListener(e,t))),this._connect()}_handleClose(e){this._clearTimeouts(),this._shouldReconnect&&this._connect(),this.onclose&&this.onclose(e),this._listeners.close.forEach((t=>this._callEventListener(e,t)))}_removeListeners(){this._ws&&(this._ws.removeEventListener("open",this._handleOpen),this._ws.removeEventListener("close",this._handleClose),this._ws.removeEventListener("message",this._handleMessage),this._ws.removeEventListener("error",this._handleError))}_addListeners(){this._ws&&(this._ws.addEventListener("open",this._handleOpen),this._ws.addEventListener("close",this._handleClose),this._ws.addEventListener("message",this._handleMessage),this._ws.addEventListener("error",this._handleError))}_clearTimeouts(){clearTimeout(this._connectTimeout),clearTimeout(this._uptimeTimeout)}}const x={debug:3,info:4,warn:5,error:6};class F{constructor(e,t,s,i){this.wsAddr=`${e}?app=${t}&id=${s}&v=${i}`,this.destroyed=!1;try{this._ws=this._init()}catch(e){console.error(e)}}_init(){const e={maxRetries:3,minReconnectionDelay:p(5e3,15e3),maxReconnectionDelay:6e5,maxEnqueuedMessages:200};return new B(this.wsAddr,void 0,e)}send(e,t){if(this.destroyed)return;const s=x[e];this._ws.send(JSON.stringify({records:[{level:s,text:`${C()}: ${t}`}]}))}sendBatch(e){const t=[];for(let s of e)t.push({level:x[s.levelKey],text:s.message});this._ws.send(JSON.stringify({records:t}))}destroy(){this._ws&&(this._ws.close(1e3),this._ws=null,this.destroyed=!0)}}const q=e=>{const t=localStorage.getItem(e);try{const e=JSON.parse(t);return e.value?e.value:e}catch(e){return t}},W=(e,t,s)=>{((e,t)=>{"object"==typeof t&&(t=JSON.stringify(t)),localStorage.setItem(e,t)})(e,{value:t,duration:s,startTime:Date.now()})},z={debug:0,info:1,warn:2,error:3,none:4};const U=class{constructor(e){this.logLevel=e,this.onlineDebug=!1,this.logCache=[];try{console.debug=console.log}catch(e){console.debug=console.info}"debug"!==e&&"info"!==e||(this.logLevel="error"),q("SW_DEBUG")&&(this.logLevel="debug"),!0===e?this.logLevel="warn":!1===e?this.logLevel="none":e in z||(this.logLevel="error"),this.resetLogger()}enableDebug(){this.onlineDebug=!0;for(let e in z)this[e]=console[e];this._hookLogFunc(((e,t)=>{this.logUploader&&this.logUploader.send(e,t)}))}enableReport(e){this.reportUrl=e,this._hookLogFunc(((e,t)=>{this.reportUrl?(this.logCache.push({levelKey:e,message:`${C()}: ${t}`}),this.logCache.length>350&&this.logCache.shift()):this.reporter&&this.reporter.send(e,t)}))}report(e,t,s,i,r=5e3){this.reportUrl&&!this.reporter&&(e&&this.logCache.unshift({levelKey:"info",message:e}),this.reporter=new F(this.reportUrl,t,s,i),this.reporter._ws.addEventListener("open",(()=>{this.reportUrl=void 0,this.reporter.sendBatch(this.logCache),setTimeout((()=>{this.reporter.destroy(),this.reporter=null}),r)}),{once:!0}))}_hookLogFunc(e){for(let t in z){const s=this[t];this[t]=i=>{e(t,i),s(i)}}}setUploader(e){this.logUploader=e}resetLogger(){this.onlineDebug=!1;for(let e in z)z[e](H||(H=Promise.resolve())).then(e).catch((e=>setTimeout((()=>{throw e}),0))),G=65536;function V(e){return e.replace(/a=ice-options:trickle\s\n/g,"")}class X extends(n()){constructor(e){super(),this.channelName=e.initiator?e.channelName:null,this.initiator=e.initiator||!1,this.channelConfig=e.channelConfig||X.channelConfig,this.channelNegotiated=this.channelConfig.negotiated,this.config=Object.assign({},X.config,e.config),this.offerOptions=e.offerOptions||{},this.answerOptions=e.answerOptions||{},this.sdpTransform=e.sdpTransform||(e=>e),this.trickle=void 0===e.trickle||e.trickle,this.allowHalfTrickle=void 0!==e.allowHalfTrickle&&e.allowHalfTrickle,this.iceCompleteTimeout=e.iceCompleteTimeout||5e3,this.destroyed=!1,this.destroying=!1,this._connected=!1,this.remoteAddress=void 0,this.remoteFamily=void 0,this.remotePort=void 0,this.localAddress=void 0,this.localFamily=void 0,this.localPort=void 0,this._wrtc=_(),this._pcReady=!1,this._channelReady=!1,this._iceComplete=!1,this._iceCompleteTimer=null,this._channel=null,this._pendingCandidates=[],this._pendingData=[],this._isNegotiating=!1,this._firstNegotiation=!0,this._batchedNegotiation=!1,this._queuedNegotiation=!1,this._senderMap=new Map,this._closingInterval=null,this._chunk=null,this._cb=null,this._interval=null;try{this._pc=new this._wrtc.RTCPeerConnection(this.config)}catch(e){return void j((()=>this.destroy(e)))}this._pc.oniceconnectionstatechange=()=>{this._onIceStateChange()},this._pc.onicegatheringstatechange=()=>{this._onIceStateChange()},this._pc.onconnectionstatechange=()=>{this._onConnectionStateChange()},this._pc.onsignalingstatechange=()=>{this._onSignalingStateChange()},this._pc.onicecandidate=e=>{this._onIceCandidate(e)},this.initiator||this.channelNegotiated?this._setupData({channel:this._pc.createDataChannel(this.channelName,this.channelConfig)}):this._pc.ondatachannel=e=>{this._setupData(e)},this._needsNegotiation()}get bufferSize(){return this._channel&&this._channel.bufferedAmount||0}get connected(){return this._connected&&"open"===this._channel.readyState}signal(e){if(!this.destroyed&&this._pc){if("string"==typeof e)try{e=JSON.parse(e)}catch(t){e={}}if(e.renegotiate&&this.initiator&&this._needsNegotiation(),e.candidate)if(this._pc.remoteDescription&&this._pc.remoteDescription.type)try{this._addIceCandidate(e.candidate)}catch(e){}else this._pendingCandidates.push(e.candidate);e.sdp&&this._pc.setRemoteDescription(new this._wrtc.RTCSessionDescription(e)).then((()=>{this.destroyed||(this._pendingCandidates.forEach((e=>{try{this._addIceCandidate(e)}catch(e){}})),this._pendingCandidates=[],"offer"===this._pc.remoteDescription.type&&this._createAnswer())})).catch((e=>{e.debug=!0,this.destroy(e)})),e.sdp||e.candidate||e.renegotiate||e.transceiverRequest||this.destroy(new Error("signal() called with invalid signal data"))}}_addIceCandidate(e){const t=new this._wrtc.RTCIceCandidate(e);this._pc.addIceCandidate(t).catch((e=>{var s;!t.address||t.address.endsWith(".local")?(s="Ignoring unsupported ICE candidate.",console.warn(s)):(e.debug=!0,this.destroy(e))}))}send(e){if("string"==typeof e){RTCDataChannel.prototype.send.toString().includes("[native code]")&&this._channel.send(e)}else this._channel.send(e)}_needsNegotiation(){this._batchedNegotiation||(this._batchedNegotiation=!0,j((()=>{this._batchedNegotiation=!1,!this.initiator&&this._firstNegotiation||this.negotiate(),this._firstNegotiation=!1})))}negotiate(){this.initiator?this._isNegotiating?this._queuedNegotiation=!0:setTimeout((()=>{this._createOffer()}),0):this._isNegotiating?this._queuedNegotiation=!0:this.emit("signal",{type:"renegotiate",renegotiate:!0}),this._isNegotiating=!0}destroy(e){this._destroy(e)}_destroy(e){this.destroyed||this.destroying||(this.destroying=!0,j((()=>{if(this.destroyed=!0,this.destroying=!1,this._connected=!1,this._pcReady=!1,this._channelReady=!1,this._senderMap=null,clearInterval(this._closingInterval),this._closingInterval=null,clearInterval(this._interval),this._interval=null,this._chunk=null,this._cb=null,this._channel){try{this._channel.close()}catch(e){}this._channel.onmessage=null,this._channel.onopen=null,this._channel.onclose=null,this._channel.onerror=null}if(this._pc){try{this._pc.close()}catch(e){}this._pc.oniceconnectionstatechange=null,this._pc.onicegatheringstatechange=null,this._pc.onsignalingstatechange=null,this._pc.onicecandidate=null,this._pc.ondatachannel=null}this._pc=null,this._channel=null,e&&this.emit("error",e),this.emit("close")})))}_setupData(e){if(!e.channel)return this.destroy(new Error("Data channel event is missing `channel` property"));this._channel=e.channel,this._channel.binaryType="arraybuffer","number"==typeof this._channel.bufferedAmountLowThreshold&&(this._channel.bufferedAmountLowThreshold=G),this.channelName=this._channel.label,this._channel.onmessage=e=>{this._onChannelMessage(e)},this._channel.onbufferedamountlow=()=>{this._onChannelBufferedAmountLow()},this._channel.onopen=()=>{this._onChannelOpen()},this._channel.onclose=()=>{this._onChannelClose()},this._channel.onerror=e=>{e.debug=!0,this.destroy(e)};let t=!1;this._closingInterval=setInterval((()=>{this._channel&&"closing"===this._channel.readyState?(t&&this._onChannelClose(),t=!0):t=!1}),5e3)}get isBufferedAmountHigh(){return this._channel.bufferedAmount>G}write(e,t){if(this.destroyed)return t(new Error("cannot write after peer is destroyed"));if(this._connected){try{this.send(e)}catch(e){return this.destroy(e)}this.isBufferedAmountHigh?this._cb=t:t(null)}else this._chunk=e,this._cb=t}_startIceCompleteTimeout(){this.destroyed||this._iceCompleteTimer||(this._iceCompleteTimer=setTimeout((()=>{this._iceComplete||(this._iceComplete=!0,this.emit("iceTimeout"),this.emit("_iceComplete"))}),this.iceCompleteTimeout))}_createOffer(){this.destroyed||this._pc.createOffer(this.offerOptions).then((e=>{if(this.destroyed)return;this.trickle||this.allowHalfTrickle||(e.sdp=V(e.sdp)),e.sdp=this.sdpTransform(e.sdp);const t=()=>{if(this.destroyed)return;const t=this._pc.localDescription||e;this.emit("signal",{type:t.type,sdp:t.sdp})};this._pc.setLocalDescription(e).then((()=>{this.destroyed||(this.trickle||this._iceComplete?t():this.once("_iceComplete",t))})).catch((e=>{this.destroy(e)}))})).catch((e=>{this.destroy(e)}))}_createAnswer(){this.destroyed||this._pc.createAnswer(this.answerOptions).then((e=>{if(this.destroyed)return;this.trickle||this.allowHalfTrickle||(e.sdp=V(e.sdp)),e.sdp=this.sdpTransform(e.sdp);const t=()=>{if(this.destroyed)return;const t=this._pc.localDescription||e;this.emit("signal",{type:t.type,sdp:t.sdp})};this._pc.setLocalDescription(e).then((()=>{this.destroyed||(this.trickle||this._iceComplete?t():this.once("_iceComplete",t))})).catch((e=>{this.destroy(e)}))})).catch((e=>{this.destroy(e)}))}_onConnectionStateChange(){this.destroyed||"failed"===this._pc.connectionState&&this.destroy(new Error("Connection failed."))}_onIceStateChange(){if(this.destroyed)return;const e=this._pc.iceConnectionState,t=this._pc.iceGatheringState;this.emit("iceStateChange",e,t),"connected"!==e&&"completed"!==e||(this._pcReady=!0,this._maybeReady()),"failed"===e&&this.destroy(new Error("Ice connection failed.")),"closed"===e&&this.destroy(new Error("Ice connection closed."))}getStats(e){const t=e=>("[object Array]"===Object.prototype.toString.call(e.values)&&e.values.forEach((t=>{Object.assign(e,t)})),e);0===this._pc.getStats.length?this._pc.getStats().then((s=>{const i=[];s.forEach((e=>{i.push(t(e))})),e(null,i)}),(t=>e(t))):this._pc.getStats.length>0?this._pc.getStats((s=>{if(this.destroyed)return;const i=[];s.result().forEach((e=>{const s={};e.names().forEach((t=>{s[t]=e.stat(t)})),s.id=e.id,s.type=e.type,s.timestamp=e.timestamp,i.push(t(s))})),e(null,i)}),(t=>e(t))):e(null,[])}_maybeReady(){if(this._connected||this._connecting||!this._pcReady||!this._channelReady)return;this._connecting=!0;const e=()=>{this.destroyed||this.getStats(((t,s)=>{if(this.destroyed)return;t&&(s=[]);const i={},r={},n={};let o=!1;s.forEach((e=>{"remotecandidate"!==e.type&&"remote-candidate"!==e.type||(i[e.id]=e),"localcandidate"!==e.type&&"local-candidate"!==e.type||(r[e.id]=e),"candidatepair"!==e.type&&"candidate-pair"!==e.type||(n[e.id]=e)}));const a=e=>{o=!0;let t=r[e.localCandidateId];t&&(t.ip||t.address)?(this.localAddress=t.ip||t.address,this.localPort=Number(t.port)):t&&t.ipAddress?(this.localAddress=t.ipAddress,this.localPort=Number(t.portNumber)):"string"==typeof e.googLocalAddress&&(t=e.googLocalAddress.split(":"),this.localAddress=t[0],this.localPort=Number(t[1])),this.localAddress&&(this.localFamily=this.localAddress.includes(":")?"IPv6":"IPv4");let s=i[e.remoteCandidateId];s&&(s.ip||s.address)?(this.remoteAddress=s.ip||s.address,this.remotePort=Number(s.port)):s&&s.ipAddress?(this.remoteAddress=s.ipAddress,this.remotePort=Number(s.portNumber)):"string"==typeof e.googRemoteAddress&&(s=e.googRemoteAddress.split(":"),this.remoteAddress=s[0],this.remotePort=Number(s[1])),this.remoteAddress&&(this.remoteFamily=this.remoteAddress.includes(":")?"IPv6":"IPv4")};if(s.forEach((e=>{"transport"===e.type&&e.selectedCandidatePairId&&a(n[e.selectedCandidatePairId]),("googCandidatePair"===e.type&&"true"===e.googActiveConnection||("candidatepair"===e.type||"candidate-pair"===e.type)&&e.selected)&&a(e)})),o||Object.keys(n).length&&!Object.keys(r).length){if(this._connecting=!1,this._connected=!0,this._chunk){try{this.send(this._chunk)}catch(t){return this.destroy(t)}this._chunk=null;const e=this._cb;this._cb=null,e(null)}"number"!=typeof this._channel.bufferedAmountLowThreshold&&(this._interval=setInterval((()=>this._onInterval()),150),this._interval.unref&&this._interval.unref()),this.emit("connect");for(let e of this._pendingData)this.emit("data",e);this._pendingData=[]}else setTimeout(e,100)}))};e()}_onInterval(){!this._cb||!this._channel||this._channel.bufferedAmount>G||this._onChannelBufferedAmountLow()}_onSignalingStateChange(){this.destroyed||("stable"===this._pc.signalingState&&(this._isNegotiating=!1,this._queuedNegotiation?(this._queuedNegotiation=!1,this._needsNegotiation()):this.emit("negotiated")),this.emit("signalingStateChange",this._pc.signalingState))}_onIceCandidate(e){this.destroyed||(e.candidate&&this.trickle?this.emit("signal",{type:"candidate",candidate:{candidate:e.candidate.candidate,sdpMLineIndex:e.candidate.sdpMLineIndex,sdpMid:e.candidate.sdpMid}}):e.candidate||this._iceComplete||(this._iceComplete=!0,this.emit("_iceComplete")),e.candidate&&this._startIceCompleteTimeout())}_onChannelMessage(e){if(this.destroyed)return;let t=e.data;t instanceof ArrayBuffer&&(t=o.h.from(t)),this._connected?this.emit("data",t):this._pendingData.length<10&&this._pendingData.push(t)}_onChannelBufferedAmountLow(){if(this.destroyed||!this._cb)return;const e=this._cb;this._cb=null,e(null)}_onChannelOpen(){this._connected||this.destroyed||(this._channelReady=!0,this._maybeReady())}_onChannelClose(){this.destroyed||this.destroy()}}X.config={iceServers:[{urls:["stun:stun.l.google.com:19302","stun:global.stun.twilio.com:3478"]}],sdpSemantics:"unified-plan"},X.channelConfig={};const Y=X;class J{constructor(e,t,s,i,r=0,n={}){this.sn=e,this.segId=t,this.data=s,this.fromPeerId=i,this.level=r,this.ext=n}get size(){return this.data.byteLength}get isSequential(){return this.sn>=0}}var Q=s(365),K=s.n(Q);class Z extends(n()){static get defaultPacketSize(){return c}static get VERSION(){return"8"}constructor(e,t,s,i,r,n={}){super(),this.channel=e.fetcher.channelId,this.logger=e.logger,this.config=r,this.isInitiator=i,this.options=n,this.intermediator=n.intermediator||null,this.signalMsgs=[],this.assignPeerId(t,s),this.platform="unknown",this.super=!1,this.mobile=!1,this.mobileWeb=!1,this.mobileNet=!1,this.connected=!1,this.msgQueue=[],this.miss=0,this.notifySet=new Set,this.bufArr=[],this.packetSize=c,this.sendReqQueue=[],this.downloading=!1,this.uploading=!1,this.choked=!1,this.streamListeners=[],this.pieceMsg={},this.datasToSend=[],this.bytesUploaded=0,this.dataWriting=!1,this.timeSendRequest=0,this.timeReceivePiece=0,this.timeSendPiece=0,this.weight=0,this.peersConnected=1,this.uploadSpeed=0,this.currentLevel=0,this.currentPos=0,this.useBackupSignal=!1,this.gotPeersTS=0,this.gotAnswer=!1,this.gotOffer=!1,this.gotSignal=!1,this.sentSignal=!1,this.incomingSignal=[],this.webRTCConfig={};const{stuns:o}=this.options;if(o&&o.length>0){const e=[];o.forEach((t=>{this.logger.info(`use stun ${t}`),e.push({urls:t})})),this.webRTCConfig.iceServers=e}this.config.webRTCConfig&&(this.webRTCConfig={...this.config.webRTCConfig,...this.webRTCConfig}),this.playlistMap=new Map,this._initPeerChannel(),this.notFatalClosed=!1,this.startSN=Number.MAX_SAFE_INTEGER,this.endSN=-1,this._loadedBytes=0}assignPeerId(t,s){this.remotePeerId=s,this.channelId=this.isInitiator?`${t}-${s}`:`${s}-${t}`,s&&this._startTimer(),setTimeout((()=>{this.signalMsgs.length>0&&this.emit(e.DC_SIGNAL_BATCH,this.signalMsgs)}),0)}_startTimer(){this.timeJoin=f(),this.dataExchangeTs=this.timeJoin,this.gotStatsTs=this.timeJoin,this.connTimeout=setTimeout((()=>{const{gotSignal:t,sentSignal:s,signalName:i}=this;this.logger.warn(`dc ${this.channelId} connection timeout, gotSignal ${t} sentSignal ${s} signalName ${i}`),this.emit(e.DC_TIMEOUT,{gotSignal:t,sentSignal:s,data:this.signalMsgs})}),this.isInitiator?15e3:12e3)}get isAvailable(){return this.downloadNum<2&&!this.choked}get isAvailableUrgently(){return!this.downloading&&!this.choked}cancelDownload(t,s,i){return!!this.downloading&&(!(this.bufSN>t)&&(!(this.streamListeners.length>0)&&(this.logger.info(`cancel download ${i} to ${this.remotePeerId} remain packets ${this.remainAttachments}`),this.timeReceivePiece=0,this.sendJson({event:e.DC_PIECE_CANCEL,sn:t,level:s,seg_id:i}))))}addStreamListener(e,t,s){this.streamListeners.push({handler:s,peerId:t})}removeStreamListener(e){this.streamListeners=this.streamListeners.filter((t=>t.peerId!==e||(t.handler(void 0,void 0,!0,"aborted by cancel"),!1)))}_initPeerChannel(){const t=new Y({initiator:this.isInitiator,trickle:this.options.trickle||!1,config:this.webRTCConfig});this._datachannel=t,t.on("error",(t=>{let s=!0;(this.connected||this.notFatalClosed)&&(s=!1);let i=t.message;t.debug&&(i=`${i} raw: ${JSON.stringify(this.incomingSignal)}`),this.emit(e.DC_ERROR,s,i)})),t.on("signal",(t=>{t.candidate&&!t.candidate.candidate||(!this.useBackupSignal&&this.signalMsgs.length<10&&this.signalMsgs.push(t),this.sentSignal=!0,this.emit(e.DC_SIGNAL,t))}));t.on("connect",(()=>{for(this.logger.info(`datachannel CONNECTED from ${this.intermediator?"peer":"server "+this.signalName} to ${this.remotePeerId}`),this.connected=!0,this.incomingSignal=[],clearTimeout(this.connTimeout),this.signalMsgs=[],this.emit(e.DC_OPEN);this.msgQueue.length>0;){let e=this.msgQueue.shift();this.emit(e.event,e)}})),t.on("data",(t=>{const{logger:s}=this;if("string"==typeof t){let i=JSON.parse(t);if(!i)return void s.error("dc received string is null");if(!this.connected)return void this.msgQueue.push(i);let r,n=i.event;switch(r=n!==e.DC_PLAYLIST&&n!==e.DC_PEER_SIGNAL?`string: ${t}`:`event: ${n}`,s.debug(`datachannel receive ${r} from ${this.remotePeerId}`),n){case e.DC_HAVE:if(this.emit(i.event,i),!i.sn)return;this.config.live||(i.snthis.endSN&&(this.endSN=i.sn));break;case e.DC_PIECE:this.downloading=!0,this.dataExchangeTs=f(),this.timeReceivePiece=performance.now(),this.pieceMsg=i,this._prepareForBinary(i.attachments,i.seg_id,i.sn,i.size),this.emit(i.event,i);break;case e.DC_PIECE_CANCEL:s.info(`send queue ${this.datasToSend.length}, uploading ${this.uploading}`),this.emit(i.event,i),this.sendMsgPieceAbort("transfer canceled",i.seg_id);break;case e.DC_PIECE_NOT_FOUND:this._sendNextReq()||(this.downloading=!1),this.emit(i.event,i);break;case e.DC_REQUEST:this._handleRequestMsg(i);break;case e.DC_PIECE_ACK:this._handlePieceAck(i.seg_id,i.size,i.miss);break;case e.DC_STATS:this._handleStats(i);break;case e.DC_PLAYLIST:this.config.sharePlaylist&&this._handlePlaylist(i);break;case e.DC_METADATA:this._handleMetadata(i);break;case e.DC_PIECE_ABORT:this.downloading&&(this._notifyDownloadListenersAbort("aborted by upstream peer"),this.emit(e.DC_PIECE_ABORT,i)),this.downloading=!1,this.segId=void 0;break;case e.DC_CHOKE:s.info(`choke peer ${this.remotePeerId}`),this.choked=!0;break;case e.DC_UNCHOKE:s.info(`unchoke peer ${this.remotePeerId}`),this.choked=!1;break;case e.DC_CLOSE:this.emit(i.event,i.fatal||!1);break;default:this.emit(i.event,i)}}else{if(!t)return void s.error("datachannel on data is undefined!");if(!this.downloading){const i=`peer ${this.remotePeerId} not downloading, data size ${t.byteLength} pieceMsg ${JSON.stringify(this.pieceMsg)}`;return s.warn(i),void this.emit(e.DC_ERROR,!1,i)}this._handleBinaryMsg(t)}})),t.once("close",(()=>{this.emit(e.DC_CLOSE,!1)})),t.on("iceStateChange",((t,s)=>{this.connected&&"disconnected"===t&&(this.logger.warn(`${this.remotePeerId} disconnected`),this.emit(e.DC_DISCONNECT))}))}sendJson(t){if(!this.remotePeerId)return!1;t.event!==e.DC_PLAYLIST&&t.event!==e.DC_PEER_SIGNAL?this.logger.debug(`dc bufferSize ${this._datachannel.bufferSize} send ${JSON.stringify(t)} to ${this.remotePeerId}`):this.logger.debug(`dc send event ${t.event} to ${this.remotePeerId}`);const s=JSON.stringify(t);return s.length>c?(this.logger.error("string to send is too large"),!1):this.send(s,!1)}send(e,t=!0){return t?(this.datasToSend.push(e),this.dataWriting||this._sendDataSync(),!0):this.sendImmediately(e)}_sendDataSync(){if(!this._datachannel.connected||0===this.datasToSend.length)return void(this.dataWriting=!1);this.dataWriting=!0;const t=this.datasToSend.shift();t?("string"!=typeof t&&(this.bytesUploaded+=t.byteLength),this._datachannel.write(t,(t=>{if(t)return this.dataWriting=!1,void this.emit(e.DC_ERROR,!1,t.message);this._sendDataSync()}))):this.logger.error("sendDataSync data is undefined!")}sendImmediately(t){if(this._datachannel.connected)try{return this._datachannel.send(t),!0}catch(t){const s=`datachannel ${this.channelId} send data failed, close it`;this.emit(e.DC_ERROR,!1,s)}return!1}sendMsgHave(t,s,i={}){const r=i.reverse||void 0;delete i.reverse,this.sendJson({event:r?e.DC_HAVE_REVERSE:e.DC_HAVE,sn:t,seg_id:s,...i})}sendPieceNotFound(t,s,i={}){this.uploading=!1,this.sendJson({event:e.DC_PIECE_NOT_FOUND,seg_id:s||void 0,sn:t,...i})}sendPeers(t){this.sendJson({event:e.DC_PEERS,peers:t})}sendPeersRequest(){this.sendJson({event:e.DC_GET_PEERS})}sendMsgStats(t,s={}){const i={event:e.DC_STATS,total_conns:t,...s};this.sendJson(i)}sendMsgPlaylist(t,s,i){const r=this.playlistMap.get(t);if(r&&r.seq>=i)return;const n={event:e.DC_PLAYLIST,url:t,data:s,seq:i};this.playlistMap.set(t,{data:s,seq:i}),this.sendJson(n)}sendMsgSignal(t,s,i){return this.sendJson({event:e.DC_PEER_SIGNAL,action:"signal",to_peer_id:t,from_peer_id:s,data:i})}sendMsgSignalReject(t,s,i,r=!1){return this.sendJson({event:e.DC_PEER_SIGNAL,action:"reject",to_peer_id:t,from_peer_id:s,reason:i,fatal:r})}sendMetaData(t,s,i,r,n=!1){this.isInitiator&&(this.timeSendRequest=performance.now()),this.sendJson({event:e.DC_METADATA,field:t,platform:e.DC_PLAT_WEB,mobile:!!K().isMobile(),mobile_net:n,channel:this.channel,version:"2.15.5",sequential:s,peers:i,region:r})}sendPartialBuffer(e,t,s={}){if(!this.sendMsgPiece(e,s))return!1;for(let e=0;e=this.minRequiredSpeed(e))}close(t){t||(this.notFatalClosed=!0),this.emit(e.DC_CLOSE,t)}receiveSignal(e,t){if("answer"===e.type){if(this.gotAnswer||this.gotOffer)return;this.gotAnswer=!0}else if("offer"===e.type){if(this.gotOffer||this.gotAnswer)return;this.gotOffer=!0}this.gotSignal=!0,t&&this.incomingSignal.push(t),e&&this._datachannel.signal(e)}_notifyDownloadListenersAbort(e){for(let t of this.streamListeners){const{handler:s}=t;s(void 0,void 0,!0,e)}this.streamListeners=[]}destroy(t=!0){this.logger.info(`destroy datachannel ${this.channelId}`),clearTimeout(this.chokeTimer),clearTimeout(this.connTimeout),this._notifyDownloadListenersAbort("upstream peer is closed");let s={event:e.DC_CLOSE,fatal:t};this.sendJson(s),this._datachannel.removeAllListeners(),this.removeAllListeners(),this._datachannel.destroy()}_handleBinaryMsg(t){const{attachments:s,reverse:i}=this.pieceMsg;this.listenerCount(e.DC_RESPONSE)>0&&this.bufArr.push(t),this._loadedBytes+=t.byteLength,this.remainAttachments--;let r=i?this.remainAttachments+1:s-this.remainAttachments;const n=0===this.remainAttachments;if(this.emit(e.DC_PIECE_DATA,this.bufSN,this.segId,t,r,n,this.pieceMsg),this.streamListeners.length>0)for(let e of this.streamListeners){const{handler:s}=e;s(this.bufSN,this.segId,!1,t,n)}if(n){if(this.streamListeners=[],this.timeSendRequest>0)if(this.super)this.weight=1;else{const e=this.expectedSize/(performance.now()-this.timeSendRequest);this.weight=this.weight>0?.6*this.weight+.4*e:e}this.sendJson({event:e.DC_PIECE_ACK,seg_id:this.segId,size:this.expectedSize,miss:this.miss||void 0}),this.timeSendRequest=0,this.timeReceivePiece=0,this._sendNextReq()||(this.downloading=!1),this._handleBinaryData(i)}}_sendNextReq(){if(this.sendReqQueue.length>0){const e=this.sendReqQueue.shift();return this.logger.info(`get msg from sendReqQueue ${JSON.stringify(e)}`),this._realRequestData(e),!0}return!1}_handlePlaylist(e){const{url:t,data:s,seq:i}=e;this.playlistMap.set(t,{data:s,seq:i})}getLatestPlaylist(e,t){if(!this.playlistMap.has(e))return null;const s=this.playlistMap.get(e);return s.seq<=t||s.seq>t+2?null:s}_handleMetadata(t){const{logger:s}=this;if(this.isInitiator){const e=performance.now()-this.timeSendRequest;e>0&&(this.weight=1e5/e,s.info(`handle Metadata from ${this.remotePeerId} initial weight ${this.weight}`)),this.timeSendRequest=0}const i=t.channel;if(this.channel!==i){const t=`peer channel ${i} not matched!`;return s.error(t),void this.emit(e.DC_ERROR,!0,t)}if(t.super){s.info(`got super peer ${this.remotePeerId}`),this.super=!0;const{token:i}=this.config;if(i&&t.token!==i)return void this.emit(e.DC_ERROR,!0,`super peer token ${t.token} not matched!`)}t.region&&(this.region=t.region);switch(t.platform){case e.DC_PLAT_ANDROID:this.platform=e.DC_PLAT_ANDROID;break;case e.DC_PLAT_IOS:this.platform=e.DC_PLAT_IOS;break;case e.DC_PLAT_WEB:this.platform=e.DC_PLAT_WEB}if(this.mobile=t.mobile||!1,this.mobileNet=t.mobile_net||!1,this.mobileWeb=this.mobile&&this.platform===e.DC_PLAT_WEB||!1,this.sequential=t.sequential,s.info(`${this.remotePeerId} platform ${this.platform} sequential ${this.sequential}`),t.peers&&(this.peersConnected+=t.peers,s.info(`${this.remotePeerId} now has ${this.peersConnected} peers`)),this.emit(e.DC_METADATA,t),t.field&&!this.config.live&&t.sequential){const{field:e}=t;if(Array.isArray(e))this._handleField(e);else for(let t in e)this._handleField(e[t])}}_handleField(e){e.forEach((e=>{e>=0&&(ethis.endSN&&(this.endSN=e))}))}_handleStats(e){this.gotStatsTs=f();const t=e.total_conns;t>0&&this.peersConnected!==t&&(this.peersConnected=t,this.logger.info(`${this.remotePeerId} now has ${this.peersConnected} peers`)),e.level&&(this.currentLevel=e.level),e.pos&&(this.currentPos=e.pos)}_handleRequestMsg(t){if(this.dataExchangeTs=f(),this.uploading)return this.logger.warn(`${this.remotePeerId} is uploading when receive request`),void this.sendPieceNotFound(t.sn,t.seg_id,{level:t.level});this.uploading=!0,this.emit(e.DC_REQUEST,t)}_handlePieceAck(t,s,i){0!==this.timeSendPiece&&(this.uploadSpeed=Math.round(s/(performance.now()-this.timeSendPiece)*2),this.timeSendPiece=0,this.logger.info(`${this.remotePeerId} uploadSpeed is ${this.uploadSpeed}`)),i>0&&this.logger.warn(`peer ${this.remotePeerId} miss ${i}`),this.bytesUploaded>0&&this.emit(e.DC_PIECE_ACK,{seg_id:t,size:s})}_prepareForBinary(e,t,s,i){this.bufArr=[],this._loadedBytes=0,this.remainAttachments=e,this.segId=t,this.bufSN=s,this.expectedSize=i}_handleBinaryData(t=!1){if(this.listenerCount(e.DC_RESPONSE)>0){t&&this.bufArr.reverse();let s=o.h.concat(this.bufArr);const i=s.byteLength;if(i===this.expectedSize){let t=s.buffer;const i=new J(this.bufSN,this.segId,t,this.remotePeerId,this.pieceMsg.level);this.emit(e.DC_RESPONSE,i,this.weight)}else this.logger.error(`${this.segId} expectedSize ${this.expectedSize} != byteLength ${i}`)}this.bufArr=[]}checkIfNeedChoke(e=!1){const{logger:t}=this,s=performance.now()-this.timeSendRequest;if((e||!(s<1e3))&&(this.miss++,t.info(`${this.remotePeerId} miss ${this.miss}`),this.miss>=3&&!this.choked)){this.choked=!0;const e=30*this.miss;e<=150?(t.warn(`datachannel ${this.channelId} is choked`),this.chokeTimer=setTimeout((()=>{this.choked=!1,t.warn(`datachannel ${this.channelId} is unchoked`)}),1e3*e)):t.warn(`datachannel ${this.channelId} is choked permanently`)}}get bufArrSize(){return this.downloading?this.pieceMsg.attachments-this.remainAttachments:0}loadtimeout(){const{logger:e,pieceMsg:t}=this;return e.warn(`timeout while downloading from ${this.remotePeerId}, ${this.bufArrSize} of ${t.attachments} packets loaded`),this.checkIfNeedChoke(),!0}sendMsgPieceAbort(t,s,i=!1){const r=this.datasToSend.length;if(!i&&!this.uploading&&0===r)return;this.uploading=!1,this.datasToSend=[],this._handlePieceAck(s,this.bytesUploaded,0),this.bytesUploaded=0;const n={event:e.DC_PIECE_ABORT,reason:`${t}, remains ${r}`};return this.sendJson(n)}loadedBytes(){return this._loadedBytes}currentLoadSpeed(){return 0===this.timeReceivePiece?0:this.loadedBytes()/(performance.now()-this.timeReceivePiece)}minRequiredSpeed(e){return(this.pieceMsg.size-this.loadedBytes())/e}}const ee=Z,te={DPlayer:"dplayer",CBPlayer:"cbplayer",jwplayer:"jwplayer",videojs:"videojs",Clappr:"clappr",ckplayer:"ckplayer",MediaElementPlayer:"mediaelement",MediaElement:"mediaelement",TcPlayer:"tcplayer",flowplayer:"flowplayer",Chimee:"chimee",ChimeePlayer:"chimee",HlsJsPlayer:"xgplayer",fluidPlayer:"fluidplayer",OpenPlayer:"openplayer",Plyr:"plyr",Playerjs:"playerjs",Aliplayer:"aliplayer",shaka:"shakaplayer",RadiantMP:"rmp",bitmovin:"bitmovin"};const se={[e.EXCEPTION]:"onException",serverConnected:"onServerConnected",peerId:"getPeerId",p2pDownloaded:"onP2pDownloaded",p2pUploaded:"onP2pUploaded",httpDownloaded:"onHttpDownloaded",bufferStalled:"onBufferStalled",peers:"getPeersInfo"};class ie extends(n()){constructor(e={}){if(super(),this.p2pEnabled=!(!1===e.p2pEnabled||"0"===u("_p2p")),e.tag&&e.tag.length>20)throw new Error("Tag is too long");if(e.appName&&e.appName.length>30)throw new Error("appName is too long");if(e.appId&&e.appId.length>30)throw new Error("appId is too long");if(e.token&&e.token.length>20)throw new Error("Token is too long");this.segmentLoadCount=0,this.rangeTested=!1,this.trackerTried=!1,this.playerName=function(){let e;for(let t in te)if(self[t]){e=te[t];break}return e}()}resumeTracker(){this.tracker&&!this.trackerTried&&!this.tracker.connected&&this.config.p2pEnabled&&(this.tracker.resumeP2P(),this.trackerTried=!0)}onTrackerResume(e){e.report_url&&this.logger.enableReport(e.report_url)}startRangeRequestTimer(){const{config:e,logger:t}=this,s=()=>{this.curTsUri&&function(e,t,s,i=2e3,r=!1){const n=new XMLHttpRequest;let o=e;return r&&(o=g(e,l,!0)),t=t||"bytes=0-0",new Promise(((r,a)=>{n.open("GET",o,!0),n.responseType="arraybuffer",n.timeout=i,n.onreadystatechange=e=>{if(4===n.readyState){const e=n.status;206===e||200===e&&t?r(n.response):a(`status ${e} url ${o} range ${t}`)}},n.onerror=e=>{a("request error")},n.ontimeout=e=>{a("timeout")},n.setRequestHeader("Range",t),s&&s(n,e),n.send()}))}(this.curTsUri,void 0,e.xhrSetup).then((()=>{e.httpRangeSupported=!0,clearTimeout(this.rangeRequestTimer)})).catch((i=>{e.httpRangeSupported=!1,t&&t.warn(i),this.rangeRequestTimer=setTimeout(s,6e4)})).finally((()=>{t&&t.info(`http range is${e.httpRangeSupported?"":" not"} supported`)}))};this.rangeRequestTimer=setTimeout(s,0)}initLogger(){const{config:e}=this;e.showSlogan&&"en"==("zh-CN"===(navigator.language||navigator.userLanguage)?"cn":"en")&&console.log(`%cLet the browsers become your unlimitedly scalable CDN!\n%c${self.atob("aHR0cHM6Ly9zd2FybWNsb3VkLm5ldA==")}`,"color: dodgerblue; padding:20px 0; font-size: x-large","font-size: medium; padding-bottom:15px");const t=new U(e.logLevel);return e.logger=this.logger=t,t}getExtraForStats(){return{}}getExtraForPeersRequest(){const e={};return e.num_want=this._getNumWant(),e}_getNumWant(){const{tracker:e}=this;if(!e.scheduler)return;const t=e.scheduler.peersNum;return t>0&&e.maxConnsActive-t>0?e.maxConnsActive-t:void 0}makeChannelId(e,t){if(!e||"string"!=typeof e){const e="token is required while using customized channelId!";throw console.error(e),new Error(e)}return T(t)?(s,i)=>`${e}-${t(s,i)}`:()=>`${e}-${t}`}makeSignalId(){let e="";const{config:t}=this,s=`wss://${self.atob(function(e){let t="c2lnbmFsY2xvdWQuc3dhcm1jbG91ZC5vcmc=";switch(e){case"hk":t="c2lnbmFsLnN3YXJtY2xvdWQub3Jn";break;case"us":t="b3BlbnNpZ25hbC5zd2FybWNsb3VkLm9yZw==";break;case"cn":t="Z3ouc3dhcm1jbG91ZC5uZXQ="}return t}(t.trackerZone))}`;t.signalConfig&&(t.wsSignalerAddr=t.signalConfig);const{wsSignalerAddr:i}=t;if(i){let r;"object"==typeof i?(i.main||(i.main=s),r=i.main):"string"==typeof i&&(r=i,t.wsSignalerAddr={main:r}),r===s&&(r=void 0),r&&!t.wsSignalerAddr.backup&&(e=h().parseURL(r).netLoc.substring(2))}else t.wsSignalerAddr={main:s,byDefault:!0};return e}get commonBrowserInfo(){const e=K().getPlatform(),t=K().getNetType()||"wifi";this.netType=t;const{main:s,backup:i,byDefault:r}=this.config.wsSignalerAddr||{};return{signal:s,custom_signal:!r||void 0,signal2:i,device:e,netType:t,player:this.playerName}}get isMobileNet(){return"wifi"!==this.netType&&"ethernet"!==this.netType}setupWindowListeners(e){const t=["iPad","iPhone"].indexOf(navigator.platform)>=0?"pagehide":"beforeunload",s=()=>{this.fetcher&&this.fetcher.postStatsWithBeacon(),this.p2pEnabled&&this.disableP2P(),self.removeEventListener(t,s)};e?self.removeEventListener(t,s):self.addEventListener(t,s)}destroy(){clearTimeout(this.rangeRequestTimer),this.disableP2P(!0),this.removeAllListeners(),this.setupWindowListeners(!0)}enableP2P(){return this.p2pEnabled?null:(this.logger&&this.logger.info("enable P2P"),this.config.p2pEnabled=this.p2pEnabled=!0,this.browserInfo?(this._init(this.channel,this.browserInfo),this):null)}get version(){return ie.version}static isSupported(){const e=_();return!(!e||void 0===e.RTCPeerConnection.prototype.createDataChannel)}static get TrackerZone(){return{EU:"eu",HK:"hk",USA:"us",CN:"cn"}}determineHttpLoadTime(e,t,s){this.logger&&this.logger.info(`segments in playlist: ${e.length}, targetDuration: ${t} startSN ${s}`);let i=4;return t<=2?i=1.5:t<=3?i=2:t<=4?i=2.5:t<=5?i=3:t<=6&&(i=3.5),i}emitEvent(e,...t){this.emit(e,...t);const s=se[e];s&&T(this.config[s])&&this.config[s](...t)}}ie.version="2.15.5",ie.protocolVersion=ee.VERSION;const re=ie;function ne(){if(!function(){if("object"==typeof self)return self.ManagedMediaSource||self.MediaSource||self.WebKitMediaSource}())return!1;const e=self.SourceBuffer||self.WebKitSourceBuffer;return!e||e.prototype&&"function"==typeof e.prototype.appendBuffer&&"function"==typeof e.prototype.remove}function oe(e,t){let s;if(e&&("string"==typeof e?(s=document.querySelector(e),ae(s)||(s=function(e){const t=document.getElementById(e);if(ae(t))return t;if(!t)return null;const s=t.getElementsByTagName("*");for(let e=0;ee.src===t))),s||(s=e.find((e=>e.currentTime>0))))}return s}function ae(e){if(!e)return null;const t=e.tagName.toLowerCase();return"video"===t||"audio"===t}function he(e,t,s,i=0,r=0){const n=c;let o=i,a=r||s-1;const h=Math.floor(s/n),l=s%n>0?h+1:h;if(e>=0&&(o+=(e+1)*n),t>=0&&t{e.oncomplete=e.onsuccess=()=>t(e.result),e.onabort=e.onerror=()=>s(e.error)})),s=(i=fe,r="indexedDB timeout",new Promise(((e,t)=>setTimeout((()=>{t(r)}),i))));var i,r;return Promise.race([t,s])}const me={};async function _e(e,t,s=!0){const i=me[e]||{};i.promise||(i.promise=new Promise((e=>i.resolve=e)),me[e]=i,ye(e,t,i.resolve,s));const r=await i.promise;return delete i.promise,r}const Se={};async function ye(e,t,s,i){if(!Se[e]){const i=indexedDB.open(e);return i.onupgradeneeded=()=>{const e=i.result;t.forEach((t=>{e.createObjectStore(t)}))},void s(Se[e]=await pe(i))}if(i)try{t.forEach((t=>{Se[e].transaction(t)})),s(Se[e])}catch(r){console.error(`Could not open a transaction on "${e}" due to ${r.name} (${r.message}). Trying to reopen the connection...`),delete Se[e],ye(e,t,s,i)}else s(Se[e])}let ve;function Pe(){return ve||(ve=createStore("keyval-store","keyval")),ve}function Ee(e,t=Pe()){return t("readonly",(t=>pe(t.get(e))))}function be(e,t,s=Pe()){return s("readwrite",(s=>(s.put(t,e),pe(s.transaction))))}function we(e,t=Pe()){return t("readwrite",(t=>(t.delete(e),pe(t.transaction))))}function Ce(e=Pe()){return e("readwrite",(e=>(e.clear(),pe(e.transaction))))}function Te(e,t){return e.openCursor().onsuccess=function(){this.result&&(t(this.result),this.result.continue())},pe(e.transaction)}const Ie="size";class Le extends(n()){constructor(e,t){super(),this.name="SegmentStore",this.logger=t.logger,this.logger.info(`use ${this.name}`),this.engine=e,this.channel=e.channel;const s=e.browserInfo.device;this.isPC=s===K().device.PC_WEB||s===K().device.PC_NATIVE,this.maxBufSize=this.isPC?t.diskCacheLimit.pc:t.diskCacheLimit.mobile,this.overflowed=!1,this.countErrors=0,this.isCleared=!0,this.destroyed=!1}async setupStore(){if(navigator.storage&&navigator.storage.estimate){const e=await navigator.storage.estimate(),t=Math.floor(e.quota-e.usage);t{if(this.isPC&&this.maxBufSize<419430400||!this.isPC&&this.maxBufSize<104857600)return void t("disk storage not enough");const s=this.stores;let i;try{i=function(e,t){let s=_e(e,t);return t.map((i=>(r,n)=>s.then((o=>{try{const e=o.transaction(i,r).objectStore(i);return n(e)}catch(o){s=_e(e,t),s.then((e=>n(e.transaction(i,r).objectStore(i))))}}))))}(this.channel,s)}catch(e){return void t(e)}this._createStores(i),this._initMetaStore().then(e).catch(t)}))}_initMetaStore(){return be(Ie,0,this.metaStore)}currBufSize(){return new Promise((async(t,s)=>{try{const i=await Ee(Ie,this.metaStore);if(isNaN(i))return this.engine.emit(e.BM_FATAL_ERROR),void s("size is NaN");t(i)}catch(e){s(e)}}))}async putSeg(t){if(this.destroyed)return;this.isCleared=!1;const{logger:s}=this;if(E(t.data))return new Promise((i=>{this._addSeg(t).then((t=>{this._onSegPut(t),this.emit(e.BM_SEG_ADDED,t),this.countErrors=0,i()})).catch((e=>{this._handleFataError(),e&&(s.warn(`putSeg ${e}`),("QuotaExceededError"===e.name||e.inner&&"QuotaExceededError"===e.inner.name)&&this.currBufSize().then((e=>{this._trimDisk(e,!0)})).catch((e=>{this.logger.error(`trimDisk ${e}`)}))),i()}))}));s.error(`putSeg ${t.segId} is not buffer`)}_handleFataError(){this.countErrors++,this.countErrors>=3&&(this.engine.emit(e.BM_FATAL_ERROR),this.countErrors=0)}_decreaseBufSize(e){this.currBufSize().then((t=>{t&&be(Ie,t-e,this.metaStore)})).catch((e=>{this.logger.warn(`decreaseBufSize ${e}`)}))}_increaseBufSize(e){this.destroyed||this.currBufSize().then((t=>{be(Ie,t+e,this.metaStore),this._trimDisk(t+e)})).catch((e=>{this.logger.warn(`increaseBufSize ${e}`)}))}clear(e=!1){if(!this.isCleared){this.logger.warn("clear segment store");try{this._clearDisk(e)}catch(e){}this.isCleared=!0}}_clearDisk(e){Ce(this.segmentsStore),e?this._initMetaStore():Ce(this.metaStore),this.overflowed=!1}destroy(){this.clear(),this.removeAllListeners(),this.destroyed=!0}}const Re=Le;const Ae=class extends Re{constructor(e,t){super(e,t),this.loadingSN=-1,this.stores=["segments","id2Sn","metadata"]}_createStores(e){this.segmentsStore=e[0],this.id2SnStore=e[1],this.metaStore=e[2]}async hasSegOfId(e){if(!e)return Promise.resolve(!1);let t;try{t=await Ee(e,this.id2SnStore)}catch(e){return Promise.resolve(!1)}return new Promise((s=>{void 0!==t?Ee(t,this.segmentsStore).then((t=>{t&&t.length>0&&t.some((t=>t.segId===e))?s(!0):s(!1)})).catch((e=>{this.logger.warn(`hasSegOfId ${e}`),s(!1)})):s(!1)}))}async getSegById(e){if(!e)return null;const{logger:t}=this;let s;try{s=await Ee(e,this.id2SnStore)}catch(e){return null}return new Promise((i=>{void 0!==s?Ee(s,this.segmentsStore).then((s=>{if(this.countErrors=0,s&&s.length>0){const r=s.find((t=>t.segId===e));if(!r)return void i(null);if(!E(r.data))return t.error(`getSegById ${r.sn} is not buffer`),void i(null);i(r)}else i(null)})).catch((e=>{t.warn(`getSegById ${e}`),this._handleFataError(),i(null)})):i(null)}))}getSegIdBySN(e){return new Promise((t=>{Ee(e,this.segmentsStore).then((e=>{e&&e.length>0?t(e[0].segId):t(null)})).catch((e=>{this.logger.warn(`getSegIdBySN ${e}`),t(null)}))}))}_addSeg(e){const{segId:t,sn:s,size:i}=e;return be(t,s,this.id2SnStore),new Promise(((r,n)=>{Ee(s,this.segmentsStore).then((async o=>{o?0===o.filter((e=>e.segId===t)).length?(o.push(await this._segmentToCache(e)),be(s,o,this.segmentsStore).then((()=>{this._increaseBufSize(i),r(e)})).catch((e=>{n(e)}))):r(e):be(s,[await this._segmentToCache(e)],this.segmentsStore).then((()=>{this._increaseBufSize(i),r(e)})).catch((e=>{n(e)}))})).catch((e=>{n(e)}))}))}async _trimDisk(t,s=!1){if(this.isCleared||this.destroyed)return;let i=this.maxBufSize;const{logger:r}=this;s&&(i=t-104857600,i<0&&(i=0)),t{if(e.getAllKeys)return pe(e.getAllKeys());const t=[];return Te(e,(e=>t.push(e.key))).then((()=>t))}))}(this.segmentsStore).then((async s=>{const n=s.sort(((e,t)=>e-t));let o=0;do{if(o++>10){r.warn("too much loops in SegmentStore");break}const s=n.shift();if(void 0===s){r.warn("lastSN not found");continue}if(s>=this.loadingSN){r.warn(`trimDisk failed, loadingSN ${this.loadingSN}`);break}const i=n[0],a=await Ee(s,this.segmentsStore);if(!a){r.warn("lastSeg not found");continue}let h=0;a.forEach((e=>{h+=e.data.byteLength})),we(s,this.segmentsStore).then((()=>{this._decreaseBufSize(parseInt(h))})),a.forEach((t=>{we(t.segId,this.id2SnStore),r.info(`pop seg ${t.segId} size ${t.data.byteLength}`),this.emit(e.BM_LOST,{sn:s,segId:t.segId,next:i,level:t.level})})),t-=h,r.info(`pop sn ${s} size ${h} currBufSize ${t}`),this.overflowed||(this.overflowed=!0)}while(t>=i)})))}async _segmentToCache(e){const{ext:t={}}=e;let s=t.hash;s||(s=await D(e.data));const i={data:e.data,level:e.level,segId:e.segId,sn:e.sn,fromPeerId:e.fromPeerId,ext:{}};return s&&(i.ext.hash=s),i}_onSegPut(t){this.emit(`${e.BM_ADDED_SN_}${t.sn}`,t)}_clearDisk(e){try{super._clearDisk(e)}catch(e){}Ce(this.id2SnStore).catch((e=>{}))}};class De extends(n()){constructor(e,t){super(),this.name="SegmentCache",this.logger=t.logger,this.logger.info(`use ${this.name}`);const s=e.browserInfo.device;if(this.maxBufSize=s===K().device.PC_WEB||s===K().device.PC_NATIVE?t.memoryCacheLimit.pc:t.memoryCacheLimit.mobile,this.isLive=t.live,this.isLive)this.maxBufSize=47185920;else{if(0===this.maxBufSize)throw new Error("cannot use SegmentCache");const e=function(){const{memory:e}=performance;return e?e.jsHeapSizeLimit-e.usedJSHeapSize:-1}();e>=0&&e{t.forEach((t=>{e+=t.size}))})),e}async putSeg(e){this.destroyed||(this.isCleared=!1,this._currBufSize>=1.5*this.maxBufSize&&(this._currBufSize=this._calSegPoolSize(),this._currBufSize>=1.5*this.maxBufSize&&(this.clear(),this.overflowed=!1)),E(e.data)?this._addSeg(e):this.logger.error(`putSeg ${e.segId} is not buffer`))}clear(){this.isCleared||(this.logger.warn("clear segment cache"),this._segPool.clear(),this._currBufSize=0,this.isCleared=!0,this.overflowed=!1)}destroy(){this.clear(),this.removeAllListeners(),this.destroyed=!0}}const Me=De;const ke=class extends Me{constructor(e,t){super(e,t),this.id2Sn=new Map,this.loadingSN=-1}hasSegOfId(e){return new Promise(((t,s)=>{const i=this.id2Sn.get(e);this._segPool.has(i)?t(this._segPool.get(i).some((t=>t.segId===e))):t(!1)}))}getSegById(e){const t=this.id2Sn.get(e);return new Promise(((s,i)=>{if(!this._segPool.has(t))return void s(null);const r=this._segPool.get(t).find((t=>t.segId===e));s(r||null)}))}getSegIdBySN(e){return new Promise(((t,s)=>{if(this._segPool.has(e)){t(this._segPool.get(e)[0].segId)}else t(null)}))}async _addSeg(t){const{logger:s}=this,{segId:i,sn:r,size:n,ext:o={}}=t;if(this.id2Sn.set(i,r),o.hash||(o.hash=await D(t.data),t.ext=o),this._segPool.has(r)){this._segPool.get(r).push(t)}else this._segPool.set(r,[t]);this._currBufSize+=parseInt(n);const a=this._segPool.size;if(this.emit(`${e.BM_ADDED_SN_}${t.sn}`,t),this.emit(e.BM_SEG_ADDED,t),this._currBufSizee-t)));let l=0;do{if(l++>10){s.error("too much loops in SegmentCache");break}const t=h.shift();if(void 0===t){s.error("lastSN not found");continue}const i=h[0],r=this._segPool.get(t);if(!r){s.error("lastSeg not found");continue}let n=0;r.forEach((e=>{n+=e.size})),this._currBufSize-=parseInt(n),this._segPool.delete(t),r.forEach((s=>{this.id2Sn.delete(s.segId),this.emit(e.BM_LOST,{sn:t,segId:s.segId,next:i,level:s.level})})),s.info(`pop sn ${t} size ${n} currBufSize ${this._currBufSize}`),this.overflowed||(this.overflowed=!0)}while(this._currBufSize>=this.maxBufSize&&this._segPool.size>5)}clear(){super.clear(),this.id2Sn.clear()}};var Ne=s(832),Oe=s.n(Ne);function $e(e,t){for(const s in t)Object.defineProperty(e,s,{value:t[s],enumerable:!0,configurable:!0});return e}const Be=function(e,t,s){if(!e||"string"==typeof e)throw new TypeError("Please pass an Error to err-code");s||(s={}),"object"==typeof t&&(s=t,t=void 0),null!=t&&(s.code=t);try{return $e(e,s)}catch(t){s.message=e.message,s.stack=e.stack;const i=function(){};return i.prototype=Object.create(Object.getPrototypeOf(e)),$e(new i,s)}};class xe{constructor(){this.p2p=0,this.share=0,this.http=0}recordP2p(e){this.p2p+=e}recordShare(e){this.share+=e}recordHttp(e){this.http+=e}resetTraffic(){this.p2p=0,this.share=0,this.http=0}get healthRatio(){if(0===this.http)return 1e3;let e=Math.round((this.p2p+this.share)/this.http*100);return e<=0&&(e=1),e}}const Fe="SW_GEOIP_KEY",qe=2592e5,We=432e5,ze="TRACKER_EXPT",Ue="IPAPI_ERROR",He="uY2R",je="LmNv",Ge="uYnll",Ve="bQ==",Xe="Z3o",Ye="aGsuc3d",Je="hcm1j",Qe="bG91ZC",Ke="5uZXQ=",Ze=Symbol("httpDownloaded"),et=Symbol("p2pDownloaded"),tt=Symbol("p2pUploaded");class st extends(n()){constructor(e,t,s,i,r){let n;super(),this.config=e.config;let o=this.config.announceLocation;switch(this.config.trackerZone&&(o=this.config.trackerZone),o){case"hk":n=Ye+Je+Qe+Ke;break;case"us":n="dXMuaGR0dmNsb3VkLmNvbQ==";break;case"cn":n=Xe+He+Ge+je+Ve;break;default:n="ZXUuaGR0dmNsb3VkLmNvbQ=="}this.engine=e,this.key=t||void 0,Array.isArray(i)&&(i=i[Math.floor(Math.random()*i.length)]),this.baseUrl=i||`https://${self.atob(n)}/v1`,this.channelId=self.btoa(s),this.timestamp=f(),this.health=new xe;const a=h().parseURL(this.baseUrl).netLoc;this.announce=a.replace(/\/\//,""),function(e,t){function s(e,t,s,i,r){return l(s-219,r)}var i,r,n=e();function o(e,t,s,i,r){return l(r- -994,e)}function a(e,t,s,i,r){return l(i-233,t)}function h(e,t,s,i,r){return l(r-305,s)}for(;;)try{if(156690===-parseInt(a(0,246,0,247))/1*(-parseInt(a(0,243,0,248))/2)+-parseInt(a(0,238,0,245))/3+parseInt(o(-1e3,0,0,0,-989))/4*(-parseInt(s(0,0,225,0,216))/5)+-parseInt((i=-180,r=-173,l(r- -181,i)))/6*(parseInt(h(0,0,324,0,324))/7)+-parseInt(o(-991,0,0,0,-990))/8*(parseInt(h(0,0,313,0,307))/9)+-parseInt(h(0,0,310,0,305))/10+-parseInt(o(-968,0,0,0,-974))/11*(-parseInt(s(0,0,226,0,216))/12))break;n.push(n.shift())}catch(e){n.push(n.shift())}}(d);function l(e,t){var s=d();return(l=function(e,t){return s[e-=0]})(e,t)}const c=function(e,t,s,i,r,n){let o=location.hostname;o===l(-922- -923,-915)&&n&&(o=n+"."+o);return 13,Oe()(o+"2.15.5"+s+i+r,e).substr(0,8)}(this.timestamp,0,this.announce,this.channelId,r.type,this.key);function d(){var e=["13055AgbnUs","2739cfXSxI","CxYEuy093515".split("").reverse().join(""),"localhost","OCXDId9".split("").reverse().join(""),"yek".split("").reverse().join(""),"QyapiZ8635101".split("").reverse().join(""),"scRrUF02".split("").reverse().join(""),"bNcslL58187".split("").reverse().join(""),"QEbZrW65772".split("").reverse().join(""),"12gYmKGR","emantsoh".split("").reverse().join(""),"dIlennahc".split("").reverse().join(""),"pmatsemit".split("").reverse().join(""),"676614MZdLCs","type","hpNRbU1".split("").reverse().join(""),"133332xoUKrS","announce","lmia","substr"];return(d=function(){return e})()}l(895-878,886),this.native=!(!r.bundle||!window.electron&&!navigator.userAgent.toLowerCase().includes("electron")),this.announceInfo={...r,channel:this.channelId,ts:this.timestamp,version:"2.15.5",v:c,announce:this.announce,k:ot(this.key)},this.announceURL=`${this.baseUrl}/channel`,this.reportFails=0,this.statsRequesting=!1,this.forbidden=!1,this.failConns=0,this.totalHTTPDownloaded=0,this.totalP2PDownloaded=0,this.totalP2PUploaded=0,this[Ze]=0,this[et]=0,this[tt]=0,this.speed=0,this.offline=!1,this.errsBufStalled=0,this.mediaRequests=0,this.errsInternalExpt=0}geoipRequest(){const{logger:e}=this.engine;return new Promise(((t,s)=>{if((e=>{const t=localStorage.getItem(e);try{const e=JSON.parse(t);return!(!e.duration||!e.startTime)&&Date.now()-e.startTime{s(e)}))}))}btAnnouncePreflight(){const{logger:e}=this.engine;return this.announceInfo.asn?this.btAnnounce():(e.info("preflight ip-api"),Promise.race([this.geoipRequest(),new Promise(((e,t)=>{setTimeout((()=>{t(Be(new Error("request timeout"),Ue))}),600)}))]).then((e=>(this._parseGeoResponse(e),this.btAnnounce()))).catch((t=>{if(t.code!==ze){const t=q(Fe);return t&&(e.info("use expired ipData"),this._parseGeoResponse(t)),this.btAnnounce()}throw t})))}_parseGeoResponse(e){const{lat:t,lon:s,isp:i,as:r,mobile:n,countryCode:o,continentCode:a}=e;n&&(this.announceInfo.netType="cellular");const h=r.split(" ")[0].substr(2);this.announceInfo={...this.announceInfo,lat:t,lon:s,isp:i,asn:h,country:o}}btAnnounce(){const{logger:e}=this.engine;return new Promise(((t,s)=>{fetch(this.announceURL,{headers:this._requestHeader,method:"POST",body:JSON.stringify(this.announceInfo)}).then((e=>{if(!e.ok){const t=e.status>=500&&e.status<600;throw Be(new Error(`server response code is ${e.status}`),ze,{retry:t})}return e.json()})).then((e=>{if(!this.engine)throw Be(new Error("runtime error"),ze,{retry:!1});const s=e.data;if(s.f&&(this.forbidden=!0),-1===e.ret){const{code:t,msg:s}=e.data;throw Be(new Error(s),ze,{retry:t>=5e3})}if(s.info&&console.info(`${s.info}`),s.warn&&console.warn(`${s.warn}`),s.min_conns||(s.min_conns=8),(!s.rejected||s.rejected&&s.share_only)&&s.id&&s.report_interval&&s.peers){if(this.peerId=this.id=s.id,s.report_interval<20&&(s.report_interval=20),this.btStats(s.report_interval),this.getPeersURL=`${this.baseUrl}/channel/${this.channelId}/node/${this.peerId}/peers`,this.statsURL=`${this.baseUrl}/channel/${this.channelId}/node/${this.peerId}/stats`,!this.announceInfo.asn&&s.asn){const{country:e,asn:t,mobile:i,isp:r,lat:n,lon:o}=s;this.announceInfo={...this.announceInfo,country:e,asn:t},W(Fe,{countryCode:e,as:`AS${t}`,mobile:i,isp:r,lat:n,lon:o,status:"success"},i?We:qe)}t(s)}else this.engine&&(this.engine.p2pEnabled=!1)})).catch((t=>{e.error(`btAnnounce error ${t}`);const i=t.code||ze,r=!t.code||t.retry;s(Be(t,i,{retry:r}))}))}))}btStats(e=10){this.heartbeater=setInterval((()=>{this.postStats()}),1e3*e)}postStatsWithBeacon(){if(this.offline)return;this.offline=!0;let e={off:!0};this.statsRequesting||(e={...e,...this._makeStatsBody()}),this.statsURL&&navigator.sendBeacon&&navigator.sendBeacon(this.statsURL,JSON.stringify(e))}postStats(){const{logger:t}=this.engine;this.statsRequesting=!0,fetch(this.statsURL,{method:"POST",body:JSON.stringify(this._makeStatsBody())}).then((e=>(this.statsRequesting=!1,this.reportFails=0,e.text()))).then((s=>{let i;if(i=s?JSON.parse(s):{ret:0,data:{}},-1===i.ret)clearInterval(this.heartbeater),t.error(`${i.data.msg} code ${i.data.code}`),this.engine.emit(e.RESTART_P2P);else{const{http:e=0,p2p:t=0,share:s=0,failConns:i=0,rebuffers:r=0,requests:n=0,errsInternalExpt:o=0}=this.lastStats||{};this[Ze]>=e&&(this[Ze]-=e),this[et]>=t&&(this[et]-=t),this[tt]>=s&&(this[tt]-=s),this.failConns>=i&&(this.failConns-=i),this.errsBufStalled>=r&&(this.errsBufStalled-=r),this.mediaRequests>=n&&(this.mediaRequests-=n),this.errsInternalExpt>=o&&(this.errsInternalExpt-=o),this.exptMsg&&(this.exptMsg=void 0)}})).catch((e=>{t.error(`btStats error ${e}`),this.statsRequesting=!1,this.reportFails++,this.reportFails>=3&&clearInterval(this.heartbeater)}))}btGetPeers(e,t=!1){const{logger:s}=this.engine,{asn:i,country:r}=this.announceInfo;let n={exclusions:e,asn:i,country:r,ratio:this.health.healthRatio,urgent:t||void 0},o={};return this.engine.getExtraForPeersRequest&&(o=this.engine.getExtraForPeersRequest()),n=Object.assign({},n,o),new Promise(((e,t)=>{this.reportFails>=3?t(new Error("reportFails >= 3")):fetch(this.getPeersURL,{headers:this._requestHeader,method:"POST",body:JSON.stringify(n)}).then((e=>e.json())).then((s=>{-1===s.ret?t(s.data.msg):e(s.data)})).catch((e=>{s.error(`btGetPeers error ${e}`),t(e)})).finally((()=>{this.health.resetTraffic()}))}))}increFailConns(){this.failConns++}increRebuffers(){this.engine.emitEvent("bufferStalled"),this.errsBufStalled++}increMediaRequests(){this.mediaRequests++,this.engine.emit(e.MEDIA_REBUFFER,this.errsBufStalled>=2)}reportFlow(e){const t=Math.round(e/1024);this.engine.emitEvent("httpDownloaded",t),this[Ze]+=t,this.totalHTTPDownloaded+=t,this.health.recordHttp(t),this._emitStats()}reportDCTraffic(e,t){const s=Math.round(e/1024);this[et]+=s,this.totalP2PDownloaded+=s,this.health.recordP2p(s),this.speed=Math.round(t),this.engine.emitEvent("p2pDownloaded",s,this.speed),this._emitStats()}reportUploaded(e=0){const t=Math.round(e/1024);this.engine.emitEvent("p2pUploaded",t),this.totalP2PUploaded+=t,this.health.recordShare(t),this[tt]+=t,this._emitStats()}destroy(){const{logger:e}=this.engine;e.warn("destroy fetcher"),this.removeAllListeners(),clearInterval(this.heartbeater)}_emitStats(){const{totalHTTPDownloaded:e,totalP2PDownloaded:t,totalP2PUploaded:s}=this;this.engine.emit("stats",{totalHTTPDownloaded:e,totalP2PDownloaded:t,totalP2PUploaded:s,p2pDownloadSpeed:this.speed});const{getStats:i}=this.config;T(i)&&i(t,s,e,this.speed)}_makeStatsBody(){const{asn:e,country:t}=this.announceInfo;let s={totalConns:this.engine.tracker.totalConns,failConns:this.failConns,rebuffers:this.errsBufStalled||void 0,requests:this.mediaRequests||void 0,errsInternalExpt:this.errsInternalExpt,http:Math.round(this[Ze])||0,p2p:Math.round(this[et])||0,share:Math.round(this[tt])||0,asn:e,country:t},i={};this.engine.getExtraForStats&&(i=this.engine.getExtraForStats()),s=Object.assign({},s,i),this.lastStats=JSON.parse(JSON.stringify(s)),Object.keys(s).forEach((e=>{0===s[e]&&delete s[e]}));const{logger:r}=this.engine;return r.isDebugLevel&&r.info(`report ${JSON.stringify(s)}`),this.exptMsg&&(s.exptMsg="2.15.5 "+this.exptMsg),s}get _requestHeader(){let e={};return this.native&&(e={...e,"X-SW-Key":ot(this.key),"User-Agent":"electron","X-SW-ID":this.announceInfo.bundle}),e}}const it=st;function rt(e,t){const s=nt();return(rt=function(e,t){return s[e-=0]})(e,t)}function nt(){const e=["CsLPpZ8932212".split("").reverse().join(""),"htgnel".split("").reverse().join(""),"UZpUzY5895021".split("").reverse().join(""),"yJZuxA9452121".split("").reverse().join(""),"tAedoCrahc".split("").reverse().join(""),"btoa","q#{this._longPolling()}))}_hello(e){fetch(this.addr+"&hello",{method:"POST"}).then((e=>{if(!e.ok)throw new Error("hello response was not ok");return e.json()})).then((t=>{this.connected=!0,e(),this.onopen&&this.onopen(t.ver)})).catch((e=>{this.closed=!0,this.onerror&&this.onerror(e)}))}send(e){this.msgQueue.push(e),this.posting||this._realSend([...this.msgQueue])}_realSend(e){0!==e.length&&(this.posting=!0,this.msgQueue=[],fetch(this.addr,{method:"POST",body:JSON.stringify(e)}).then((()=>{this.posting=!1,this.msgQueue.length>0&&this._realSend([...this.msgQueue])})).catch((e=>{this.logger.error(e),this.posting=!1})))}close(){this.connected&&(this.closed=!0,this.connected=!1,this.abortController&&(this.abortController.abort(),this.abortController=null),this.onclose&&this.onclose())}destroy(){this.close(),this.removeAllListeners()}_longPolling(){if(this.closed)return;this.pollingTs=f(),this.abortController=new AbortController;const e=this.abortController.signal;fetch(this.addr,{signal:e}).then((e=>{if(!e.ok)throw new Error("polling response was not ok");return e.text()})).then((async e=>{e&&this.onmessage&&this.onmessage(JSON.parse(e)),this.retryCount=0;const t=f()-this.pollingTs;JSON.stringify(e)===JSON.stringify(this.lastData)&&t<10&&(this.logger.warn(`wait ${10-t}s for next polling`),await m(1e3*(10-t))),this.lastData=e,this._longPolling()})).catch((e=>{this.connected&&(this.retryCount<=3?(this.retryCount++,this._longPolling()):(this.connected=!1,this.onerror&&this.onerror(e)))}))}}const ht=class{constructor(e,t,s,i="main"){this.logger=e,this.config=t,this.wsAddr=s,this.serverVersion=0,this.pingInterval=95e3,this.name=i,this.normalClosed=!1,this.lastSendTs=performance.now(),this.pollingClient=new at(e,s);try{this._ws=this._init()}catch(t){e.error(t),this._startPolling()}}get batchSupported(){return this.serverVersion>=50}_init(){const e={maxRetries:this.config.wsMaxRetries,minReconnectionDelay:p(15e3,6e4),maxReconnectionDelay:6e5,maxEnqueuedMessages:20,connectionTimeout:7e3};let t=new B(this.wsAddr,void 0,e);return t.addEventListener("open",(()=>{this.logger.info(`signal ${this.name} ${this.wsAddr} connection opened`),this.normalClosed=!1,this.pollingClient.connected?this.pollingClient.close():this.onopen&&this.onopen(),this._startPing(this.pingInterval)})),t.push=t.send,t.send=e=>{this.lastSendTs=performance.now();let s=JSON.stringify(e);t.push(s)},t.addEventListener("message",(e=>{let t=e.data;const s=JSON.parse(t),i=s.action;if("pong"!==i){if("ver"!==i)return"close"===i?(this.logger.warn(`server close signal ${this.name} reason ${s.reason}`),void this.close()):void(this.onmessage&&this.onmessage(s,this.name));this.serverVersion=s.ver}else clearTimeout(this.pongTimer)})),t.addEventListener("close",(e=>{this.logger.warn(`signal ${this.name} ${this.wsAddr} closed ${e.code} ${e.reason}`),e.code>=5e3||e.code<4e3?(this.onclose&&this.onclose(),this._stopPing()):this.close()})),t.addEventListener("error",(e=>{this._stopPing(),this.onerror&&this.onerror(e),this._startPolling()})),t}forcePolling(){this.pollingClient.connected||(this.close(),this.pollingClient=new at(this.logger,this.wsAddr),this._startPolling())}_startPolling(){this.pollingClient.connected||(this.logger.info(`${this.name} start polling`),this.pollingClient.start(),this._setupPolling(this.pollingClient))}sendDebug(e,t,s){this._send({action:"debug",details:t,ping:s||void 0,to:e})}sendSignal(e,t){const s={action:"signal",to:e,data:t};this._send(s)}sendSignalBatch(e,t){if(this.batchSupported&&t.length>1)this._send({action:"signals",to:e,data:t});else for(let s of t)this.sendSignal(e,s)}sendReject(e,t,s){if(this.rejectIdCache===e)return;this.rejectIdCache=e;const i={action:"reject",to:e,reason:t,fatal:s};this._send(i)}_send(e){this.pollingClient.connected?this.pollingClient.send(e):this._ws&&this._ws.send(e)}_startPing(e){this.connected&&(this.pingTimer=setTimeout((()=>{const e=95e3-(performance.now()-this.lastSendTs);if(e>=0)return this._startPing(e);const t={action:"ping"};this._ws&&this._ws.push(JSON.stringify(t)),this.pongTimer=setTimeout((()=>{this.logger.warn(`signal ${this.name} wait for pong timeout, reconnect`),this.close(),this.reconnect()}),15e3),this._startPing(this.pingInterval)}),e))}_stopPing(){clearTimeout(this.pingTimer),clearTimeout(this.pongTimer)}close(){this.logger.info(`close signal ${this.name}`),this._stopPing(),(()=>{this._ws&&this._ws.close(1e3)})(),this.pollingClient.close(),this.normalClosed=!0}reconnect(){this._ws&&(this.logger.info(`reconnect signal ${this.name}`),this._ws.reconnect())}destroy(){this.close(),this._ws=null,this.pollingClient.destroy()}get connected(){return!!this.pollingClient.connected||this._connected}get _connected(){return!!this._ws&&this._ws.readyState===B.OPEN}_setupPolling(e){e.onopen=e=>{e&&(this.serverVersion=e),this.logger.info(`${this.name} polling opened`),this.onopen&&this.onopen()},e.onerror=e=>{this._connected||this.onerror&&this.onerror(e)},e.onclose=()=>{this._connected||this.onclose&&this.onclose()},e.onmessage=e=>{if(this.onmessage)for(let t of e)this.onmessage(t,this.name)}}},lt=class{constructor(e,t,s,i){this.logger=e,this.config=t,this.mainAddr=s,this.backupAddr=i,this.mainWS=this._init(s),this.backupTimer=setTimeout((()=>{this.destroyed||(this.backupWS=this._init(i,"backup"))}),900),this._connected=!1,this.destroyed=!1,this.normalClosed=!1}_init(e,t){if(!e)return null;let s=new ht(this.logger,this.config,e,t);return s.onopen=()=>{this.normalClosed=!1,!this._connected&&this.onopen&&(this._connected=!0,this.onopen())},s.onmessage=e=>{this.onmessage&&this.onmessage(e,s.name)},s.onclose=()=>{this._connected&&!this.connected&&this.onclose&&(this._connected=!1,this.onclose())},s.onerror=e=>{this.onerror&&this.onerror(e)},s}sendSignalBatch(e,t,s){if(s){const i=this._getWSByName(s);i&&i.sendSignalBatch(e,t)}else this.mainConnected?this.mainWS.sendSignalBatch(e,t):this.backupConnected&&this.backupWS.sendSignalBatch(e,t)}sendSignal(e,t,s){this.sendSignalBatch(e,[t],s)}sendReject(e,t,s,i){if(i){const r=this._getWSByName(i);if(r)return void r.sendReject(e,t,s)}this.mainConnected?this.mainWS.sendReject(e,t,s):this.backupConnected?this.backupWS.sendReject(e,t,s):this.logger.warn("no signal available, send reject failed")}sendDebug(e,t,s){this.mainConnected&&this.mainWS.sendDebug(e,t,s)}close(){this.mainWS&&this.mainWS.close(),this.backupWS&&this.backupWS.close(),this.normalClosed=!0}_getWSByName(e){return this.mainWS&&this.mainWS.name===e?this.mainWS:this.backupWS&&this.backupWS.name===e?this.backupWS:null}reconnect(e){this.mainWS&&"backup"!==e&&this.mainWS.reconnect(),this.backupWS&&"main"!==e&&this.backupWS.reconnect()}forcePolling(e){this.mainWS&&"backup"!==e&&this.mainWS.forcePolling(),this.backupWS&&"main"!==e&&this.backupWS.forcePolling()}destroy(){this.close(),clearTimeout(this.backupTimer),this.mainWS=null,this.backupWS=null,this.destroyed=!0}get connected(){return this.mainConnected||this.backupConnected}get mainConnected(){return this.mainWS&&this.mainWS.connected}get backupConnected(){return this.backupWS&&this.backupWS.connected}};const ct=function(e,t,s=40){var i=null,r=!1,n=s;return function(s=!1){if(s)return clearTimeout(i),void(r=!1);r||(r=!0,i=setTimeout((function(){e.call(t,n),r=!1,i=null}),1e3*n),n*=1.1)}};class dt{constructor(e,t,s=10){this.engine=e,this.config=t,this.trickle=t.trickleICE,this.poolSize=s,this.pool=[],t.ICEPreflight&&this.reset(),this.trickle=!1}reset(){this.destroy();for(let e=0;e0}getPeer(){if(0===this.pool.length)return this._createPeer();const e=this.pool.shift();return this.pool.length<5&&this.pool.push(this._createPeer()),e}destroy(){for(let e of this.pool)e.destroy(!0);this.pool=[]}}const ut=class{static CHARSET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static BITS_PER_BYTE=8;static BITS_PER_BASE64_CHAR=6;static decode(e){let t=0,s=0,i="";for(const r of e){if("="===r)break;const e=this.CHARSET.indexOf(r);for(t=t<=this.BITS_PER_BYTE;){s-=this.BITS_PER_BYTE;i+=(t>>s&(1<(e.startsWith("C")&&(e="candidate:"+e.slice(1)),e.split(" ").map((e=>(e in Pt&&(e=Pt[e]),e))).join(" "));function Tt(e,t){let s=e.split("~"),i=[];s=s.map((e=>{let t=e.slice(0,1),s=e.slice(1);if(t in St&&(t=St[t]),"a="===t){let e=s.slice(0,1);const t=s.slice(1);e in yt&&(e=yt[e],s=e+t)}return t+s})),i.push("v=0"),i.push("s=-"),i.push("t=0 0"),i.push("a=msid-semantic: WMS");let r=0;s.forEach((e=>{if(e.startsWith("o=")){let t=e.slice(2).split(" "),s=[];s.push("-");const r=t.shift();if(r&&s.push(r),0===t.length)s.push("2 IN IP4 127.0.0.1");else{const e=t.shift();if(e&&s.push(e),0===t.length)s.push("IN IP4 127.0.0.1");else{s.push("IN");const e=t.shift();e&&s.push(e);const i=t.shift();i&&s.push(i)}}i.splice(1,0,`o=${s.join(" ")}`)}else{if(e.startsWith("m="))return e=function(e){return e.replace(It,(e=>Et[e]))}(e),i.push(e),i.push("a=setup:"+(t?"actpass":"active")),i.push(`a=mid:${r}`),void r++;if(e.startsWith("a=candidate:"))return e=Ct(e),void i.push(e);if(e.startsWith("a=fingerprint:")){let[t,s]=e.slice(14).split(" ");return t in vt&&(t=vt[t]),s=ut.decode(s),void i.push(`a=fingerprint:${t} ${s}`)}if(e.startsWith("c=")){let[t,s]=e.slice(2).split(" ");return t in bt&&(t=bt[t]),s in wt&&(s=wt[s]),void i.push(`c=IN ${t} ${s}`)}"I"!==e?"Z"!==e?"B"!==e?i.push(e):i.push("a=sendrecv"):i.push("a=ice-options:ice2,trickle"):i.push("a=ice-options:trickle")}}));const n=i.length-1;return i.splice(n,0,`a=group:BUNDLE ${Array.from(Array(r).keys()).join(" ")}`),i.join("\r\n")}const It=new RegExp(Object.keys(Et).join("|"),"g");class Lt extends(n()){constructor(e,t,s,i){super(),this.engine=e,this.logger=e.logger,this.config=i,this.connected=!1,this.scheduler=s,this.sequential=this.scheduler.sequential,this.DCMap=new Map,this.failedDCMap=new Map,this.notFoundDCSet=new Set;const r=K().isMobile();this.peerPool=new dt(e,i,15),this.signalerWs=null,this.fetcher=t,this.peers=[],this.requestPeersQueue=[],this.minConns=5,this.stuns=[],this.requestMorePeers=ct(this._requestMorePeers,this,p(35,45)),this.maxConns=r?15:22,this.maxConnsActive=r?10:13,this.peersIncrement=0,this.gotPeersFromTracker=!1,this.requestPeersWaitCount=0,this.gotSignalFails={main:0,backup:0,limit:5},this.fuseRate=-1,this.overloaded=!1}get totalConns(){return this.scheduler.peersNum+1}resumeP2P(){if(!this.fetcher)return;const{engine:t,config:s,fetcher:i}=this,{btAnnounce:r,btAnnouncePreflight:n}=i,{wsSignalerAddr:o,wifiOnly:a,geoIpPreflight:h}=s;(h?n:r).call(i).then((e=>{const{scheduler:s}=this;if(!s)return;t.peerId=this.peerId=e.id,this.minConns=e.min_conns,s.minConns=this.minConns;const r=e.peers;s.notifyPeersLoaded(r.length),r.length>this.gotSignalFails.limit&&(this.gotSignalFails.limit=r.length),t.netType=i.announceInfo.netType,(e.wifi_only||a)&&t.isMobileNet&&(s.downloadOnly=!0,this.logger.info("downloadOnly mode"));const n=o.main;let h=o.backup;e.signal&&!e.signal2&&(h=void 0),this.signalerWs=this._initSignalerWs(e.signal||n,e.signal2||h,e.token,e.token2),0===r.length?this.requestMorePeers():this.peers=this._filterPeers(r),t.emitEvent("peerId",this.peerId),e.stun&&e.stun.length>0&&(this.stuns=e.stun),e.debug&&(this.logger.enableDebug(),e.log_url&&(this.logUploader=new F(e.log_url,this.fetcher.key||location.hostname,this.peerId,"2.15.5"),this.logger.setUploader(this.logUploader))),t.onTrackerResume&&t.onTrackerResume(e),e.fuse_rate&&(this.fuseRate=e.fuse_rate),e.overload&&(this.overloaded=!0,this.logger.warn("server overloaded, degrade signaling")),this.logger.info(`announce request response ${JSON.stringify(e,null,2)}`),/^.\d{2}/.test(this.peerId)||(this.maxConnsActive=1,this.maxConns=2)})).catch((s=>{if(this.scheduler&&("TRACKER_EXPT"===s.code&&t.emitEvent(e.EXCEPTION,s),this.scheduler.notifyPeersLoaded(0),s.retry)){const e=p(15e3,4e4);this.logger.warn(`announce retry after ${e}ms`),this.announceTimer=setTimeout((()=>{this.resumeP2P()}),e)}}))}stopP2P(){this.fetcher.postStatsWithBeacon(),this.fetcher.destroy(),this.fetcher=null,this.requestMorePeers(!0),this.scheduler.destroy(),this.scheduler=null,this.signalerWs&&(this.signalerWs.destroy(),this.signalerWs=null),this.peers=[];for(let e of this.DCMap.values())e.destroy(!0);this.DCMap.clear(),this.peerPool.destroy(),this.peerPool=null,this.failedDCMap.clear(),this.notFoundDCSet.clear(),this.logUploader&&(this.logUploader.destroy(),this.logUploader=null),this.logger.warn("tracker stop p2p")}destroy(){this.stopP2P(),this.removeAllListeners(),clearTimeout(this.announceTimer),clearTimeout(this.requestPeersTimer);const{config:e}=this;e.getStats=e.getPeerId=e.getPeersInfo=null,this.logger.warn("destroy tracker")}isPeerConnectedOrFailed(e){return!e||(this.DCMap.has(e)||this.failedDCMap.has(e)||e===this.peerId)}_filterPeers(e){const t=[];return e.filter((e=>!this.isPeerConnectedOrFailed(e.id))).forEach((e=>{t.push({id:e.id,intermediator:e.intermediator})})),t}_tryConnectToAllPeers(){const{logger:e}=this;if(0!==this.peers.length)for(this._checkDCMap(),e.info(`try connect to ${this.peers.length} peers, map size ${this.DCMap.size} limit ${this.maxConnsActive} peersNum ${this.scheduler.peersNum}`);this.peers.length>0&&!(this.DCMap.size>=this.maxConnsActive);){let t=this.peers.shift();if(this.isPeerConnectedOrFailed(t.id))continue;const s=t.intermediator;this.signalerWs.connected||s&&this.DCMap.has(s)?(e.debug(`create DataChannel ${t.id} intermediator ${s}`),this._createDatachannel(t.id,!0,s)):e.info(`skip peer ${t.id} without intermediator`)}else e.info("no peers after filter")}_handleSendSignal(e,t){const s=e.remotePeerId;if(e.intermediator){const i=this.DCMap.get(e.intermediator);if(i){let r=!0;for(let e of t)i.sendMsgSignal(s,this.peerId,e)||(r=!1);if(r)return;this.logger.warn(`intermediator ${e.intermediator} relay failed`)}}e.intermediator=void 0,this.signalerWs.sendSignalBatch(s,t,e.signalName)}_setupDC(t){t.on(e.DC_SIGNAL,(e=>{this._handleSendSignal(t,[e])})).on(e.DC_SIGNAL_BATCH,(e=>{this._handleSendSignal(t,e)})).on(e.DC_PEER_SIGNAL,(e=>{const s=e.to_peer_id||e.to,i=e.from_peer_id||e.from,r=e.action;if(s&&i&&r)if(s!==this.peerId){this.logger.info(`relay signal for ${i}`);const n=this.DCMap.get(s);if(n){if("signal"!==r)return void n.sendMsgSignalReject(s,i,e.reason,e.fatal);if(n.sendMsgSignal(s,i,e.data))return}t.sendMsgSignal(i,s)}else"signal"===r?this._handleSignalMsg(i,e,t.remotePeerId):this._handSignalRejected(i,e)})).on(e.DC_GET_PEERS,(()=>{const e=f(),s=this.scheduler.getPeers().filter((e=>e.peersConnected<(e.mobileWeb?15:22)&&!e.super));if(s&&s.length>0){const i=[];s.forEach((s=>{if(s.remotePeerId===t.remotePeerId||s.remotePeerId===this.peerId)return;if(!this.config.live&&(s.currentPos-t.currentPos>600||s.currentPos50&&i.push({id:s.remotePeerId,...s.region})})),this.logger.info(`send ${i.length} peers to ${t.remotePeerId}`),t.sendPeers(i)}})).on(e.DC_PEERS,(e=>{const s=e.peers;this.logger.info(`receive ${s.length} peers from ${t.remotePeerId}`),s&&s.length>0&&(s.forEach((e=>{e.intermediator=t.remotePeerId,e.region||(e.region={})})),this.requestPeersQueue.push(...s)),this.requestPeersWaitCount--,this.requestPeersWaitCount<=0&&this._handleRequestedPeers()})).once(e.DC_ERROR,((e,s)=>{this.logger.warn(`datachannel ${t.channelId} failed fatal ${e} ${s}`),this.scheduler&&(this.scheduler.deletePeer(t),this._destroyAndDeletePeer(t.remotePeerId,e),this.fetcher&&(t.connected||e&&this.fetcher.increFailConns(),e&&this.failedDCMap.set(t.remotePeerId,`DC_FAILED ${s}`),this._doSignalFusing(this.scheduler.peersNum),this._doPeersRequest()))})).once(e.DC_TIMEOUT,(({gotSignal:e,sentSignal:s,data:i})=>{const{logger:r,signalerWs:n,gotSignalFails:o}=this,{remotePeerId:a,useBackupSignal:h,isInitiator:l}=t,c=h?"backup":"main";if(e?o[c]=0:(o[c]++,o[c]>=o.limit&&(o[c]=0,r.warn("gotSignalFails many, forcePolling"),n.forcePolling(c))),s&&e&&l&&(this.failedDCMap.set(a,"DC_TIMEOUT"),this.fetcher&&this.fetcher.increFailConns()),!e&&l&&!h&&this._tryBackupSignal(t,a,i))return t._startTimer(),void r.warn(`${a} conn timeout, try backup signal`);this._destroyAndDeletePeer(a,!1),this._doPeersRequest()})).once(e.DC_CLOSE,(e=>{this.logger.info(`datachannel ${t.channelId} closed fatal ${e}`),this.scheduler&&(this.scheduler.deletePeer(t),this._doSignalFusing(this.scheduler.peersNum)),this._destroyAndDeletePeer(t.remotePeerId,e),e&&this.failedDCMap.set(t.remotePeerId,"DC_CLOSE"),this._doPeersRequest()})).once(e.DC_OPEN,(()=>{t.isInitiator&&this.scheduler.handshakePeer(t)})).once(e.DC_METADATA,(e=>{const{scheduler:s}=this;t.isInitiator||s.handshakePeer(t),s.handleMetaData(t,e);const i=this.DCMap.size>=this.maxConnsActive;this.requestMorePeers(i),t.intermediator&&this.peersIncrement++,this._doSignalFusing(s.peersNum)}))}_doPeersRequest(){const e=this.scheduler.peersNum;!this.signalerWs.connected||this.overloaded&&e>this.minConns?this._requestPeersFromPeers(e):this.requestMorePeers(),this._tryConnectToAllPeers()}_doSignalFusing(e){if(this.fuseRate<=0)return;const t=this.signalerWs.connected;t&&e>=this.fuseRate?(this.logger.warn("reach fuseRate, report stats close signaler"),this.totalConns-1>0&&this.fetcher.postStats(),this.signalerWs.close()):!t&&e<=this.minConns&&this.signalerWs.normalClosed&&(this.logger.warn(`low conns ${e}, reconnect signaler`),this.signalerWs.reconnect())}_initSignalerWs(t,s,i,r){const n=(e,t)=>{let s=`${e}?id=${this.peerId}&p=web&v=2.15.5`;return this.config.signalCompact&&(s=`${s}&c=1`),t&&(s=`${s}&token=${t}`),s};let o,a=n(t,i);if(s&&s!==t){let e=n(s,r);o=new lt(this.logger,this.config,a,e)}else o=new ht(this.logger,this.config,a);return o.onopen=()=>{this.connected=!0,this.engine.emitEvent("serverConnected",!0),this._tryConnectToAllPeers()},o.onmessage=(e,t)=>{let s=e.action;const i=e.from_peer_id||e.from;if(i)switch(s){case"signal":this._handleSignalMsg(i,e,null,t);break;case"reject":this._handSignalRejected(i,e);break;default:this.logger.warn(`Signal websocket unknown action ${s}`)}else this.logger.warn("fromPeerId is missed")},o.onclose=()=>{this.connected=!1,this.engine.emitEvent("serverConnected",!1)},o.onerror=t=>{t.message&&this.logger.warn(`signal err: ${t.message}`),t.message&&this.engine.emitEvent(e.EXCEPTION,Be(t,"SIGNAL_EXPT"))},o}_handSignalRejected(e,t){const s=`signaling ${e} rejected`;this.logger.warn(`${s}, reason ${t.reason}`);const i=this.DCMap.get(e);i&&!i.connected&&(i.destroy(t.fatal),this.DCMap.delete(e)),this.requestMorePeers(),t.fatal&&this.failedDCMap.set(e,s),this._tryConnectToAllPeers()}_tryBackupSignal(e,t,s,i="main"){return!(!(this.signalerWs.backupConnected&&e&&s.length>0&&"main"===i)||e.useBackupSignal)&&(e.useBackupSignal=!0,e.signalName="backup",e.intermediator=void 0,this.signalerWs.sendSignalBatch(t,s,"backup"),!0)}_handleSignalMsg(e,t,s,i){if(!this.scheduler)return;const{logger:r}=this;if(t.data){if(this.failedDCMap.has(e))return void this._sendSignalReject(e,`${e} ${this.failedDCMap.get(e)||"unknown"}`,s,i,!0);this._handleSignal(e,t.data,s,i)}else{const t=this.DCMap.get(e);if(!t)return;if(this._tryBackupSignal(t,e,t.signalMsgs,i))return void this.logger.warn(`${e} not found from main, try backup signal`);if(t.useBackupSignal)return;this._destroyAndDeletePeer(e),r.info(`signaling ${e} not found`);const{scheduler:n}=this;n.waitForPeer&&(n.waitingPeers--,0===n.waitingPeers&&n.notifyPeersLoaded(0)),this.requestMorePeers(),this._tryConnectToAllPeers(),s||this.notFoundDCSet.add(e)}}_handleSignal(e,t,s,i){let r=t;"string"==typeof r?r=(e=>{if("C"===e[0])return{type:"candidate",candidate:{candidate:Ct(e),sdpMLineIndex:0,sdpMid:"0"}};const t=e.slice(1),s="O"===e[0];return{type:s?"offer":"answer",sdp:Tt(t,s)}})(r):t=void 0;const n=r.type,{logger:o}=this;let a=this.DCMap.get(e);if(a){if(a.connected)return void o.info("datachannel had connected, signal ignored");if("offer"===n&&a.isInitiator){if(!(this.peerId>e))return void o.warn(`${e} signal type wrong ${n}, ignored`);o.warn(`${e} signal type wrong ${n}, convert to non initiator`),this._destroyAndDeletePeer(e,!1),a=this._createDatachannel(e,!1,s)}}else{if("answer"===n){const t=`${e} type wrong ${n}`;return o.warn(t),this._sendSignalReject(e,t,s,i),void this._destroyAndDeletePeer(e,!1)}if(o.debug(`receive node ${e} connection request`),this.DCMap.size>=this.maxConns){const t=`reach limit ${this.maxConns}`;return o.warn(t),void this._sendSignalReject(e,t,s,i)}a=this._createDatachannel(e,!1,s)}a&&(i&&(a.signalName=i),a.receiveSignal(r,t))}_createDatachannel(e,t,s){if(!this.fetcher)return;let i;if(t&&this.peerPool.available)i=this.peerPool.getPeer(),this.logger.info(`get peer from pool, signal size ${i.signalMsgs.length}`),i.intermediator=s,i.assignPeerId(this.peerId,e);else{let r=this.config.trickleICE;this.overloaded&&(r=!1),i=new ee(this.engine,this.peerId,e,t,this.config,{stuns:this.stuns,intermediator:s,trickle:!s&&r})}return this.DCMap.set(e,i),this._setupDC(i),i}_sendSignalReject(e,t,s,i,r){if(s){const i=this.DCMap.get(s);if(i&&i.sendMsgSignalReject(e,this.peerId,t,r))return}this.signalerWs.sendReject(e,t,r,i)}_requestMorePeers(e){if(!this.fetcher)return;const{logger:t}=this,s=this.scheduler.peersNum;s>=this.maxConnsActive||(t.info(`requestMorePeers after delay ${e}, peersIncrement ${this.peersIncrement}`),s<3||s50&&(this.failedDCMap=new Map([...this.failedDCMap].slice(-50))),this.notFoundDCSet.size>20&&(this.notFoundDCSet=new Set([...this.notFoundDCSet].slice(-20))),this.fetcher.btGetPeers([...this.DCMap.keys(),...this.failedDCMap.keys(),...this.notFoundDCSet.keys()],0===e).then((e=>{e&&e.peers&&(t.info(`requestMorePeers resp ${JSON.stringify(e,null,2)}`),this.peers=this._filterPeers(e.peers),this._tryConnectToAllPeers())})).catch((e=>{t.error(`requestMorePeers error ${e}`)})),this.gotPeersFromTracker=!0}_requestPeersFromPeers(e){return!!this.requestPeersTimer||(e>=this.maxConnsActive||(this.requestPeersWaitCount=this.scheduler.requestPeers(),0!==this.requestPeersWaitCount&&(this.gotPeersFromTracker=!1,this.requestPeersTimer=setTimeout((()=>{this.logger.warn("requestPeersTimer timeout"),this._handleRequestedPeers()}),1e4),!0)))}_handleRequestedPeers(){if(clearTimeout(this.requestPeersTimer),this.requestPeersTimer=void 0,this.fetcher){if(this.requestPeersQueue.length>0){const e=function(e,t){const s=[],i=new Set;for(let t of e)i.has(t.id)||(i.add(t.id),s.push(t));const{asn:r,country:n}=t;if(!r||!n||s.length<2)return s;const o=s.filter((e=>!e.asn&&!e.country)),a=s.filter((e=>e.country===n&&e.asn!==r)),h=s.filter((e=>e.asn===r&&e.country===n)),l=s.filter((e=>!o.includes(e)&&!h.includes(e)&&!a.includes(e)));return h.concat(a).concat(o).concat(l)}(this.requestPeersQueue,this.fetcher.announceInfo);this.peers=this._filterPeers(e),this.requestPeersQueue=[]}this._tryConnectToAllPeers()}}_destroyAndDeletePeer(e,t=!0){const s=this.DCMap.get(e);return!!s&&(s.destroy(t),this.DCMap.delete(e),!0)}_checkDCMap(){const e=f();for(let t of this.DCMap.values()){const s=e-t.timeJoin;e-t.timeJoin>30&&!t.connected&&(this.logger.warn(`delete ${t.remotePeerId} not connected for ${s} in DCMap`),this._destroyAndDeletePeer(t.remotePeerId,!1))}}}const Rt=Lt;class At extends re{constructor(e={},t=null){if(super(e),e.validateSegment||(e.validateSegment=function(e,t){return!0}),this.hlsjs=t,this.config=Object.assign({useDiskCache:!e.live},ge,e),t){this.HLSEvents=t.constructor.Events;const e=t.constructor.version;this.hlsjsVersion=e,this.config.isHlsV0=e&&"0"===e.split(".")[0]}this.lastLevel=0,this.multiBitrate=!1}setup(){let{token:e,channelId:t}=this.config,s=e=>{const t=h().parseURL(e);return`${t.netLoc.substring(2)+t.path.substring(0,t.path.lastIndexOf("."))}`};t&&(s=this.makeChannelId(e,t));return{channelIdMaker:s,signalId:this.makeSignalId(),browserInfo:{...this.commonBrowserInfo}}}setupElectron(){this.browserInfo.device===Q.device.PC_NATIVE&&(this.browserInfo={...this.browserInfo,app:this.config.appName,bundle:this.config.appId})}getExtraForStats(){const e=super.getExtraForStats();return!this.config.live&&this.media&&(e.pos=Math.round(this.media.currentTime)),this.multiBitrate&&this.currentLevel!==this.lastLevel&&(e.level=this.currentLevel+"",this.lastLevel=this.currentLevel),e}getExtraForPeersRequest(){const e=super.getExtraForPeersRequest();return this.multiBitrate&&(e.level=this.currentLevel+""),e}destroy(){super.destroy()}async initSegmentManager(e){const{logger:s,config:i}=this;if(self.indexedDB&&i.useDiskCache&&!i.live){const e=new Ae(this,i);try{await e.setupStore(),this.bufMgr=e}catch(e){s.warn(e),this.bufMgr=new ke(this,i)}}else this.bufMgr=new ke(this,i);if(this.bufMgr.maxBufSize<=0)throw new Error("bufMgr state is invalid");"SegmentStore"===this.bufMgr.name&&(this.removeAllListeners(t.BM_FATAL_ERROR),this.once(t.BM_FATAL_ERROR,(()=>{s.warn("SegmentStoreFatalError, switch to SegmentCache"),this.bufMgr.destroy(),this.bufMgr=new ke(this,i),e&&e(this.bufMgr)})))}generateTag(){let e=(0,Q.getBrowser)();return e.includes("iPhone")&&"HlsSwP2pEngine"===this.engineName&&(e=`${e}_p`),this.playerName&&(e=`${e}_${this.playerName}`),e}async _init(e,t,s){const{logger:i,config:r}=this;if(!re.isSupported())throw new Error("webrtc is not supported");await this.initSegmentManager((e=>{if(this.tracker){const{scheduler:t}=this.tracker;t.bufferManager=e,t.bitset.clear()}})),s.live||this.media&&(s.pos=Math.round(this.media.currentTime)),s.tag=void 0===r.tag?this.generateTag():r.tag;let n=new it(this,r.token,encodeURIComponent(e),r.announce||"",s);this.fetcher=n,this.tracker=new Rt(this,n,t,r),t.bufferManager=this.bufMgr,this.setupWindowListeners()}_setupSegmentId(){this.config.segmentId||(this.config.segmentId=this.config.strictSegmentId?ce:le)}_onHlsError(e,s){if(!s||!this.hlsjs)return;const{logger:i,tracker:r}=this;if(!i)return;const n=`${s.type} details ${s.details} reason ${s.reason}`;if(s.fatal?i.error(n):i.warn(n),"networkError"===s.type&&"HlsjsP2pEngine"===this.engineName)return;const{player:o}=this.browserInfo,a=`${o||""} hlsjs ${this.hlsjsVersion} ${location.href}`,h=this.hlsjs.constructor.ErrorDetails;switch(s.details){case h.BUFFER_STALLED_ERROR:if("HlsjsP2pEngine"===this.engineName&&this.fetcher&&this.fetcher.increRebuffers(),r&&r.scheduler){const e=r.scheduler;i.warn(`buffered: ${1e3*e.getBufferedDuration()} fragLoading ${e.fragLoading} isCritical ${e.isCritical()}`)}break;case h.INTERNAL_EXCEPTION:if(s.event&&"demuxerWorker"!==s.event){s.error||(s.error={});const e=`${s.error.message} event ${s.event} ${a}`;this.fetcher&&s.fatal&&(this.fetcher.errsInternalExpt++,this.fetcher.exptMsg=e),i.error(`INTERNAL_EXCEPTION event ${s.event} err ${s.error.message}`),this.emitEvent(t.EXCEPTION,Be(s.error,"HLSJS_EXPT")),i.report(e,s.event,this.peerId,"2.15.5")}break;default:if(s.fatal||s.details===h.FRAG_PARSING_ERROR){"mediaError"===s.type&&r&&r.scheduler&&r.scheduler.disconnectLoadingPeer().finally((()=>{r.scheduler.clearCache()}));const e=`${s.type} ${s.details} ${s.err||""} ${a}`;i.report(e,s.details,this.peerId,"2.15.5")}}}}class Dt{constructor(){this.method=null,this.key=null,this.iv=null,this._uri=null}get uri(){return!this._uri&&this.reluri&&(this._uri=a.buildAbsoluteURL(this.baseuri,this.reluri,{alwaysNormalize:!0})),this._uri}}class Mt{constructor(){this._url=null,this._byteRange=null,this._decryptdata=null,this.tagList=[],this.programDateTime=null,this.rawProgramDateTime=null,this._elementaryStreams={[Mt.ElementaryStreamTypes.AUDIO]:!1,[Mt.ElementaryStreamTypes.VIDEO]:!1}}static get ElementaryStreamTypes(){return{AUDIO:"audio",VIDEO:"video"}}get url(){return!this._url&&this.relurl&&(this._url=a.buildAbsoluteURL(this.baseurl,this.relurl,{alwaysNormalize:!0})),this._url}set url(e){this._url=e}get byteRange(){if(!this._byteRange&&!this.rawByteRange)return[];if(this._byteRange)return this._byteRange;let e=[];if(this.rawByteRange){const t=this.rawByteRange.split("@",2);if(1===t.length){const t=this.lastByteRangeEndOffset;e[0]=t||0}else e[0]=parseInt(t[1]);e[1]=parseInt(t[0])+e[0],this._byteRange=e}return e}get byteRangeStartOffset(){return this.byteRange[0]}get byteRangeEndOffset(){return this.byteRange[1]}get decryptdata(){return this._decryptdata||(this._decryptdata=this.fragmentDecryptdataFromLevelkey(this.levelkey,this.sn)),this._decryptdata}get endProgramDateTime(){if(!Number.isFinite(this.programDateTime))return null;let e=Number.isFinite(this.duration)?this.duration:0;return this.programDateTime+1e3*e}get encrypted(){return!(!this.decryptdata||null===this.decryptdata.uri||null!==this.decryptdata.key)}addElementaryStream(e){this._elementaryStreams[e]=!0}hasElementaryStream(e){return!0===this._elementaryStreams[e]}createInitializationVector(e){let t=new Uint8Array(16);for(let s=12;s<16;s++)t[s]=e>>8*(15-s)&255;return t}fragmentDecryptdataFromLevelkey(e,t){let s=e;return e&&e.method&&e.uri&&!e.iv&&(s=new Dt,s.method=e.method,s.baseuri=e.baseuri,s.reluri=e.reluri,s.iv=this.createInitializationVector(t)),s}}class kt{constructor(e){this.endCC=0,this.endSN=0,this.fragments=[],this.initSegment=null,this.live=!0,this.needSidxRanges=!1,this.startCC=0,this.startSN=0,this.startTimeOffset=null,this.targetduration=0,this.totalduration=0,this.type=null,this.url=e,this.version=null}get hasProgramDateTime(){return!(!this.fragments[0]||!Number.isFinite(this.fragments[0].programDateTime))}}const Nt=/^(\d+)x(\d+)$/,Ot=/\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g;class $t{constructor(e){"string"==typeof e&&(e=$t.parseAttrList(e));for(let t in e)e.hasOwnProperty(t)&&(this[t]=e[t])}decimalInteger(e){const t=parseInt(this[e],10);return t>Number.MAX_SAFE_INTEGER?1/0:t}hexadecimalInteger(e){if(this[e]){let t=(this[e]||"0x").slice(2);t=(1&t.length?"0":"")+t;const s=new Uint8Array(t.length/2);for(let e=0;eNumber.MAX_SAFE_INTEGER?1/0:t}decimalFloatingPoint(e){return parseFloat(this[e])}enumeratedString(e){return this[e]}decimalResolution(e){const t=Nt.exec(this[e]);if(null!==t)return{width:parseInt(t[1],10),height:parseInt(t[2],10)}}static parseAttrList(e){let t,s={};for(Ot.lastIndex=0;null!==(t=Ot.exec(e));){let e=t[2],i='"';0===e.indexOf(i)&&e.lastIndexOf(i)===e.length-1&&(e=e.slice(1,-1)),s[t[1]]=e}return s}}const Bt=$t,xt={audio:{a3ds:!0,"ac-3":!0,"ac-4":!0,alac:!0,alaw:!0,dra1:!0,"dts+":!0,"dts-":!0,dtsc:!0,dtse:!0,dtsh:!0,"ec-3":!0,enca:!0,g719:!0,g726:!0,m4ae:!0,mha1:!0,mha2:!0,mhm1:!0,mhm2:!0,mlpa:!0,mp4a:!0,"raw ":!0,Opus:!0,samr:!0,sawb:!0,sawp:!0,sevc:!0,sqcp:!0,ssmv:!0,twos:!0,ulaw:!0},video:{avc1:!0,avc2:!0,avc3:!0,avc4:!0,avcp:!0,drac:!0,dvav:!0,dvhe:!0,encv:!0,hev1:!0,hvc1:!0,mjp2:!0,mp4v:!0,mvc1:!0,mvc2:!0,mvc3:!0,mvc4:!0,resv:!0,rv60:!0,s263:!0,svc1:!0,svc2:!0,"vc-1":!0,vp08:!0,vp09:!0}};const Ft=/#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)/g,qt=/#EXT-X-MEDIA:(.*)/g,Wt=new RegExp([/#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source,/|(?!#)([\S+ ?]+)/.source,/|#EXT-X-BYTERANGE:*(.+)/.source,/|#EXT-X-PROGRAM-DATE-TIME:(.+)/.source,/|#.*/.source].join(""),"g"),zt=/(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:(#)([^:]*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/,Ut=/\.(mp4|m4s|m4v|m4a)$/i;class Ht{static findGroup(e,t){if(!e)return null;let s=null;for(let i=0;i2?(t=s.shift()+".",t+=parseInt(s.shift()).toString(16),t+=("000"+parseInt(s.shift()).toString(16)).substr(-4)):t=e,t}static resolve(e,t){return a.buildAbsoluteURL(t,e,{alwaysNormalize:!0})}static parseMasterPlaylist(e,t){let s,i=[];function r(e,t){["video","audio"].forEach((s=>{const i=e.filter((e=>function(e,t){const s=xt[t];return!!s&&!0===s[e.slice(0,4)]}(e,s)));if(i.length){const r=i.filter((e=>0===e.lastIndexOf("avc1",0)||0===e.lastIndexOf("mp4a",0)));t[`${s}Codec`]=r.length>0?r[0]:i[0],e=e.filter((e=>-1===i.indexOf(e)))}})),t.unknownCodecs=e}for(Ft.lastIndex=0;null!=(s=Ft.exec(e));){const e={},n=e.attrs=new Bt(s[1]);e.url=Ht.resolve(s[2],t);const o=n.decimalResolution("RESOLUTION");o&&(e.width=o.width,e.height=o.height),e.bitrate=n.decimalInteger("AVERAGE-BANDWIDTH")||n.decimalInteger("BANDWIDTH"),e.name=n.NAME,r([].concat((n.CODECS||"").split(/[ ,]+/)),e),e.videoCodec&&-1!==e.videoCodec.indexOf("avc1")&&(e.videoCodec=Ht.convertAVC1ToAVCOTI(e.videoCodec)),i.push(e)}return i}static parseMasterPlaylistMedia(e,t,s,i=[]){let r,n=[],o=0;for(qt.lastIndex=0;null!==(r=qt.exec(e));){const e={},a=new Bt(r[1]);if(a.TYPE===s){if(e.groupId=a["GROUP-ID"],e.name=a.NAME,e.type=s,e.default="YES"===a.DEFAULT,e.autoselect="YES"===a.AUTOSELECT,e.forced="YES"===a.FORCED,a.URI&&(e.url=Ht.resolve(a.URI,t)),e.lang=a.LANGUAGE,e.name||(e.name=e.lang),i.length){const t=Ht.findGroup(i,e.groupId);e.audioCodec=t?t.codec:i[0].codec}e.id=o++,n.push(e)}}return n}static parseLevelPlaylist(e,t){let s,i,r=0,n=0,o=new kt(t),a=new Dt,h=0,l=null,c=new Mt,d=null;for(Wt.lastIndex=0;null!==(s=Wt.exec(e));){const e=s[1];if(e){c.duration=parseFloat(e);const t=(" "+s[2]).slice(1);c.title=t||null,c.tagList.push(t?["INF",e,t]:["INF",e])}else if(s[3]){if(Number.isFinite(c.duration)){const e=r++;c.start=n,c.levelkey=a,c.sn=e,c.cc=h,c.baseurl=t,c.relurl=(" "+s[3]).slice(1),jt(c,l),o.fragments.push(c),l=c,n+=c.duration,c=new Mt}}else if(s[4]){if(c.rawByteRange=(" "+s[4]).slice(1),l){const e=l.byteRangeEndOffset;e&&(c.lastByteRangeEndOffset=e)}}else if(s[5])c.rawProgramDateTime=(" "+s[5]).slice(1),c.tagList.push(["PROGRAM-DATE-TIME",c.rawProgramDateTime]),null===d&&(d=o.fragments.length);else{for(s=s[0].match(zt),i=1;i=0&&(a.method=g,a.baseuri=t,a.reluri=f,a.key=null,a.iv=p));break;case"START":let i=new Bt(e).decimalFloatingPoint("TIME-OFFSET");Number.isFinite(i)&&(o.startTimeOffset=i);break;case"MAP":let l=new Bt(e);c.relurl=l.URI,c.rawByteRange=l.BYTERANGE,c.baseurl=t,c.sn="initSegment",o.initSegment=c,c=new Mt,c.rawProgramDateTime=o.initSegment.rawProgramDateTime;break;default:console.warn(`line parsed but not handled: ${s}`)}}}return c=l,c&&!c.relurl&&(o.fragments.pop(),n-=c.duration),o.totalduration=n,o.averagetargetduration=n/o.fragments.length,o.endSN=r-1,o.startCC=o.fragments[0]?o.fragments[0].cc:0,o.endCC=h,!o.initSegment&&o.fragments.length&&o.fragments.every((e=>Ut.test(e.relurl)))&&(console.warn("MP4 fragments found but no init segment (probably no MAP, incomplete M3U8), trying to fetch SIDX"),c=new Mt,c.relurl=o.fragments[0].relurl,c.baseurl=t,c.level=id,c.sn="initSegment",o.initSegment=c,o.needSidxRanges=!0),d&&function(e,t){let s=e[t];for(let i=t-1;i>=0;i--){const t=e[i];t.programDateTime=s.programDateTime-1e3*t.duration,s=t}}(o.fragments,d),o}}function jt(e,t){e.rawProgramDateTime?e.programDateTime=Date.parse(e.rawProgramDateTime):t&&t.programDateTime&&(e.programDateTime=t.endProgramDateTime),Number.isFinite(e.programDateTime)||(e.programDateTime=null,e.rawProgramDateTime=null)}const Gt={ANY:0,COMPLETE:1,PARTIAL_FORWARD:2,PARTIAL_REVERSE:3},Vt=(e,t,s,i,r=!1)=>{const[n,o,a]=Xt(e,t,s,i);return r&&n.length>=1?L(n[0]):n.length>=2?[n[0],n[1]]:R(n,o,a)},Xt=(e,t,s,i)=>{const r=[],{COMPLETE:n,PARTIAL_FORWARD:o,PARTIAL_REVERSE:a}=Gt;return[n,o,a].forEach((n=>{r.push(Yt(e,n,t,s,i))})),r},Yt=(e,t,s,i,r)=>e.filter((e=>e.bitset.hasWithId(s,i,r,t)));class Jt{constructor(e=!1,t){this.isLive=e,this.levelMap=new Map;for(let e in t){const s=Number(e);if(s<0)continue;const i=new Map;if(t[e])for(let s of t[e])i.set(s,{state:Gt.COMPLETE,segId:void 0,size:void 0});this.levelMap.set(s,i)}}totalLevels(){return this.levelMap.size}hasWithId(e,t,s,i=Gt.ANY){if(t<0)return!1;const r=this._createOrGetSet(t).get(e);return!!r&&((!s||!r.segId||r.segId===s)&&(i===Gt.ANY||r.state===i))}has(e,t,s=Gt.ANY){return this.hasWithId(e,t,void 0,s)}hasCompleteOr(e,t,s=Gt.COMPLETE){const i=this._createOrGetSet(t).get(e);return!!i&&(i.state===Gt.COMPLETE||i.state===s)}getObj(e,t){let s=this._createOrGetSet(t).get(e);return s||(s={}),s}getSegId(e,t){return this.getObj(e,t).segId}getSize(e,t){return this.getObj(e,t).size}getState(e,t){return this.getObj(e,t).state}delete(e,t){return this._createOrGetSet(t).delete(e)}add(e,t,s,i,r){if("number"!=typeof(n=e)||n%1!=0)return;var n;this._createOrGetSet(t).set(e,{state:i,segId:s,size:r}),this.isLive&&this._trimBitset(e)}array(e){const t=this._createOrGetSet(e);return this._keysForStateComplete(t)}allArray(){let e={};return this.levelMap.forEach(((t,s)=>{e[s]=this._keysForStateComplete(t)})),e}clear(){this.levelMap.forEach((e=>{e.clear()}))}size(e){return this._createOrGetSet(e).size}_createOrGetSet(e){"number"!=typeof e&&(e=Number(e));let t=this.levelMap.get(e);return t||(t=new Map,this.levelMap.set(e,t)),t}_trimBitset(e){const t=e-20;t>0&&this.levelMap.forEach((e=>{e.delete(t)}))}_keysForStateComplete(e){const t=[];for(let[s,i]of e)i.state===Gt.COMPLETE&&t.push(s);return t}}class Qt{constructor(){this.levelMap=new Map}totalLevels(){return this.levelMap.size}has(e,t){return this._createOrGetMap(t).has(e)}delete(e,t){return this._createOrGetMap(t).delete(e)}decre(e,t){const s=this._createOrGetMap(t);if(s.has(e)){let t=s.get(e);1===t?s.delete(e):s.set(e,t-1)}}incre(e,t){const s=this._createOrGetMap(t);if(s.has(e)){let t=s.get(e);s.set(e,t+1)}else s.set(e,1)}clear(){this.levelMap.forEach((e=>{e.clear()}))}size(e){return this._createOrGetMap(e).size}_createOrGetMap(e){"number"!=typeof e&&(e=Number(e));let t=this.levelMap.get(e);return t||(t=new Map,this.levelMap.set(e,t)),t}}const Kt=class{constructor(){this.peerMap=new Map}isEmpty(){return 0===this.peerMap.size}size(){return this.peerMap.size}clear(){this.peerMap.clear()}getPeers(){return[...this.peerMap.values()]}getPeerValues(){return this.peerMap.values()}hasPeer(e){return this.peerMap.has(e)}addPeer(e,t){this.peerMap.set(e,t)}getPeerIds(){return[...this.peerMap.keys()]}removePeer(e){this.peerMap.delete(e)}getPeersOrderByWeight(){const e=this.getAvailablePeers();return e.sort(((e,t)=>0===t.weight?1:0===e.weight?-1:t.weight-e.weight)),e}getPeer(e){return this.peerMap.get(e)}getAvailablePeers(){return this.getPeers().filter((e=>e.isAvailableUrgently))}},Zt=Symbol("shareOnly");class es extends(n()){constructor(e,t){super(),this.engine=e,this.config=t,this.logger=e.logger,this.bufMgr=null,this.peerManager=new Kt,this.fragLoading=!1,this._setupEngine&&this._setupEngine(),this.startCheckConnsTimer(),this.dcDownloadTimeout=t.dcDownloadTimeout,this[Zt]=!1,this.downloadOnly=!1,this.loadedPeerNum=0,this.minConns=5}get isMobileNet(){return this.engine.isMobileNet}startCheckConnsTimer(){this.checkConnsTimer=setInterval((()=>{this.logger.info("start check conns");const e=this.getStatsForPeer();let t=this.peersNum;const s=f();this.getPeers().forEach((i=>{t>this.minConns+1&&(s-i.dataExchangeTs>120||s-i.gotStatsTs>=83)?(this.logger.warn(`close dead peer ${i.remotePeerId} level ${i.currentLevel}`),i.close(!1),t--):i.connected&&i.sendMsgStats(t,e)}))}),4e4)}get httpRangeSupported(){return this.config.httpRangeSupported}getStatsForPeer(){return{}}_handlePieceAborted(){}requestPeers(){const e=f();let t=0;for(let s of this.getPeers())s.mobileNet||s.super||(e-s.gotPeersTS<60?this.logger.warn(`${s.remotePeerId} just got peers, ignored`):(s.sendPeersRequest(),s.gotPeersTS=e,t++));return t}chokePeerRequest(t){const s={event:e.DC_CHOKE};t?t.sendJson(s):this._broadcastToPeers(s)}unchokePeerRequest(t){const s={event:e.DC_UNCHOKE};t?t.sendJson(s):this._broadcastToPeers(s)}stopRequestFromPeers(){for(let e of this.getPeers())e.choked=!0}resumeRequestFromPeers(){for(let e of this.getPeers())e.choked=!1}setShareOnly(){this[Zt]=!0}deletePeer(e){e.downloading&&this._handlePieceAborted(e.remotePeerId),this.peerManager.hasPeer(e.remotePeerId)&&this.peerManager.removePeer(e.remotePeerId),this._peersStats(this.peerManager.getPeerIds())}getPeers(){return[...this.peerManager.getPeerValues()]}addPeer(e){const{logger:t}=this;this.peerManager.addPeer(e.remotePeerId,e),this[Zt]&&(e.choked=!0);const s=this.peerManager.getPeerIds();this._peersStats(s);const{asn:i,country:r}=e.region||{};t.info(`add peer ${e.remotePeerId} country ${r||""} asn ${i||""}, now has ${s.length} peers`)}hasPeer(e){return this.peerManager.hasPeer(e)}get hasPeers(){return this.peersNum>0}get peersNum(){return this.peerManager.size()}get hasIdlePeers(){const{logger:e}=this,t=this.getIdlePeer().length;if(e.info(`peers: ${this.peersNum} idle peers: ${t}`),te.downloading));e.warn(`downloading: ${s.length} choked: ${t.filter((e=>e.choked)).length}`);for(let t of s)e.warn(`${t.remotePeerId} loading ${t.segId} remains ${t.remainAttachments} total ${t.pieceMsg.attachments}`)}return t>0}getIdlePeer(){return this.peerManager.getAvailablePeers()}set bufferManager(t){this.bufMgr=t,t.on(e.BM_LOST,(({sn:e,segId:t,next:s,level:i})=>{this._broadcastLost(e,t,i),this.onBufferManagerLost(e,t,s,i)})).on(e.BM_SEG_ADDED,(e=>{this.onBufferManagerSegAdded(e)}))}onBufferManagerSegAdded(e){}_broadcastLost(t,s,i,r){this.config.live||this._broadcastToPeers({event:e.DC_LOST,sn:t,seg_id:s||void 0,level:i},r)}destroy(){const{logger:e}=this;this.peersNum>0&&this.peerManager.clear(),this.removeAllListeners(),clearInterval(this.checkConnsTimer),clearTimeout(this.checkTimer),e.warn("destroy BtScheduler")}notifyPeersLoaded(e){}_setupDC(t){const{logger:s}=this;t.on(e.DC_PIECE_ACK,(e=>{e.size&&(this.engine.fetcher.reportUploaded(e.size),s.info(`uploaded ${e.seg_id} size ${e.size} to ${t.remotePeerId}`))})).on(e.DC_PIECE_ABORT,(e=>{s.warn(`peer ${t.remotePeerId} download aborted, reason ${e.reason}`),this._handlePieceAborted(t.remotePeerId),this.config.live&&this.checkPeers&&this.checkPeers()})).on(e.DC_DISCONNECT,(()=>{this.peersNum>=this.minConns&&(this.logger.warn(`close disconnected peer ${t.remotePeerId}`),t.close(!1))}))}_broadcastToPeers(e,t){for(let s of this.getPeers())t&&s===t||s.sendJson(e)}_peersStats(e){this.engine.emitEvent("peers",e);const t=this.engine.config.getPeersInfo;T(t)&&t(e)}startCheckPeersTimer(){this.logger.info("startCheckPeersTimer");const e=()=>{this.checkPeers();const t=1e3*(0===(s=this.loadedPeerNum)?3:.5*s+1.67);var s;this.loadedPeerNum=0,this.checkTimer=setTimeout(e,t)};this.checkTimer=setTimeout(e,15e3)}removeStreamListener(e,t){const s=this.requestingMap.get(e);if(s)return void s.removeStreamListener(t);const i=this.segmentBuilderMap.get(e);i&&i.removeStreamListener(t)}setTargetPeersFromGroup(e,t,s,i){if(e.hasReversePeer){if((s=t.concat(s)).length>0)return this.targetPeers.forwardPeer=s[0],!0}else if(e.hasForwardPeer&&(i=t.concat(i)).length>0)return this.targetPeers.reversePeer=i[0],!0;return t.length>0?(e.hasForwardBuffer?this.targetPeers.reversePeer=t[0]:this.targetPeers.forwardPeer=t[0],!0):(this.targetPeers=R(t,s,i),this.targetPeers.some((e=>!!e)))}}const ts=es;class ss extends(n()){constructor(){super(),this.internalMap=new Map}has(e){return this.internalMap.has(e)}set(e,t){this.internalMap.set(e,t),v(this.internalMap,13,(e=>{e&&e.destroy()}))}get(e){return this.internalMap.get(e)}delete(e){const t=this.internalMap.get(e);t&&(t.destroy(),this.internalMap.delete(e))}get size(){return this.internalMap.size}clear(){this.internalMap.clear(),this.removeAllListeners()}get activePeers(){let e=0;return[...this.internalMap.values()].forEach((t=>{t.hasForwardPeer&&!t.forwardCanceled&&(e+=1),t.hasReversePeer&&!t.reverseCanceled&&(e+=1)})),e}}const is=0,rs=1,ns=2,os=3;class as extends(n()){constructor(){super(),this.UNSENT=0,this.OPENED=1,this.HEADERS_RECEIVED=2,this.LOADING=3,this.DONE=4,this.timeout=0,this.withCredentials=!1,this.status=0,this.readyState=this.UNSENT,this.headers=new Map,this.responseHeaders=null,this.on("load",(e=>{this.onload&&this.onload(e)})),this.on("abort",(e=>{this.onabort&&this.onabort(e)})),this.on("error",(e=>{this.onerror&&this.onerror(e)})),this.on("loadstart",(e=>{this.onloadstart&&this.onloadstart(e)})),this.on("progress",(e=>{this.onprogress&&this.onprogress(e)})),this.on("timeout",(e=>{this.ontimeout&&this.ontimeout(e)})),this.on("loadend",(e=>{this.onloadend&&this.onloadend(e)})),this.on("readystatechange",(()=>{this.onreadystatechange&&this.onreadystatechange()}))}setRequestHeader(e,t){this.headers.set(e,t)}addEventListener(e,t){this.addListener(e,t)}removeEventListener(e,t){this.removeListener(e,t)}overrideMimeType(){}getAllResponseHeaders(){if(!this.responseHeaders)return null;let e="";return this.responseHeaders.forEach(((t,s)=>{e+=`${s}: ${t}\n`})),e}getResponseHeader(e){return this.responseHeaders?this.responseHeaders.get(e):null}open(){this.readyState=this.OPENED,this.emit("loadstart")}abort(){this.readyState=this.DONE,this.status=0,this.emit("loadend")}send(){}_emitEvent(e){this.emit(e,{type:e,target:this})}}const hs=/(\d+)-(\d+)\/(\d+)/;function ls(){if(self.fetch&&self.AbortController&&self.ReadableStream&&self.Request)try{return new self.ReadableStream({}),!0}catch(e){}return!1}class cs{constructor(e){this.fetchSetup=e.fetchSetup||ds,this.xhrSetup=e.xhrSetup,this.controller=new self.AbortController,this.stats=A(),this.packetSize=c,this.fakeXhr=new as}destroy(){this.loader=this.callbacks=this.context=this.config=this.request=null,this.abortInternal(),this.response=null,this.fetchSetup=this.xhrSetup=this.fakeXhr=this.controller=this.stats=null}abortInternal(){this.controller&&!this.stats.loading.end&&(this.stats.aborted=!0,this.callbacks&&this.callbacks.onUpdate&&this.callbacks.onUpdate(void 0,!1,!0),this.controller.abort())}abort(){this.abortInternal(),this.callbacks&&this.callbacks.onAbort&&this.callbacks.onAbort(this.stats,this.context,this.response)}load(e,t,s){const i=this.stats;i.trequest=i.loading.start;let r=function(e,t){const s={method:"GET",mode:"cors",credentials:"same-origin",signal:t,headers:new self.Headers(Object.assign({},e.headers))};e.rangeEnd&&s.headers.set("Range","bytes="+e.rangeStart+"-"+String(e.rangeEnd-1));return s}(e,this.controller.signal);const n="arraybuffer"===e.responseType,o=n?"byteLength":"length",{maxTimeToFirstByteMs:a=8e3,maxLoadTimeMs:h=2e4}=t.loadPolicy||{},l=s.onUpdate,c=s.onBodyStart;this.context=e,this.config=t,this.callbacks=s,this.xhrSetup&&(this.xhrSetup(this.fakeXhr,e.url),r=function(e,t){e.withCredentials&&(t.credentials="include");for(let[s,i]of e.headers)t.headers.set(s,i);return t}(this.fakeXhr,r)),this.request=this.fetchSetup(e,r),clearTimeout(this.requestTimeout),t.timeout=a&&Number.isFinite(a)?a:h,this.requestTimeout=setTimeout((()=>{this.abortInternal(),this.fakeXhr._emitEvent("timeout"),this.fakeXhr._emitEvent("loadend"),s.onTimeout&&s.onTimeout(i,e,this.response)}),this.fakeXhr.timeout||t.timeout);const d="then"in(u=this.request)&&u.then instanceof Function?this.request.then(self.fetch):self.fetch(this.request);var u;const{fakeXhr:g}=this;g.readyState=g.OPENED,g.emit("readystatechange"),g._emitEvent("loadstart"),d.then((r=>{this.response=this.loader=r;const o=Math.max(self.performance.now(),i.loading.start);if(self.clearTimeout(this.requestTimeout),t.timeout=h,this.requestTimeout=self.setTimeout((()=>{this.abortInternal(),s.onTimeout&&s.onTimeout(i,e,this.response)}),h-(o-i.loading.start)),!r.ok){const{status:e,statusText:t}=r;throw new us(t||"fetch, bad network response",e,r)}i.tfirst=i.loading.first=o,i.total=function(e){const t=e.get("Content-Range");if(t){const e=function(e){const t=hs.exec(e);if(t)return parseInt(t[2])-parseInt(t[1])+1}(t);if(Number.isFinite(e))return e}const s=e.get("Content-Length");if(s)return parseInt(s)}(r.headers)||i.total;let a=0;try{const e=r.headers.get("Content-Range").split("/");2===e.length&&(a=parseInt(e[1],10))}catch(e){}const{fakeXhr:d}=this;return d.readyState=d.HEADERS_RECEIVED,d.responseHeaders=r.headers,d.emit("readystatechange"),l&&"0"!==i.total?(c&&c(i.total,a),this.loadProgressively(r,i,e,l)):(d.emit("progress",new ProgressEvent("progress",{lengthComputable:!1})),n?r.arrayBuffer():"json"===e.responseType?r.json():r.text())})).then((t=>{const{response:r}=this;clearTimeout(this.requestTimeout),i.tload=i.loading.end=Math.max(performance.now(),i.loading.first);const n=t[o];n&&(i.loaded=i.total=n);const a={url:r.url,data:t,code:r.status};s.onProgress&&s.onProgress(i,e,t,r),s.onSuccess&&s.onSuccess(a,i,e,r)})).catch((t=>{if(clearTimeout(this.requestTimeout),i.aborted)return;const r=t&&t.code||0,n=t?t.message:null;s.onError&&s.onError({code:r,text:n},e,t?t.details:null,i)}))}loadProgressively(e,t,s,i){const r=e.body.getReader();let n=0,a=0,h=(0,o.h)(0),l=!1;const d=()=>r.read().then((({value:s,done:r})=>{const{fakeXhr:u}=this;if(u.readyState!==u.LOADING&&(u.readyState=u.LOADING,u.emit("readystatechange")),s&&(n+=s.length),r){if(h.byteLength>0)if(n<=this.packetSize){const e=(0,o.h)(n);h.copy(e,0,a*this.packetSize,h.byteLength),i(e,!0)}else{const e=function(e,t){const s=e.byteLength-t,i=[];let r=t,n=Math.floor(s/c),a=s%c;for(let t=0;t0){const t=(0,o.h)(a);e.copy(t,0,r,r+a),i.push(t)}return i}(h,a*this.packetSize);for(let t=0;t=this.packetSize){n-=this.packetSize;const e=(0,o.h)(this.packetSize);h.copy(e,0,a*this.packetSize,(a+1)*this.packetSize),a++,i(e,!1)}return d()})).catch((()=>(this.fakeXhr._emitEvent("abort"),this.fakeXhr._emitEvent("loadend"),Promise.reject())));return d()}}function ds(e,t){return new self.Request(e.url,t)}class us extends Error{constructor(e,t,s){super(e),this.code=t,this.details=s}}class gs extends(n()){constructor(e,t,s=!1){super(),this.coordinator=e,this.logger=t,this.rangeSupported=s,this.rangeStart=0,this.rangeEnd=0,this.httpLoadTime=2e3,this.proxied=!1,this.forwardPeer=null,this.reversePeer=null,this.bufArr=[],this.forwardBufList=[],this.reverseBufList=[],this.forwardOffset=-1,this.reverseOffset=1e4,this.timeStart=0,this.timeReceivePiece=0,this.destroyed=!1,this.forwardStreamListeners=[],this.reverseStreamListeners=[],this.rangeRequesting=!1,this.waitingRemain=!1,this.httpLoaded=0,this.p2pLoaded=0,this.deadline=0,this.forwardCanceled=!1,this.reverseCanceled=!1,this.firstReceived=!1,this.alreadyOutput=!1,this.pieceMsg={}}get isDownloading(){return this.timeReceivePiece>0}get isAlmostDeadline(){return this.rangeRequesting||this.alreadyOutput}hasPeer(e){return!!e&&(e===this.forwardPeer||e===this.reversePeer)}get streamListeners(){return[...this.reverseStreamListeners,...this.forwardStreamListeners].length}_notifyStreamListenersAbort(){const{sn:e,seg_id:t}=this.pieceMsg,s=[...this.reverseStreamListeners,...this.forwardStreamListeners];for(let i of s){const{handler:s}=i;s(e,t,!0,"aborted by synthesizer")}this._resetStreamListeners()}_resetStreamListeners(){this.reverseStreamListeners.length=0,this.forwardStreamListeners.length=0}_notifyStreamListenersRemain(){if(this.forwardStreamListeners.length>0){for(let e=this.forwardOffset+1;e0){for(let e=this.reverseOffset-1;e>=0;e--)this._notifyStreamListeners(!0,this.bufArr[e],e);this.reverseStreamListeners=[]}}addStreamListener(e,t,s){(e?this.reverseStreamListeners:this.forwardStreamListeners).push({handler:s,peerId:t})}removeStreamListener(e){const{sn:t,seg_id:s}=this.pieceMsg,i=i=>i.filter((i=>i.peerId!==e||(i.handler(t,s,!0,"aborted by cancel"),!1)));this.forwardStreamListeners=i(this.forwardStreamListeners),this.reverseStreamListeners=i(this.reverseStreamListeners)}setTimeout(e=0,t=!1){this.logger.info(`syn setTimeout ${e}`);let s=performance.now();e<=0?setTimeout((()=>{this._handleTimeout(!1,!1)}),0):(this.firstPieceTimer=setTimeout((()=>{if(this.firstReceived)return;const e=()=>{this.logger.warn(`switch to http, firstReceived ${this.firstReceived}`),this._handleTimeout(!1)};if(this.timeReceivePiece>0){const t=(this.timeReceivePiece-s)/2;t>0?this.firstPieceTimer=setTimeout((()=>{this.firstReceived&&!this._shouldSwitch()||e()}),t):e()}else e()}),e/2),this.deadline=s+e,this._startTimer(e,t))}setExtra(e={}){e.url&&(this.url=e.url),e.rangeStart&&(this.rangeStart=e.rangeStart),e.rangeEnd&&(this.rangeEnd=e.rangeEnd),e.httpLoadTime&&(this.httpLoadTime=e.httpLoadTime),e.proxied&&(this.proxied=!0),e.xhrSetup&&(this.xhrSetup=e.xhrSetup),e.headers&&(this.headers=e.headers),e.segId&&!this.pieceMsg.seg_id&&(this.pieceMsg.seg_id=e.segId)}get hasForwardPeer(){return!!this.forwardPeer}get hasReversePeer(){return!!this.reversePeer}hasPeerId(e){return this.forwardPeer&&this.forwardPeer.remotePeerId===e||this.reversePeer&&this.reversePeer.remotePeerId===e}get isEmpty(){return null===this.forwardPeer&&null===this.reversePeer}get isFull(){return this.forwardPeer&&this.reversePeer}setForwardPeer(e,t){return!this.alreadyOutput&&(!!this._checkPieceSize(t)&&(this.forwardPeer=e,this.reversePeer&&this._print(),this._setupPeer(e,!1,t),!0))}setReversePeer(e,t){return!this.alreadyOutput&&(!!this._checkPieceSize(t)&&(this.reversePeer=e,this.forwardPeer&&this._print(),this._setupPeer(e,!0,t),!0))}setPeer(e,t,s){return t?this.setReversePeer(e,s):this.setForwardPeer(e,s)}deletePeer(e){const t=e===this.reversePeer;this._detachPeer(e),t?this.reversePeer=null:this.forwardPeer=null,(this.isEmpty||this.deadline>0)&&this._handleTimeout(!1,!1)}terminate(){this._handleTimeout(!1,!1)}get hasPartialBuffer(){return this.hasForwardBuffer||this.hasReverseBuffer}get hasForwardBuffer(){return this.forwardOffset>=0}get hasReverseBuffer(){return this.pieceMsg&&this.reverseOffset=this.pieceMsg.attachments-1}get isReverseBufferFull(){return this.reverseOffset<=0}_cancelP2p(e=!1){const{seg_id:t,sn:s,level:i}=this.pieceMsg;!this.forwardPeer||this.isForwardBufferFull||this.forwardCanceled||(this.forwardPeer.cancelDownload(s,i,t),this.forwardCanceled=!0),e||!this.reversePeer||this.isReverseBufferFull||this.reverseCanceled||(this.reversePeer.cancelDownload(s,i,t),this.reverseCanceled=!0)}detachPeers(){this._detachPeer(this.forwardPeer),this._detachPeer(this.reversePeer)}destroy(){clearTimeout(this.timer),clearTimeout(this.firstPieceTimer),this._notifyStreamListenersAbort(),this.removeAllListeners(),this.destroyed=!0,this._detachPeer(this.forwardPeer),this.forwardPeer=null,this.forwardOffset=-1,this._detachPeer(this.reversePeer),this.reversePeer=null,this.reverseOffset=1e4,this.bufArr=[],this.forwardStreamListeners=[],this.reverseStreamListeners=[],this._abortLoading()}_abortLoading(){this._cancelP2p(),this.httpLoader&&(this.logger.warn("abort syn httpLoader"),this.httpLoader.abort(),this.httpLoader=void 0)}_detachPeer(t){if(!t)return;const s=t===this.reversePeer?this.reverseEvents:this.forwardEvents;s&&s&&t.off(e.DC_PIECE_DATA,s.onPieceData).off(e.DC_PIECE,s.onPiece).off(e.DC_PIECE_NOT_FOUND,s.onPieceNotFound).off(e.DC_PIECE_ABORT,s.onPieceAbort)}_receivePacket(t,s,i,r=!0){const{seg_id:n,sn:a,level:h,size:l,ext:c}=this.pieceMsg,d=s-1;if(this.bufArr[d]?(this.logger.warn(`syn bufArr ${n} already has ${d} size ${i.byteLength}`),this.bufArr[d]=i):(r?this.p2pLoaded+=i.byteLength:this.httpLoaded+=i.byteLength,this.emit(e.SYN_PROGRESS,{total:l,loaded:this.p2pLoaded+this.httpLoaded,first:!this.firstReceived,segId:n,sn:a}),this.firstReceived=!0,this.bufArr[d]=i,t?this.reverseOffset=d:this.forwardOffset=d,this._notifyStreamListeners(t,i,d)),this.forwardOffset!==this.reverseOffset-1)return!0;this.rangeRequesting||(this.forwardPeer&&(this.forwardPeer.miss=0),this.reversePeer&&(this.reversePeer.miss=0)),clearTimeout(this.timer),this._notifyStreamListenersRemain();const u=performance.now()-this.timeStart,g=l/u;let f=o.h.concat(this.bufArr);const p=f.byteLength;if(p===l){if(this.alreadyOutput)return!1;this.alreadyOutput=!0,this._abortLoading();let t=f.buffer;const s=new J(a,n,t,this.getFromPeerId(),h,c);this.emit(e.SYN_OUTPUT,s,{speed:g,time:u,p2p:this.p2pLoaded,http:this.httpLoaded})}else{this.logger.error(`${n} expectedSize ${l} != byteLength ${p} forward ${this.forwardOffset} reverse ${this.reverseOffset}`);for(let e=0;e{t&&t.emit(e.DC_ERROR,!0)}))}_checkPieceSize(e){const{size:t,seg_id:s,sn:i}=this.pieceMsg;return!e||!t||e===t||(this.logger.warn(`checkPieceSize ${s||i} size not match ${t} ${e}`),!1)}_setupPeer(t,s,i){const{logger:r}=this;0===this.timeStart&&(this.timeStart=performance.now()),i&&!this.pieceMsg.size&&(this.pieceMsg.size=i);const n=(s,i,n,o,a,h)=>{if(this.destroyed)return;if(!this._validateMsg(s,h.level,i))return void r.error(`onPieceData ${i||s} size ${n.byteLength} not match ${JSON.stringify(this.pieceMsg)} from ${t.remotePeerId}`);if(o0&&this._shouldSwitch()&&(r.warn("should switch to http"),clearTimeout(this.timer),clearTimeout(this.firstPieceTimer),this._handleTimeout(!1,!1))},o=e=>{if(this.destroyed)return;const{attachments:s,size:i,sn:n,level:o,seg_id:a,ext:h={}}=e;let l=!0;(i<=999||!this._validateMsg(n,o,a))&&(r.warn(`onPiece ${JSON.stringify(e)} not match ${JSON.stringify(this.pieceMsg)}`),l=!1),this._checkPieceSize(i)||(l=!1);const{ext:c}=this.pieceMsg;if(c&&h.hash&&c.hash&&h.hash!==c.hash&&(this.logger.warn(`syn ${a||n} hash not match ${h.hash} ${c.hash}`),l=!1),!l)return t.cancelDownload(n,o,a),void this.deletePeer(t);0===this.bufArr.length?(this.pieceMsg={...this.pieceMsg,seg_id:a,size:i,attachments:s,ext:h},this.reverseOffset=s,this.bufArr=new Array(s),this.timeReceivePiece=performance.now()):!this.pieceMsg.ext.hash&&h.hash&&(this.pieceMsg.ext.hash=h.hash)},a=e=>{this.destroyed||this.deletePeer(t)},h=()=>{this.destroyed||this.deletePeer(t)},l={onPieceData:n,onPiece:o,onPieceNotFound:a,onPieceAbort:h};s?this.reverseEvents=l:this.forwardEvents=l,t.on(e.DC_PIECE_DATA,n).once(e.DC_PIECE,o).once(e.DC_PIECE_NOT_FOUND,a).once(e.DC_PIECE_ABORT,h)}_shouldSwitch(){const e=c,t=this.pieceMsg.size-e*this.loadedPackets;return this.coordinator.shouldSwitchToHttp(t,this.deadline,this.p2pSpeed,e,this.httpLoadTime)}_startTimer(e,t=!0){this.timer=setTimeout(this._handleTimeout.bind(this,t),e)}get loadedPackets(){return this.pieceMsg.attachments-(this.reverseOffset-this.forwardOffset-1)}_handleTimeout(t=!1,s=!0){if(this.destroyed||this.rangeRequesting)return;const{seg_id:i,size:r,attachments:n}=this.pieceMsg;if(!r||0===this.timeReceivePiece)return this.logger.warn(`syn load timeout ${i} url ${this.url}`),void this.emit(e.SYN_ERROR,this.pieceMsg,is);if(t&&this.timeReceivePiece>0&&n){this.logger.warn(`syn ${this.loadedPackets} of ${n} packets loaded`);const e=this.httpLoadTime>3e3?3e3:this.httpLoadTime;if(this.shouldWaitForRemain(e))return this.waitingRemain=!0,this.logger.info(`syn wait for remain ${e}`),void this._startTimer(e,!1)}if(s){const e=[this.forwardPeer,this.reversePeer].filter((e=>!!e)).sort(((e,t)=>{const s=e.currentLoadSpeed(),i=t.currentLoadSpeed();return s===i?e.timeSendRequest-t.timeSendRequest:s-i})).shift();e&&e.loadtimeout()}if((this.rangeSupported||!this.hasPartialBuffer)&&this.url)return this._cancelP2p(!0),this._loadRemainBufferByHttp();this._notifyStreamListenersAbort(),this.emit(e.SYN_ERROR,this.pieceMsg,os)}shouldWaitForRemain(e){return!this.isEmpty&&this.shouldWaitForRemainUrgent(e)}shouldWaitForRemainUrgent(e){if(0===this.timeReceivePiece||e<=0)return!1;const t=this.p2pSpeed,s=this.minRequiredSpeed(e);return this.logger.info(`syn remainTime ${e} speed ${t} required ${s}`),t>=s}minRequiredSpeed(e){let t=0;return[this.forwardPeer,this.reversePeer].forEach((e=>{e&&(t+=e.loadedBytes())})),(this.pieceMsg.size-t)/e}get p2pSpeed(){let e=0;return[this.forwardPeer,this.reversePeer].forEach((t=>{t&&(e+=t.currentLoadSpeed())})),e}getFromPeerId(){const{forwardPeer:e,reversePeer:t}=this;return this.isFull&&e!==t?`${e.remotePeerId}:${t.remotePeerId}`:e?`${e.remotePeerId}`:t?`${t.remotePeerId}`:""}getStreamInfo(e){const t=e?this.reverseBufList:this.forwardBufList;let s,i;return t.length0?this.rangeEnd-1:0;let n=this.forwardOffset;const o=performance.now();this.rangeRequesting=!0;let a=he(n,this.reverseOffset,t,this.rangeStart,r);const h=a.rangeEnd-a.rangeStart;i.info(`listeners ${this.streamListeners} continue download ${s} from ${this.url} range: ${a.rangeStart}-${a.rangeEnd}`),this.hasPartialBuffer||(a={});const c=new cs({xhrSetup:this.xhrSetup});this.httpLoader=c;let d={url:this.proxied?g(this.url,l,!0):this.url,...a};let u,f=n+1;const p={onUpdate:(t,s,r)=>{if(!this.destroyed){if(r)return i.warn("httpLoader aborted"),void(this.alreadyOutput||this.emit(e.SYN_ERROR,this.pieceMsg,rs));if(s){const e=u/(performance.now()-o);this.coordinator.addHttpSpeed(e),this.httpLoader=void 0}this.bufArr[f]||this._receivePacket(!1,f+1,t,!1),f++}},onBodyStart:(t,r)=>{if(0===r&&i.warn(`range request fileSize ${r}`),this.destroyed)return;const{size:n}=this.pieceMsg;if(u=t,t!==n||0!==r&&r!==n){let s=!1;r>0&&r!==n?(i.error(`onBodyStart fileSize ${r} != ${n}`),s=!0):t!==h&&(i.error(`onBodyStart size ${t} != expectedSize ${h}`),s=!0),s&&this.emit(e.SYN_ERROR,this.pieceMsg,rs)}else i.warn(`syn range request ${s} resp whole ts`),f=0},onError:t=>{this.destroyed||(i.error(`httpLoader error ${t.text}`),this.emit(e.SYN_ERROR,this.pieceMsg,rs))},onTimeout:()=>{this.destroyed||(i.warn("httpLoader timeout"),this.emit(e.SYN_ERROR,this.pieceMsg,ns))}};c.load(d,{timeout:15e3},p)}_print(){const{seg_id:e,sn:t}=this.pieceMsg;this.logger.info(`syn parallel loading ${e||t}`)}}class fs extends gs{constructor(e,s,i,r,n,o=!1,a){super(e,s,o,a),this.pieceMsg={event:t.DC_PIECE,sn:i,level:r,seg_id:n},a&&this.setExtra(a)}get segId(){return this.pieceMsg.seg_id}_notifyStreamListeners(e,t,s){const{sn:i,seg_id:r,attachments:n}=this.pieceMsg,o=e&&0===s||!e&&s===n-1,a=e?this.reverseStreamListeners:this.forwardStreamListeners;e?this.reverseBufList.push(t):this.forwardBufList.push(t),o&&(this.forwardBufList.push([...this.reverseBufList].reverse()),this.reverseBufList.push([...this.forwardBufList].reverse()));for(let e of a){const{handler:s}=e;s(i,r,!1,t,o)}o&&this._resetStreamListeners()}_validateMsg(e,t,s){return(!this.pieceMsg.seg_id||s===this.pieceMsg.seg_id)&&(e===this.pieceMsg.sn&&t===this.pieceMsg.level)}}class ps{constructor(){this.meanHttpSpeed=0,this.loaderHttpSpeed=0}addHttpSpeed(e){this.meanHttpSpeed=this._cal(this.meanHttpSpeed,e)}addLoaderHttpSpeed(e,t){t&&e&&(this.loaderHttpSpeed=this._cal(this.loaderHttpSpeed,t/e))}getMeanTimeToLoaded(e){return this.loaderHttpSpeed?e/this.loaderHttpSpeed:500}shouldSwitchToHttp(e,t,s,i,r){if(this.meanHttpSpeed<=0)return!1;if(s>=this.meanHttpSpeed)return!1;if(this.meanHttpSpeed*r>=e)return!1;return((r+t-performance.now())*this.meanHttpSpeed-e)/(this.meanHttpSpeed-s)*s{if(e.bitset&&t.sn>=0){const{sn:s,level:i,complete:r,seg_id:n,size:o}=t,a=r?Gt.COMPLETE:Gt.PARTIAL_FORWARD;e.bitset.add(s,i,n,a,o),this._receiveDCHave(s,i,n,e),e.isAvailableUrgently&&this._handleDCHave(e,s,i,n,o,a)}})).on(t.DC_HAVE_REVERSE,(t=>{if(e.bitset&&t.sn>=0){const{sn:s,level:i,seg_id:r,size:n}=t;e.bitset.hasCompleteOr(s,i,Gt.PARTIAL_REVERSE)||e.bitset.add(s,i,r,Gt.PARTIAL_REVERSE,n),this._receiveDCHave(s,i,r,e),e.isAvailableUrgently&&this._handleDCHave(e,s,i,r,n,Gt.PARTIAL_REVERSE)}})).on(t.DC_LOST,(t=>{if(!e.bitset)return;const{sn:s,level:i}=t;e.bitset.has(s,i)&&(e.bitset.delete(s,i),this.bitCounts.decre(s,i))})).on(t.DC_PIECE,(e=>{e.ext&&e.ext.incompletes>=7||this.requestingMap.has(de(e.sn,e.level))&&this.notifyAllPeers(e.sn,e.level,e.seg_id,e.size,e.reverse?Gt.PARTIAL_REVERSE:Gt.PARTIAL_FORWARD)})).on(t.DC_PIECE_CANCEL,(t=>{const{sn:s,level:i}=t,r=de(s,i);this.removeStreamListener(r,e.remotePeerId)})).on(t.DC_PIECE_NOT_FOUND,(t=>{const{sn:s,level:i}=t;e.bitset.delete(s,i),this.bitCounts.decre(s,i),e.checkIfNeedChoke(!0)})).on(t.DC_DISCONNECT,(()=>{this.cleanRequestingMap(e.remotePeerId)})).on(t.DC_REQUEST,(async t=>{const{logger:s}=this,{sn:i,level:r,reverse:n}=t;let o=t.seg_id;o||(o=await this.bufMgr.getSegIdBySN(i));const a=()=>{this.bitset.delete(i,r),e.sendPieceNotFound(i,o,{level:r}),this._broadcastLost(i,o,r,e)},h=await this.bufMgr.getSegById(o),l=de(i,r),c=this.requestingMap.get(l);let d=!1;c&&c.isDownloading&&(d=!0);const u=this.segmentBuilderMap.get(l);if(h)if(s.info(`found seg ${o} from bufMgr`),h.level===r){let t="SegmentStore"===this.bufMgr.name?"Disk":"Cache";h.ext.from&&h.ext.from.length<2500&&(t=`${h.ext.from}-${t}`),e.sendBuffer(h.sn,h.segId,h.data,{from:t,level:h.level,reverse:n,hash:h.ext.hash})}else a();else if(!n&&u)s.info(`peer request ${i} wait from builder, sent ${u.bufferList.length}`),I(e,u,u.pieceMsg,u.bufferList,u.source,1);else if(d){s.info(`syn had ${c.loadedPackets} packets, wait remain from upstream ${c.getFromPeerId()}`);const t={...c.pieceMsg,reverse:n},{from:i,incompletes:r,bufferList:o}=c.getStreamInfo(n);I(e,c,t,o,i,r)}else a()}))}handleMetaData(e,t){if(t.field){e.bitset=new Jt(this.config.live,t.field);for(let e in t.field){const s=Number(e);if(s<0)continue;t.field[s].forEach((e=>{this.bitset.has(e,s)||this.bitCounts.incre(e,s)}))}this.addPeer(e),this.downloadOnly&&this.chokePeerRequest(e)}}peersHas(e,t){return this.bitCounts.has(e,t)}deletePeer(e){if(this.peerManager.hasPeer(e.remotePeerId)&&e.bitset){const t=e.bitset.allArray();for(let e in t){const s=Number(e),i=t[s];i&&i.forEach((e=>{this.bitCounts.decre(e,s)}))}}this.cleanRequestingMap(e.remotePeerId),super.deletePeer(e)}hasAndSetTargetPeer(e,t,s,i){const{logger:r,config:n}=this;let o=1e3*(i-n.httpLoadTime);this.allowP2pLimit=n.httpLoadTime+1.5,r.info(`bufferedDuration ${1e3*i} remainLoadTime ${o} allowP2pLimit ${1e3*this.allowP2pLimit}`);const a=de(e,t),h=this.requestingMap.get(a);if(h){const n=h.segId;if(n&&n!==s)return r.warn(`syn segId ${n} not match ${s}`),this.requestingMap.delete(a),this._searchAvailablePeers(e,t,s,i);if(!h.shouldWaitForRemain(o)){if(r.warn(`syn prefetch timeout at ${e}`),h.prefetchTimeout=!0,h.isFull)return this.httpRangeSupported;const i=this.peerManager.getPeersOrderByWeight();let[n,a,l]=Xt(i,e,t,s);return!!this.setTargetPeersFromGroup(h,n,a,l)||(h.hasReversePeer||h.hasPartialBuffer||o>1e3*(this.allowP2pLimit+1))&&this.httpRangeSupported}return r.info(`prefetch ${e} wait for remain`),!0}return this._searchAvailablePeers(e,t,s,i)}_searchAvailablePeers(e,t,s,i){if(i<=this.allowP2pLimit)return!1;if(!this.hasIdlePeers||!this.peersHas(e,t))return!1;const r=this.peerManager.getPeersOrderByWeight(),[n,o]=Vt(r,e,t,s);return this.targetPeers={forwardPeer:n,reversePeer:o},[n,o].some((e=>!!e))}reportTraffic(e,t,s){const{fetcher:i}=this.engine;i&&(e>0&&i.reportFlow(e),t>0&&i.reportDCTraffic(t,s))}notifyAllPeers(e,t,s,i,r=Gt.COMPLETE){if(!s)return void this.logger.error("segId is required");if(this.downloadOnly)return;const{live:n}=this.config;if(this.bitset.has(e,t,r))return;const o=((e,t,s)=>`${e}-${t}-${s}`)(e,t,r);let a;r!==Gt.PARTIAL_REVERSE&&(a=r===Gt.COMPLETE);const h=this.requestingMap.get(de(e,t));for(let l of this.getPeers())h&&h.hasPeer(l)||l.notifySet.has(o)||l.bitset.hasCompleteOr(e,t,r)||l.uploading||(l.sendMsgHave(e,s,{level:t,reverse:r===Gt.PARTIAL_REVERSE,complete:a,size:i}),l.notifySet.add(o),n&&P(l.notifySet,20))}checkPeers(){const{logger:e,config:t,engine:s}=this;if(!this.hasPeers)return;const i=t.live;if(this.fragLoading)return void e.info("loading urgently, skip prefetch");const{currentLevel:r}=s;if(0===this.bitCounts.size(r))return;if(!i&&this.nextLostSN>=0&&this.nextLostSN>=this.currPlaySN-10)return;let n=this.peerManager.getPeersOrderByWeight();if(0===n.length)return;let o=0,{prefetchNum:a,endSN:h,startSN:l}=t;if(!i){const t=this.requestingMap.size,s=this.requestingMap.activePeers;if(s>=a)return void e.warn(`requestingMap size ${t} activePeers ${s}`);a-=s}if(this.getBufferedDuration()=h&&!this.bufMgr.overflowed)d=l;else{const e=Math.min(...n.filter((e=>e.endSN>=d)).map((e=>e?e.startSN:1/0)));if(!isFinite(e))return;dh))&&!(i&&d>this.loadingSN+2);){if(this.bitset.has(d,r)){d++;continue}const t=de(d,r),s=this.requestingMap.get(t);if(this.bitCounts.has(d,r)){if(s){for(let e of n)if(e.bitset.has(d,r)){const{state:t,segId:i,size:n}=e.bitset.getObj(d,r);if(this._trySetPeerForSyn(s,e,i,d,r,n,t))break}}else{let s=[null,null];if(i)s=Vt(n,d,r,void 0,!0);else for(let e of n)if(e.bitset.has(d,r)){const t=e.bitset.getState(d,r);let i;i=t===Gt.COMPLETE?0===p(0,1):t===Gt.PARTIAL_REVERSE,s[i?1:0]=e;break}if(s.some((e=>!!e))){const i=new fs(this.coordinator,this.logger,d,r,void 0,this.httpRangeSupported);this._setupSynthesizer(i),this.requestingMap.set(t,i),s.forEach(((t,s)=>{if(t&&o{for(let s of this.getPeers()){const i=s.getLatestPlaylist(e,t);if(i)return this.playlistInfo.set(e,i),this.gotPlaylist=!0,i}return null};let r=i();return!r&&this.gotPlaylist&&(this.logger.info("getPlaylist wait 240ms"),await m(240),this.gotPlaylist=!1,r=i()),r}getBufferedDuration(){const{config:e}=this;let{media:t,currentSrc:s}=this.engine;if(!t||t.src!==s&&0===t.currentTime){if(this.logger.info("try get video element"),t=oe(this.config.mediaElem,s),!t)return 4;this.engine.media=t}let i=function(e){let t=0,s=e.currentTime,i=e.buffered;for(let e=i.length-1;e>=0;e--)if(s>=i.start(e)&&s<=i.end(e)){t=i.end(e)-s;break}return e.playbackRate&&(t/=e.playbackRate),t>0?t:0}(t);return i}destroy(){super.destroy(),this.requestingMap.clear(),this.segmentBuilderMap.clear(),this.engine.removeAllListeners(t.MEDIA_REBUFFER)}clearCache(){"SegmentStore"===this.bufMgr.name?this.engine.emit(t.BM_FATAL_ERROR):this.bufMgr.clear(),this.bitset.clear()}async _handleSynOutput(e,t,s,i,r,n){if(this.logger.info(`syn output ${e} http ${t} p2p ${s} time ${i}`),!this.config.validateSegment(e,new Uint8Array(r)))return!1;if(n){const t=await D(r);if(t&&t!==n)return this.logger.warn(`${e} computedHash ${t} != hash ${n}`),!1}return!0}_handleSynError(e,t,s,i){const{logger:r,config:n}=this;r.warn(`SYN_ERROR ${t}-${s} code ${i}`),i!==is&&e.hasPartialBuffer&&s>this.loadingSN?r.warn(`syn abort ${s} with partial buffer`):this.requestingMap.delete(de(s,t)),n.live&&this.checkPeers()}_notifySynthesizer(e,t,s,i,r,n,o=!0){const a=this.requestingMap.get(de(s,i));a&&this._trySetPeerForSyn(a,e,t,s,i,r,n,o)}_trySetPeerForSyn(e,t,s,i,r,n,o,a=!1){const{logger:h}=this,l=e.segId;if(s&&l&&s!==l)return h.warn(`notifySynthesizer segId ${s} not match ${l}`),!1;if(e.isFull)return!0;if(e.isAlmostDeadline)return!0;if(e.isEmpty){if(e.hasForwardBuffer&&u()){if(e.setReversePeer(t,n))return c(!0,a),!0}else if(e.hasReverseBuffer&&d()&&e.setForwardPeer(t,n))return c(!1,a),!0}else if(!e.hasForwardPeer&&d()){if(e.setForwardPeer(t,n))return c(!1,a),!0}else if(!e.hasReversePeer&&u()&&e.setReversePeer(t,n))return c(!0,a),!0;function c(e,n){n?t.requestDataById(s,i,!0,{level:r,reverse:e}):t.requestDataBySN(i,!1,{level:r,reverse:e})}function d(){return o===Gt.PARTIAL_FORWARD||o===Gt.COMPLETE}function u(){return o===Gt.PARTIAL_REVERSE||o===Gt.COMPLETE}return!1}_setupEngine(){this.engine.on(t.MEDIA_REBUFFER,(e=>{const{prefetchOnly:t,live:s}=this.config;t||s||(e&&!this.prefetchOnly&&this.logger.warn("rebuffer reach limit"),this.prefetchOnly=e)}))}getStatsForPeer(){const{currentLevel:e,media:t}=this.engine,s={level:e};if(t&&!this.config.live){const{currentTime:e}=t;s.pos=Math.round(e)}return s}checkSynthesizer(e,t){const s=de(e,t),i=this.requestingMap.get(s);i&&(0===i.streamListeners?(this.logger.info(`destroy syn ${s} without listeners`),this.requestingMap.delete(s)):this.logger.info(`keep syn ${s} with listeners`))}setupSynForLoad(e,t,s,i,r){const{forwardPeer:n,reversePeer:o}=this.targetPeers,a=de(e,t);let h=this.requestingMap.get(a);if(h?h.setExtra(i):(h=new fs(this.coordinator,this.logger,e,t,s,this.httpRangeSupported,i),this._setupSynthesizer(h),this.requestingMap.set(a,h)),h.prefetchTimeout&&r<1e3*this.allowP2pLimit&&!n&&!o)return h.setTimeout(0);r>700&&(n&&h.setForwardPeer(n)&&n.requestDataById(s,e,!0,{level:t}),o&&h.setReversePeer(o)&&o.requestDataById(s,e,!0,{level:t,reverse:!0})),h.setTimeout(h.isEmpty?0:r,!0)}async disconnectLoadingPeer(e){let t=e;if(!t){const e=await this.bufMgr.getSegById(this.loadingSegId);e&&e.fromPeerId&&(t=e.fromPeerId)}t&&(this.logger.warn(`disconnect loading peer ${t}`),t.split(":").forEach((e=>{const t=this.peerManager.getPeer(e);t&&t.close(!0)})))}}class _s{constructor(t,s,i,r){this.bufferList=[],this.streamListeners=[],this.finished=!1,this.packetSize=c,this.attachments=r%this.packetSize==0?r/this.packetSize:Math.floor(r/this.packetSize)+1,this.pieceMsg={event:e.DC_PIECE,attachments:this.attachments,seg_id:i,sn:t,level:s,size:r,reverse:!1},this.sink=(0,o.h)(0),this.source="HttpStream"}receiveBytes(e,t){e.byteLength&&(this.sink=o.h.concat([this.sink,e]),this.bufferList.push(e),t&&(this.finished=!0),this._notifyStreamListeners(e))}getCompleteBuffer(){return this.sink.buffer}destroy(){this.finished||this._notifyStreamListenersAbort()}addStreamListener(e,t,s){this.streamListeners.push({handler:s,peerId:t})}removeStreamListener(e){const{sn:t,seg_id:s}=this.pieceMsg;this.streamListeners=this.streamListeners.filter((i=>i.peerId!==e||(i.handler(t,s,!0,"aborted by cancel"),!1)))}_notifyStreamListenersAbort(){const{sn:e,seg_id:t}=this.pieceMsg;for(let s of this.streamListeners){const{handler:i}=s;i(e,t,!0,"aborted by httpLoader")}this.streamListeners.length=0}_notifyStreamListeners(e){const{sn:t,seg_id:s}=this.pieceMsg;for(let i of this.streamListeners){const{handler:r}=i;r(t,s,!1,e,this.finished)}this.finished&&(this.streamListeners.length=0)}}const Ss=/^age:\s*[\d.]+\s*$/im;function ys(e,t,s,i){if(!e)return!1;const r=i&&i.code,n=t499)}(r)||!!s);return e.shouldRetry?e.shouldRetry(e,t,s,i,n):n}const vs=class{constructor(e){this.xhrSetup=e&&e.xhrSetup||null,this.stats=A(),this.retryDelay=0,this.config=null,this.callbacks=null,this.context=null,this.loader=null}destroy(){this.callbacks=null,this.abortInternal(),this.loader=null,this.config=null,this.context=null,this.xhrSetup=null}abortInternal(){const e=this.loader;self.clearTimeout(this.requestTimeout),self.clearTimeout(this.retryTimeout),e&&(e.onreadystatechange=null,e.onprogress=null,4!==e.readyState&&(this.stats.aborted=!0,e.abort()))}abort(){this.abortInternal(),this.callbacks&&this.callbacks.onAbort&&this.callbacks.onAbort(this.stats,this.context,this.loader)}load(e,t,s){this.context=e,this.config=t,this.callbacks=s,this.loadInternal()}loadInternal(){const{config:e,context:t}=this;if(!e||!t)return;const s=this.loader=new self.XMLHttpRequest,i=this.stats;i.loading.first=0,i.loaded=0,i.aborted=!1;const r=this.xhrSetup;r?Promise.resolve().then((()=>{if(this.loader===s&&!this.stats.aborted)return r(s,t.url)})).catch((e=>{if(this.loader===s&&!this.stats.aborted)return s.open("GET",t.url,!0),r(s,t.url)})).then((()=>{this.loader!==s||this.stats.aborted||this.openAndSendXhr(s,t,e)})).catch((e=>{this.callbacks.onError({code:s.status,text:e.message},t,s,i)})):this.openAndSendXhr(s,t,e)}openAndSendXhr(e,t,s){e.readyState||e.open("GET",t.url,!0);const i=t.headers,{maxTimeToFirstByteMs:r,maxLoadTimeMs:n}=s.loadPolicy;if(i)for(const t in i)e.setRequestHeader(t,i[t]);t.rangeEnd&&e.setRequestHeader("Range","bytes="+t.rangeStart+"-"+(t.rangeEnd-1)),e.onreadystatechange=this.readystatechange.bind(this),e.onprogress=this.loadprogress.bind(this),e.responseType=t.responseType,self.clearTimeout(this.requestTimeout),s.timeout=r&&Number.isFinite(r)?r:n,this.requestTimeout=self.setTimeout(this.loadtimeout.bind(this),s.timeout),e.send()}readystatechange(){const{context:e,loader:t,stats:s}=this;if(!e||!t)return;const i=t.readyState,r=this.config;if(!s.aborted&&i>=2&&(0===s.loading.first&&(s.loading.first=Math.max(self.performance.now(),s.loading.start),r.timeout!==r.loadPolicy.maxLoadTimeMs&&(self.clearTimeout(this.requestTimeout),r.timeout=r.loadPolicy.maxLoadTimeMs,this.requestTimeout=self.setTimeout(this.loadtimeout.bind(this),r.loadPolicy.maxLoadTimeMs-(s.loading.first-s.loading.start)))),4===i)){self.clearTimeout(this.requestTimeout),t.onreadystatechange=null,t.onprogress=null;const i=t.status,n="text"===t.responseType?t.responseText:null;if(i>=200&&i<300){const r=n||t.response;if(null!=r){s.loading.end=Math.max(self.performance.now(),s.loading.first);const n="arraybuffer"===t.responseType?r.byteLength:r.length;if(s.loaded=s.total=n,s.bwEstimate=8e3*s.total/(s.loading.end-s.loading.first),!this.callbacks)return;const o=this.callbacks.onProgress;if(o&&o(s,e,r,t),!this.callbacks)return;const a={url:t.responseURL,data:r,code:i};return void this.callbacks.onSuccess(a,s,e,t)}}const o=r.loadPolicy.errorRetry;ys(o,s.retry,!1,{url:e.url,data:void 0,code:i})?this.retry(o):this.callbacks.onError({code:i,text:t.statusText},e,t,s)}}loadtimeout(){if(!this.config)return;const e=this.config.loadPolicy.timeoutRetry;if(ys(e,this.stats.retry,!0))this.retry(e);else{const e=this.callbacks;e&&(this.abortInternal(),e.onTimeout(this.stats,this.context,this.loader))}}retry(e){const{context:t,stats:s}=this;this.retryDelay=function(e,t){const s="linear"===e.backoff?1:Math.pow(2,t);return Math.min(s*e.retryDelayMs,e.maxRetryDelayMs)}(e,s.retry),s.retry++,this.abortInternal(),this.loader=null,self.clearTimeout(this.retryTimeout),this.retryTimeout=self.setTimeout(this.loadInternal.bind(this),this.retryDelay)}loadprogress(e){const t=this.stats;t.loaded=e.loaded,e.lengthComputable&&(t.total=e.total)}getCacheAge(){let e=null;if(this.loader&&Ss.test(this.loader.getAllResponseHeaders())){const t=this.loader.getResponseHeader("age");e=t?parseFloat(t):null}return e}getResponseHeader(e){return this.loader&&new RegExp(`^${e}:\\s*[\\d.]+\\s*$`,"im").test(this.loader.getAllResponseHeaders())?this.loader.getResponseHeader(e):null}};const Ps=class extends ms{constructor(e,t){super(e,t),this.fragloadTimeout=e.hlsjs?10:6.8,this.resolveMap=new Map,this.segmentBypass=T(t.segmentBypass)?t.segmentBypass:()=>!1,!0===t.httpStreamEnabled?this.streamEnabled=ls()&&t.live:this.streamEnabled=!1}async handleGetMediaData(e,s){const{logger:i,engine:r,config:n}=this;let{url:o,range:a}=e;const h=this._getFrag(o,a);if(!h)return i.warn(`cannot get frag ${o}`),s.postMessage({action:t.SW_GET_MEDIA});r.currentLevelIndex=h.level;const{sn:l,level:c}=h,d=this.config.segmentId(String(c),l,o,a);if(r.segmentLoadCount++,this.segmentBypass(o,h.tagList))return i.info(`bypass frag ${o}`),s.postMessage({action:t.SW_GET_MEDIA});if(r.segmentLoadCountthis.fragloadTimeout&&(f=this.fragloadTimeout),i.info(`handleGetMediaData sn ${l} bufferedDuration ${f}`);let p=1e3*(f-this.config.httpLoadTime);p<0?p=0:p>4e3&&(p=4e3);const m=de(l,c);if(this.resolveMap.has(l)||u){let e=this.requestingMap.get(m);if(e||u){e&&this.httpRangeSupported&&(i.warn(`${l} is requesting, terminate syn wait for seg`),e.terminate());let r=setTimeout((()=>{i.info(`notify seg ${l} timeout`),r=-1,s.postMessage({action:t.SW_GET_MEDIA})}),p);this.bufMgr.once(`${t.BM_ADDED_SN_}${l}`,(e=>{r<0||e&&e.level===c&&(clearTimeout(r),i.info(`notify seg ${e.sn}`),s.postMessage({action:t.SW_GET_MEDIA,data:{url:o,buffer:e.data}}))}))}else i.warn(`${l} is requesting, fallback`),s.postMessage({action:t.SW_GET_MEDIA})}else if(this.hasAndSetTargetPeer(l,c,d,f)){await this._loadFragByP2p(h,s,l,d,o,c,a,p)||(i.warn(`p2p timeout switch to http load ${d}`),this._loadFragByHttp(h,s,d,o,a,1e3*this.fragloadTimeout))}else this._loadFragByHttp(h,s,d,o,a,1e3*this.fragloadTimeout)}_loadFragByHttp(e,s,i,r,n,o,a=!0){const{sn:h,level:c}=e,d=de(h,c),u=g(r,l,!0),f={},p=this.streamEnabled&&a?new cs(f):new vs(f);let m={url:u,responseType:"arraybuffer",...b(n)};const _={timeout:o,loadPolicy:{maxTimeToFirstByteMs:8e3,maxLoadTimeMs:2e4}},y={onError:e=>{e.text&&this.logger.warn(e.text),this.fragLoading=!1,s.postMessage({action:t.SW_GET_MEDIA})},onTimeout:()=>{this.logger.warn("http load timeout"),this.fragLoading=!1,s.postMessage({action:t.SW_GET_MEDIA})},onSuccess:async(n,o)=>{this.fragLoading=!1;const{data:a}=n;let l=o.loading.end-o.loading.start;if(this.logger.info(`HTTP loaded ${i} time ${l} speed ${a.byteLength/l}`),!await this.bufMgr.hasSegOfId(i)){const e=S(a).buffer,t=new J(h,i,e,"",c);await this.bufMgr.putSeg(t),this.reportTraffic(a.byteLength,0,0)}this.segmentBuilderMap.delete(d),e.segId=i,e.loaded=a.byteLength,this.engine.emit(t.FRAG_LOADED,{url:r,sn:h,level:c,segId:i,loaded:e.loaded,duration:e.duration,byP2p:!1}),this._onFragLoaded(),s.postMessage({action:t.SW_GET_MEDIA,data:{url:r,buffer:a}})}};if(this.streamEnabled&&a){let e;y.onBodyStart=t=>{!e&&t>0&&(this.notifyAllPeers(h,c,i,t,Gt.PARTIAL_FORWARD),e=new _s(h,c,i,t),this.segmentBuilderMap.has(d)||this.segmentBuilderMap.set(d,e))},y.onUpdate=(t,s,r)=>{if(r)return this.logger.warn(`loadFragByHttp ${i} aborted`),void this.segmentBuilderMap.delete(d);e&&e.receiveBytes(t,s)}}p.load(m,_,y)}async _loadFragByP2p(e,s,i,r,n,o,a,h){const{logger:l}=this;l.info(`p2p load sn ${i} segId ${r} level ${o}`);const c=await this.load(i,r,o,n,a,h);if(c&&c.data){const{data:a,fromPeerId:h,size:d}=c;if(l.info(`p2p loaded segId ${r} level ${o} size ${a.byteLength}`),!await this.bufMgr.hasSegOfId(r)){const e=new J(i,r,a,h,o,c.ext);l.info(`bufMgr putSeg ${i} level ${o}`),await this.bufMgr.putSeg(e)}return e.loaded=a.byteLength,e.fromPeerId=h,this.engine.emit(t.FRAG_LOADED,{url:n,sn:i,level:o,segId:r,loaded:e.loaded,duration:e.duration,byP2p:!0,fromPeerId:h}),this._onFragLoaded(),s.postMessage({action:t.SW_GET_MEDIA,data:{url:n,buffer:a,size:d}}),!0}l.warn(`P2P timeout load segId ${r}`);const d=await this.bufMgr.getSegById(r);return!!d&&(this.fragLoading=!1,l.info(`already loaded seg sn ${i} segId ${r}`),s.postMessage({action:t.SW_GET_MEDIA,data:{url:n,buffer:d.data}}),!0)}notifySWMessage(e,s,i){if(e===t.SW_GET_MEDIA)this.engine.fetcher&&this.engine.fetcher.increMediaRequests(),this.handleGetMediaData(s,i);else this.logger.warn(`unknown action ${e}`)}_getFrag(e,t){return t&&(e=`${e}|${t}`),this.fragMap.get(e)}destroy(){super.destroy(),this.logger.warn("destroy HlsSwScheduler")}_onFragLoaded(){if(!this.engine)return;const{media:e,targetDuration:t}=this.engine;!this.config.live&&e&&t&&(this.currPlaySN=Math.ceil(e.currentTime/t))}load(e,t,s,i,r,n){const{logger:o,config:a}=this;let h={...b(r),proxied:!0,url:i,segId:t,httpLoadTime:1e3*a.httpLoadTime};this.setupSynForLoad(e,s,t,h,n);const l=new Promise((i=>{const r={resolve:i,sn:e,level:s,segId:t};this.resolveMap.set(e,r)}));return this.targetPeers={},l}isCritical(){return this.resolveMap.has(this.loadingSN)}_setupSynthesizer(e){e.on(t.SYN_OUTPUT,(async(t,s)=>{const{config:i,logger:r}=this,{segId:n,sn:o,data:a,level:h,ext:l}=t,{speed:c,time:d,http:u,p2p:g}=s,f=this.resolveMap.has(o);f&&(this.fragLoading=!1);const p=await this._handleSynOutput(n,u,g,d,a,l.hash),m=e.getFromPeerId();if(p)if(this.bitset.has(o,h)||this.reportTraffic(u,g,c),f){r.info(`receive criticalSeg seg_id ${n}`);const e=this.resolveMap.get(o);this.resolveMap.delete(o),e.resolve({data:a,fromPeerId:g>0?m:void 0,ext:l})}else this.bitset.has(o,h)||(e.detachPeers(),await this.bufMgr.putSeg(t));else{if(r.error(`segment ${n} validate failed`),f){const e=this.resolveMap.get(o);this.resolveMap.delete(o),e.resolve()}this.requestingMap.delete(de(o,h)),this.disconnectLoadingPeer(m)}})).on(t.SYN_ERROR,((t,s)=>{const{sn:i,level:r}=t;if(this.resolveMap.has(i)){const e=this.resolveMap.get(i);this.resolveMap.delete(i),e.resolve()}this._handleSynError(e,r,i,s)}))}_handleDCHave(e,t,s,i,r,n){this._notifySynthesizer(e,i,t,s,r,n,this.resolveMap.has(t)),this.config.live&&j((()=>{this.checkPeers()}))}},Es="2.13.0";class bs extends At{static get name(){return"HlsSwP2pEngine"}static isServiceWorkerSupported(){return"serviceWorker"in navigator}constructor(e={},s=null){super(e,s),this.swSupported=self.isSecureContext,this.levels=[],this.bypassLevels=[],this.currentLevelIndex=0,this.currentSrc="",this.swVersion="",this.media=oe(this.config.mediaElem),this.workerKeepAliveInterval=null,this.fragMap=new Map,this.engineName=bs.name,bs.isServiceWorkerSupported()||(this.swSupported=!1,console.warn("service worker is not supported")),s&&(s.once("hlsDestroying",(()=>{this.destroy(),this.hlsjs=null})),s.on(this.HLSEvents.ERROR,this._onHlsError.bind(this)));const{channelIdMaker:i,signalId:r,browserInfo:n}=this.setup();if(this.onLevelLoaded=e=>{const{config:s}=this,o=e.live;s.live=o,this.segmentLoadCount=0,this.targetDuration=e.averagetargetduration,this.browserInfo={...n,live:o,abr:this.multiBitrate||void 0,type:"hls_sw"},this.channel=`${i(this.currentSrc)}|${r}[${ee.VERSION}]`,this.setupElectron();const a=this.initLogger();a.info("use HlsSwP2pEngine"),a.info(`engine version: ${re.version} hls-proxy version: ${this.swVersion}`),a.info(`channel ${this.channel}`),o||(s.startSN=e.startSN,s.endSN=e.endSN,a.info(`startSN ${e.startSN} endSN ${e.endSN}`)),this._init(this.channel,this.browserInfo),this.off(t.LEVEL_LOADED,this.onLevelLoaded)},0===this.config.httpLoadTime&&(this.config.live?this.on(t.LEVEL_LOADED,(e=>{const{fragments:t,averagetargetduration:s,startSN:i}=e;this.config.httpLoadTime=this.determineHttpLoadTime(t,s,i)})):this.config.httpLoadTime=3.5),this.on(t.LEVEL_LOADED,this.onLevelLoaded),this.onManifestParsed=(e,s)=>{this.multiBitrate=e.length>1,this.currentSrc=s,this.off(t.MANIFEST_PARSED,this.onManifestParsed)},this.on(t.MANIFEST_PARSED,this.onManifestParsed),this.onFragLoaded=({url:e})=>{this.curTsUri=e;const{config:t}=this;!this.rangeTested&&t.useHttpRange&&(this.startRangeRequestTimer(),this.rangeTested=!0,t.logger&&t.logger.info(JSON.stringify({engine:this.engineName,...this.browserInfo}))),this.segmentLoadCount>=t.startFromSegmentOffset&&this.resumeTracker()},this.on(t.FRAG_LOADED,this.onFragLoaded),this.swSupported){const{serviceWorker:e}=navigator;e.onmessage=e=>{const{action:s,data:i}=e.data;if(!s)return;if(s===t.SW_DEBUG){const{level:e,text:t}=i;return void(this.logger&&this.logger[e](`hls-proxy ${this.swVersion}: ${t}`))}const r=e.ports[0];if(r){if(this.logger&&this.logger.info(`engine onmessage action ${s}`),r.postMessage({action:s,pong:!0}),!this.p2pEnabled||!i)return r.postMessage({action:s});if(s===t.SW_GET_PLAYLIST)this.handleGetPlaylist(i,r);else{if(!this.scheduler)return r.postMessage({action:s});this.scheduler.notifySWMessage(s,i,r)}}else this.logger&&this.logger.error(`sender not found in action ${s}`)}}this.config.swAutoRegister&&this.registerServiceWorker().then((function(e){})).catch((e=>{console.warn("ServiceWorker registration failed ",e)}))}get currentLevel(){return this.currentLevelIndex}watchRebuffering(e){this.offEventRebuffer=function(e,t){let s=null;const i=()=>{s||(s=setTimeout((()=>{t()}),2500))},r=()=>{null!=s&&(clearTimeout(s),s=null)};return e.addEventListener("waiting",i),e.addEventListener("playing",r),()=>{e.removeEventListener("waiting",i),e.removeEventListener("playing",r)}}(e,(()=>{this.fetcher&&this.fetcher.increRebuffers()}))}handlePlaylist(e,s,i=!1){const{config:r,logger:n}=this,{url:o,redirectedUrl:a,text:h,ver:c}=e;return this.swVersion=c,-1===function(e,t){for(var s=e.split("."),i=t.split("."),r=0;ro)return 1}return 0}(c,Es)?(console.warn(`hls-proxy.js version should >= ${Es}`),s.postMessage({action:t.SW_GET_PLAYLIST})):this.bypassLevels.indexOf(w(o))>=0?(console.warn("bypass audio track"),n&&n.warn("bypass audio track"),s.postMessage({action:t.SW_GET_PLAYLIST})):(s.postMessage({action:t.SW_GET_PLAYLIST,data:{active:!0,debug:n&&n.isDebugLevel,text:h,redirectedUrl:a}}),this._parsePlaylist(h,w(o),a,i),void(this.workerKeepAliveInterval||navigator.serviceWorker.getRegistration().then((e=>{const t=()=>e&&e.active&&"activated"===e.active.state;if(!r.live&&t()){const s=new URL(e.scope);this.pathname=s.pathname+l;const i=e=>{clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null;const t=`keep alive failed ${e}`;n&&(n.error(t),n.report(t,"SWKeepAlive",this.peerId,"2.15.5"))};this.workerKeepAliveInterval=setInterval((()=>{var e;t()?(e=this.pathname,new Promise(((t,s)=>{fetch(`${e}/keepalive/`).then((e=>{if(e.ok)return e.text();throw new Error("keepalive failed")})).then((e=>{if(""!==e.trim())throw new Error("not valid keepalive response");t()})).catch((e=>{s(e)}))}))).catch((e=>{i(e)})):i("sw not activated`")}),15e3)}}))))}_parsePlaylist(e,s,i,r=!1){const n=s;i&&(s=i);const{config:o,logger:a}=this;if(e.indexOf("#EXTINF:")>0||e.indexOf("#EXT-X-TARGETDURATION:")>0){let i=0;const a=Ht.parseLevelPlaylist(e,s);this.levels.length>0?(i=this.levels.indexOf(w(a.url)),-1===i?(this.restartP2p(),this.currentSrc=n,i=0):this.currentLevelIndex=i):(""!==this.currentSrc&&n!==this.currentSrc&&this.restartP2p(),this.currentSrc=n,this.levels=[w(s)]),this.emit(t.LEVEL_LOADED,a),o.live&&v(this.fragMap,200),a.fragments.forEach((e=>{e.level=i;let t=h().buildAbsoluteURL(e.baseurl,e.relurl,{alwaysNormalize:!0});const s=e.byteRange;2===s.length&&(t=`${t}|bytes=${s[0]}-${s[1]-1}`),this.fragMap.set(t,e)})),!r&&o.sharePlaylist&&this.scheduler&&!this.scheduler.isMobileNet&&this.scheduler.broadcastPlaylist(w(s),e)}else{const i=Ht.parseMasterPlaylist(e,s);""!==this.currentSrc&&this.restartP2p(),i.length>0&&(i.sort(((e,t)=>e.bitrate-t.bitrate)),this.levels=i.map((e=>w(e.url))),["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((t=>{Ht.parseMasterPlaylistMedia(e,s,t).forEach((e=>{e.url&&this.bypassLevels.push(w(e.url))}))}))),this.emit(t.MANIFEST_PARSED,i,n)}this._setupSegmentId()}async handleGetPlaylist(e,s){const{config:i,logger:r,scheduler:n}=this,{url:o}=e,a=w(o);if(n&&n.playlistInfo.has(a)){const t=await n.getPlaylistFromPeer(a);if(t&&t.data){const{data:i,seq:n}=t;return r&&r.info(`got playlist from peer seq ${n}`),void this.handlePlaylist({text:i,...e},s,!0)}}try{const{text:i,redirectedUrl:n}=await this._loadPlaylistByHttp(o);if(!function(e){return 0===e.indexOf("#EXTM3U")}(i))return r&&r.warn(`not m3u8: ${i}`),s.postMessage({action:t.SW_GET_PLAYLIST});this.handlePlaylist({text:i,redirectedUrl:n,...e},s)}catch(e){s.postMessage({action:t.SW_GET_PLAYLIST})}}async registerServiceWorker(){const{logger:e,config:t}=this;if(!this.swSupported){let e="sw is not supported";return y||(e="https is required when using ServiceWorker",console.warn(e)),Promise.reject(e)}return this.media=oe(t.mediaElem),this.media||e&&e.warn("no video element found"),Ds.registerServiceWorker(t)}async unregisterServiceWorker(){clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null;const e="serviceWorker is not registered";return new Promise(((t,s)=>{const{serviceWorker:i}=navigator;i||s(e),i.getRegistration().then((i=>{i?i.unregister().then(t).catch(s):s(e)}))}))}async _init(e,t){const{logger:s,config:i}=this;if(!this.p2pEnabled||"object"!=typeof self)return;this.mediaTimer=setInterval((()=>{const e=()=>this.hlsjs&&this.hlsjs.media;if(this.media){const t=e();t&&this.media!==t&&(this.media=t),clearInterval(this.mediaTimer),this.rubufferTimer=setTimeout((()=>{this.watchRebuffering(this.media)}),15e3)}else this.media=e()||oe(i.mediaElem)}),3e3);let r=new Ps(this,i);r.fragMap=this.fragMap;try{await super._init(e,r,t)}catch(e){return void(s&&s.error(e))}r.server=this.fetcher,this.scheduler=r}restartP2p(){this.logger&&this.logger.warn("restart P2P"),this.disableP2P(),this.enableP2P(),this.on(t.LEVEL_LOADED,this.onLevelLoaded),this.on(t.MANIFEST_PARSED,this.onManifestParsed),this.on(t.FRAG_LOADED,this.onFragLoaded)}enableP2P(){return this.p2pEnabled?null:(this.logger&&this.logger.info("enable P2P"),this.config.p2pEnabled=this.p2pEnabled=!0,this)}disableP2P(){this.logger&&this.logger.warn("disable P2P"),clearInterval(this.mediaTimer),clearTimeout(this.rubufferTimer),this.offEventRebuffer&&this.offEventRebuffer(),this.p2pEnabled&&(this.config.p2pEnabled=this.p2pEnabled=!1,this.tracker&&this.tracker instanceof Rt&&(this.tracker.stopP2P(),this.tracker=null,this.fetcher=null,this.bufMgr.destroy(),this.bufMgr=null,this.trackerTried=!1)),this.levels=[],this.currentLevelIndex=0,this.lastLevel=0,this.multiBitrate=!1,this.rangeTested=!1,this.currentSrc="",this.media=void 0,this.config.live=!1,this.removeAllListeners(t.MANIFEST_PARSED),this.removeAllListeners(t.LEVEL_LOADED),this.removeAllListeners(t.FRAG_LOADED),clearInterval(this.workerKeepAliveInterval),this.workerKeepAliveInterval=null}destroy(){this.swSupported&&(navigator.serviceWorker.onmessage=void 0),super.destroy()}async _loadPlaylistByHttp(e){const t=g(e,l,!0),s=await fetch(t);return{text:await s.text(),redirectedUrl:s.redirected?s.url:void 0}}}const ws=bs;function Cs(e,t,s="main"){return"main"!==s}function Ts(e,t,s){let i,r,n;const o=performance.now();n=o,r=s?n-s.getMeanTimeToLoaded(t):o-200,i=r-100,e.trequest=i,e.tfirst=r,e.tload=n,e.loading={first:i,start:r,end:n},e.loaded=t,e.total=t}const Is=class extends ms{constructor(e,t){super(e,t),this.isHlsjs=!0,this.waitingPeers=0,this.waitingSeg={},this.requestedSet=new Set}updatePlaySN(e){this.currPlaySN=e}load(e,t,s){const{logger:i,config:r}=this;this.context=e;const{rangeStart:n,rangeEnd:o,url:a}=e,h=e.frag,{segId:l,sn:c,level:d}=h;this.callbacks=s,this.criticalSeg={sn:c,level:d,segId:l};let u=e.defaultTimeout-1e3*r.httpLoadTime;const g={rangeStart:Number(n),rangeEnd:Number(o),url:a,httpLoadTime:1e3*r.httpLoadTime,xhrSetup:r.xhrSetup,segId:l,headers:Object.keys(e.headers||{}).length>0?e.headers:void 0};this.setupSynForLoad(c,d,l,g,u),this.targetPeers={}}isCritical(){return!(!this.criticalSeg||this.criticalSeg.segId!==this.loadingSegId)}addPeer(e){super.addPeer(e)}destroy(){super.destroy(),this.logger.warn("destroy HlsjsScheduler")}_setupDC(e){super._setupDC(e)}_setupSynthesizer(e){e.on(t.SYN_OUTPUT,(async(t,s)=>{const{config:i,logger:r}=this,{segId:n,sn:o,data:a,level:h,ext:l}=t,{speed:c,time:d,http:u,p2p:g}=s,f=this.criticalSeg&&this.criticalSeg.segId===n,p=await this._handleSynOutput(n,u,g,d,a,l.hash),m=e.getFromPeerId();if(p)if(this.bitset.has(o,h)||this.reportTraffic(u,g,c),f&&this.callbacks){r.info(`receive criticalSeg seg_id ${n}`),this.criticalSeg=null;const{frag:e}=this.context;g>0&&(e.fromPeerId=m,e.loadByP2P=!0),this.callbacks.onSuccess({data:a,url:this.context.url},{},{...this.context,ext:l}),this.callbacks=void 0}else this.bitset.has(o,h)||(e.detachPeers(),await this.bufMgr.putSeg(t));else r.error(`segment ${n} validate failed`),f&&this.callbacks.onTimeout({},this.context,null),this.requestingMap.delete(de(o,h)),this.disconnectLoadingPeer(m)})).on(t.SYN_ERROR,((t,s)=>{const{sn:i,level:r}=t;this.criticalSeg&&this.criticalSeg.sn===i&&(this.criticalSeg=null,this.callbacks.onTimeout({},this.context,null)),this._handleSynError(e,r,i,s)})).on(t.SYN_PROGRESS,(({total:e,loaded:t,first:s,segId:i})=>{this.criticalSeg&&this.criticalSeg.segId===i&&this.callbacks&&this.callbacks.onLoaded&&this.callbacks.onLoaded({total:e,loaded:t,first:s},this.context)}))}_setupEngine(){super._setupEngine(),this.engine.on(t.FRAG_LOADING,(({sn:e,segId:t,byHttp:s,level:i})=>{this.loadingSN=e,this.loadingSegId=t,this.fragLoading=!0,s&&this.checkSynthesizer(e,i)})).on(t.FRAG_LOADED,(({sn:e,segId:t,byP2p:s,level:i})=>{this.fragLoading=!1,s||this.checkSynthesizer(e,i)})).on(t.FRAG_CHANGED,(({sn:e})=>{this.updatePlaySN(e)}))}_handleDCHave(e,t,s,i,r,n){this._notifySynthesizer(e,i,t,s,r,n,this.criticalSeg&&this.criticalSeg.segId===i),this.config.live&&j((()=>{this.checkPeers()}))}};class Ls extends At{static get name(){return"HlsjsP2pEngine"}constructor(e,t={}){if(super(t,e),!e)throw new TypeError("hlsjs instance is null");"serviceWorker"in navigator&&this._setupSW(),this.config.xhrSetup=e.config.xhrSetup,this.engineName=Ls.name,this._onFragLoading=this._onFragLoading.bind(this),this._onFragLoaded=this._onFragLoaded.bind(this),this._onFragChanged=this._onFragChanged.bind(this),this._onHlsError=this._onHlsError.bind(this),this._onLevelUpdated=this._onLevelUpdated.bind(this);const{channelIdMaker:s,signalId:i,browserInfo:r}=this.setup(),n=(t,o)=>{if(!o)return;const{config:a}=this,h=o.details,l=h.live;this._startEngine(this.hlsjs.url,l,r,s,i,h),e.off(this.HLSEvents.LEVEL_LOADED,n)};this._updateHlsEventsHandlers(),e.on(this.HLSEvents.LEVEL_LOADED,n);const o=(e,t)=>{if(!t)return;const{config:s}=this,{fragments:i,averagetargetduration:r,startSN:n}=t.details;s.httpLoadTime=this.determineHttpLoadTime(i,r,n)};0===this.config.httpLoadTime&&(this.config.live?e.on(this.HLSEvents.LEVEL_LOADED,o):this.config.httpLoadTime=3.5);const a=(t,s)=>{this._setupSegmentId();const i=s.levels.length;this.multiBitrate=i>1,e.off(this.HLSEvents.MANIFEST_PARSED,a)};e.on(this.HLSEvents.MANIFEST_PARSED,a),e.on(this.HLSEvents.DESTROYING,(()=>{e.off(this.HLSEvents.LEVEL_LOADED,o),this.destroy()}))}_startEngine(e,t,s,i,r,n={}){const{config:o}=this;o.live=t,this.browserInfo={...s,live:t,abr:this.multiBitrate||void 0,type:"hls"},this.channel=`${i(e)}|${r}[${ee.VERSION}]`,this.setupElectron();const a=this.initLogger();a.info("use HlsjsP2pEngine"),this.logger=a,a.info(`channel ${this.channel}`),t||(o.startSN=n.startSN,o.endSN=n.endSN,a.info(`startSN ${n.startSN} endSN ${n.endSN}`)),this._init(this.channel,this.browserInfo)}async _init(e,t){const{logger:s,config:i}=this;if(!this.p2pEnabled||"object"!=typeof self)return;this.media=this.hlsjs.media,this.media&&(this.currentSrc=this.media.src);const r=new Is(this,i);try{await super._init(e,r,t)}catch(e){return void s.error(e)}this.hlsjs.config.fLoader=function(e,t,s,i){const r=i.httpStreamEnabled&&ls()&&i.live;return class extends(n()){constructor(n){super(),this.logger=s,this.isHlsV0=i.isHlsV0,this.bufMgr=e.bufMgr,this.httpLoader=r||this.isHlsV0?new cs(n):new vs(n),this.p2pEnabled=i.p2pEnabled,this.isLive=i.live,this.scheduler=e,this.fetcher=t,this.segmentId=i.segmentId,this.blockTypes=i.p2pBlackList,this.stats=this.httpLoader.stats||A(),this.enableWorker=n.enableWorker,this.segmentBypass=T(i.segmentBypass)?i.segmentBypass:()=>!1,this.prefetchOnly=i.prefetchOnly,this.startFromSegmentOffset=i.startFromSegmentOffset}destroy(){this.httpLoader.destroy()}abort(){this.httpLoader.abort()}async load(e,t,s){const{logger:i,scheduler:r}=this,{url:n,frag:o}=e;this.isHlsV0||(o.stats=this.stats);const{level:a,sn:h,type:l,tagList:c}=o;let d=o.segId;if(!d){let t;e.rangeEnd&&(t="bytes="+e.rangeStart+"-"+(e.rangeEnd-1)),d=o.segId=this.segmentId(String(a),h,n,t)}const u=()=>(o.loadByHTTP=!0,this.httpLoader.load(e,t,s));if(!n||!Number.isInteger(h)||Cs(0,this.blockTypes,l)||this.segmentBypass(n,c))return i.info(`HTTP load blockType ${n}`),u();if(this.fetcher.increMediaRequests(),this.isLive&&r.requestedSet.has(d))return i.warn(`HTTP load duplicated ${n}`),u();if(r.engine.segmentLoadCount{!this.isHlsV0&&s.onProgress&&s.onProgress(this.stats,e,n.data),s.onSuccess(n,this.stats,e)}))}!this.prefetchOnly&&this.p2pEnabled&&r.hasAndSetTargetPeer(h,a,d,g)?this.loadFragByP2p(e,t,s,d,g):(i.info(`fragLoader load ${d} at ${h} level ${a} buffered ${1e3*g}`),this.loadFragByHttp(e,t,s,d))}loadFragByHttp(e,t,s,i){const{logger:n,scheduler:o}=this,{segmentBuilderMap:a}=o,h=e.frag,{sn:l,level:c}=h,d=de(l,c);if(r){let e;s.onUpdate=(t,s,r)=>{if(r)return n.warn(`loadFragByHttp ${i} aborted`),void a.delete(d);e&&e.receiveBytes(t,s)},s.onBodyStart=t=>{!e&&t>0&&(e=new _s(l,c,i,t),a.has(d)||a.set(d,e),o.notifyAllPeers(l,c,i,t,Gt.PARTIAL_FORWARD))}}const u=s.onSuccess;s.onSuccess=async(e,t,s)=>{o.coordinator.addLoaderHttpSpeed(t.tload-t.tfirst,t.loaded);const{data:r}=e;let h=t.tload-t.trequest;if(n.info(`HTTP loaded ${i} time ${h} speed ${t.total/h}`),!await this.bufMgr.hasSegOfId(i)){const e=S(r).buffer,t=new J(l,i,e,this.fetcher.peerId,c);await this.bufMgr.putSeg(t)}a.delete(d),this.fetcher.reportFlow(t.total),u(e,t,s)};const g=s.onProgress;g&&(s.onProgress=(e,t,s)=>{h.loaded=e.total,g(e,t,s&&this.enableWorker?S(s).buffer:s)}),e.frag.loadByHTTP=!0,this.httpLoader.load(e,t,s)}loadFragByP2p(t,s,i,r,n){const{logger:o}=this,a=t.frag;let h;h=s.loadPolicy?s.loadPolicy.maxTimeToFirstByteMs:s.timeout,(!h||h>1e3*n)&&(h=1e3*n),t.defaultTimeout=h,this.scheduler.load(t,s,i);const l=i.onSuccess,c=i.onTimeout;i.onTimeout=(e,t)=>{o.warn(`P2P timeout switched to HTTP load ${a.relurl} at ${a.sn}`),i.onSuccess=l,this.loadFragByHttp(t,s,i,r),i.onTimeout=c},i.onSuccess=async(t,s,n)=>{const{data:h}=t;if(Ts(s=this.stats,h.byteLength,e.coordinator),!await this.bufMgr.hasSegOfId(r)){const e=S(h).buffer,t=new J(a.sn,r,e,a.fromPeerId||this.fetcher.peerId,a.level,n.ext);await this.bufMgr.putSeg(t)}a.loadByP2P||this.fetcher.reportFlow(s.total),a.loaded=s.loaded,o.info(`${a.loadByP2P?"P2P":"HTTP"} loaded segment id ${r}`),!this.isHlsV0&&i.onProgress&&i.onProgress(s,n,h),l(t,s,n)}}}}(r,this.fetcher,s,i),i.sharePlaylist&&(this.hlsjs.config.pLoader=function(e,t,s){return class extends(n()){constructor(i){super(),this.logger=t,this.xhrLoader=new i.loader(i),this.p2pEnabled=s.p2pEnabled,this.scheduler=e,this.stats=this.xhrLoader.stats||A()}destroy(){this.xhrLoader.destroy()}abort(){this.xhrLoader.abort()}async load(e,t,s){const{logger:i}=this,{url:r}=e,n=w(r),o=s.onSuccess;if(s.onSuccess=(e,t,s)=>{this.scheduler&&!s.loadedByPeer&&this.scheduler.broadcastPlaylist(n,e.data),o(e,t,s)},this.scheduler&&this.scheduler.playlistInfo.has(n)){const t=await this.scheduler.getPlaylistFromPeer(n);if(t&&t.data){const{data:n,seq:o}=t;i.info(`got playlist from peer seq ${o}`),Ts(this.stats,n.length);let a={url:r,data:n};return e.loadedByPeer=!0,void j((()=>{s.onSuccess(a,this.stats,e)}))}}this.xhrLoader.load(e,t,s)}}}(r,s,i))}_onFragLoading(e,s){const i=s.frag;let{sn:r,level:n,segId:o}=i;if(!Cs(i.url,this.config.p2pBlackList,i.type)&&Number.isInteger(r)){if(this.logger&&this.logger.info("loading frag "+r),this.bufMgr&&(this.bufMgr.loadingSN=r),!o){let e;i._byteRange&&(e="bytes="+i._byteRange[0]+"-"+i._byteRange[1]);let t=i.url;this._setupSegmentId(),o=i.segId=this.config.segmentId(String(n),i.sn,t,e)}this.emit(t.FRAG_LOADING,{sn:r,segId:o,byHttp:i.loadByHTTP,level:n})}}_onLevelUpdated(e,t){const{details:s}=t,{hlsjs:i,config:r}=this,{targetduration:n,live:o,fragments:a}=s,h=a.length;if(o&&i&&"main"===a[0].type&&!(h<=4)&&(r.isHlsV0||!i.userConfig.liveSyncDuration&&!i.userConfig.liveSyncDurationCount)){const e=h<=9?h-1:h-2;i.config.liveSyncDurationCount!==e&&(i.config.liveSyncDurationCount=e)}}_onFragLoaded(e,s){if(this.segmentLoadCount++,!this.p2pEnabled)return;const{frag:i}=s;this.curTsUri=i.url;const{sn:r,segId:n,loaded:o,duration:a,level:h,fromPeerId:l,loadByP2P:c,url:d}=i,{config:u,logger:g}=this;this.tracker&&this.tracker.scheduler&&(P(this.tracker.scheduler.requestedSet,50),this.tracker.scheduler.requestedSet.add(n)),Cs(i.url,u.p2pBlackList,i.type)||(this.bufMgr&&this.bufMgr.loadingSN>=0&&this.emit(t.FRAG_LOADED,{url:d,sn:r,level:h,segId:n,loaded:o,duration:a,byP2p:!!c,fromPeerId:l}),!this.rangeTested&&u.useHttpRange&&(this.startRangeRequestTimer(),this.rangeTested=!0,g&&g.info(JSON.stringify({engine:this.engineName,hlsjs:this.hlsjsVersion,...this.browserInfo})))),this.segmentLoadCount>=u.startFromSegmentOffset&&this.resumeTracker()}_onFragChanged(e,s){const{frag:i}=s;if(!Cs(i.url,this.config.p2pBlackList,i.type)){this.logger&&this.logger.info("frag changed: "+i.sn);const{sn:e,duration:s}=i;this.emit(t.FRAG_CHANGED,{sn:e,duration:s})}}get currentLevel(){const{currentLevel:e}=this.hlsjs;return e>=0?e:0}disableP2P(){this.logger&&this.logger.warn("disable P2P"),this.p2pEnabled&&(this.p2pEnabled=!1,this.config.p2pEnabled=this.p2pEnabled,this.tracker&&(this.tracker.stopP2P(),this.tracker={},this.fetcher=null,this.bufMgr.destroy(),this.bufMgr=null,this.hlsjs.config.fLoader=this.hlsjs.config.pLoader=this.hlsjs.constructor.DefaultConfig.loader))}_updateHlsEventsHandlers(e=!1){const t=this.hlsjs;if(!t)return;const s=e?"off":"on";t[s](this.HLSEvents.FRAG_LOADING,this._onFragLoading),t[s](this.HLSEvents.FRAG_LOADED,this._onFragLoaded),t[s](this.HLSEvents.FRAG_CHANGED,this._onFragChanged),t[s](this.HLSEvents.ERROR,this._onHlsError),t[s](this.HLSEvents.LEVEL_UPDATED,this._onLevelUpdated)}destroy(){this._updateHlsEventsHandlers(!0),super.destroy()}_setupSW(){const{serviceWorker:e}=navigator;e.onmessage=e=>{const{action:t}=e.data,s=e.ports[0];if(s)return s.postMessage({action:t,pong:!0}),s.postMessage({action:t,data:{bypass:!0}})}}}const Rs=Ls;class As{static get Events(){return t}static get TrackerZone(){return re.TrackerZone}static isSupported(){return re.isSupported()&&(ne()||ws.isServiceWorkerSupported())}static isServiceWorkerSupported(){return ws.isServiceWorkerSupported()}static isMSESupported(){return ne()}static getBrowser(){return K().getBrowser()}static get ServiceWorkerEngine(){return ws}static get HlsjsEngine(){return Rs}static async tryRegisterServiceWorker({swFile:e="./sw.js",swScope:t="./"}={}){return As.registerServiceWorker({swFile:e,swScope:t})}static async registerServiceWorker({swFile:e="./sw.js",swScope:t="./",hlsjsInstance:s}={}){const{serviceWorker:i}=navigator;return!i||s?Promise.resolve():i.getRegistration().then((s=>s||Promise.race([i.register(e,{scope:t}).then((e=>function(e){return new Promise(((t,s)=>{const i=e.installing||e.waiting||e.active,r=()=>"activated"===i.state&&(i.removeEventListener("statechange",r),t(e),!0);r()||i.addEventListener("statechange",r)}))}(e))).catch((()=>{Promise.resolve()})),m(300)]))).catch((()=>{Promise.resolve()}))}constructor(e={}){const{hlsjsInstance:t}=e;delete e.hlsjsInstance;const s=()=>{this._realEngine=new Rs(t,e)},i=()=>{this._realEngine=new ws(e,t)};"1"!==u("_sw")?e.proxyFirst&&t?ws.isServiceWorkerSupported()?i():s():!e.proxyOnly&&ne()&&t?s():i():i()}get realEngine(){return this._realEngine}get engineName(){return this._realEngine.constructor.name}once(e,t){return this._realEngine.once(e,t)}on(e,t){return this._realEngine.on(e,t)}off(e,t){return this._realEngine.off(e,t)}removeListener(e,t){return this._realEngine.removeListener(e,t)}removeAllListeners(e){return this._realEngine.removeAllListeners(e)}set p2pEnabled(e){this._realEngine.p2pEnabled=e}get p2pEnabled(){return this._realEngine.p2pEnabled}enableP2P(){this._realEngine.enableP2P()}disableP2P(){this._realEngine.disableP2P()}destroy(){this._realEngine.destroy()}async registerServiceWorker(){return T(this._realEngine.registerServiceWorker)?this._realEngine.registerServiceWorker():Promise.reject("Not supported by this engine")}async unregisterServiceWorker(){return T(this._realEngine.unregisterServiceWorker)?this._realEngine.unregisterServiceWorker():Promise.reject("Not supported by this engine")}get version(){return re.version}}As.version=re.version,As.protocolVersion=ee.VERSION,"object"==typeof self&&(self.P2PEngineHls=As);const Ds=As})(),i=i.default})()));