diff --git a/THIRD_PARTY.txt b/THIRD_PARTY.txt
index e754bd64..c739f1a6 100644
--- a/THIRD_PARTY.txt
+++ b/THIRD_PARTY.txt
@@ -1741,9 +1741,9 @@ https://cdn.jsdelivr.net/npm/ngx-bootstrap@19.0.2/datepicker/bs-datepicker.css
https://cdn.jsdelivr.net/npm/ngx-bootstrap@6.2.0/datepicker/bs-datepicker.css
https://cdn.jsdelivr.net/npm/object-assign@4.1.1/index.js
https://cdn.jsdelivr.net/npm/p2p-media-loader-core@0.6.2/build/p2p-media-loader-core.min.js
-https://cdn.jsdelivr.net/npm/p2p-media-loader-core@2.1.0/dist/p2p-media-loader-core.es.min.js
+https://cdn.jsdelivr.net/npm/p2p-media-loader-core@2.2.0/dist/p2p-media-loader-core.es.min.js
https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@0.6.2/build/p2p-media-loader-hlsjs.min.js
-https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@2.1.0/dist/p2p-media-loader-hlsjs.es.min.js
+https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@2.2.0/dist/p2p-media-loader-hlsjs.es.min.js
https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.css
https://cdn.jsdelivr.net/npm/plyr@3.7.8/dist/plyr.min.js
https://cdn.jsdelivr.net/npm/raven-js@3.27.2/dist/raven.min.js
diff --git a/modules/internal/targets.js b/modules/internal/targets.js
index 0f9c7808..b382775e 100644
--- a/modules/internal/targets.js
+++ b/modules/internal/targets.js
@@ -372,7 +372,7 @@ targets.setLastVersion = function (type, version) {
if (type.startsWith('/owl-carousel/2.')) return '2.3.4';
if (type.startsWith('/p2p-media-loader-core') || type.startsWith('/p2p-media-loader-hlsjs')) {
if (helpers.compareVersion('0.6.2', version)) return '0.6.2'; // <= v0.6.2
- return '2.1.0';
+ return '2.2.0';
}
if (type.startsWith('/p5.js/0.')) return '0.10.2';
if (type.startsWith('/p5.js/1.')) return '1.11.2';
diff --git a/pages/updates/updates.html b/pages/updates/updates.html
index d1f9a47b..cbfcffa2 100644
--- a/pages/updates/updates.html
+++ b/pages/updates/updates.html
@@ -25,9 +25,9 @@
New in LocalCDN:
-
+
Updated
-
+ - p2p-media-loader-hlsjs & p2p-media-loader-core v2.1.0 -> v2.2.0
diff --git a/resources/p2p-media-loader-core/2.1.0/p2p-media-loader-core.min.jsm b/resources/p2p-media-loader-core/2.1.0/p2p-media-loader-core.min.jsm
deleted file mode 100644
index cff31158..00000000
--- a/resources/p2p-media-loader-core/2.1.0/p2p-media-loader-core.min.jsm
+++ /dev/null
@@ -1,3248 +0,0 @@
-var Pn = Object.defineProperty;
-var qn = (i, t, e) => t in i ? Pn(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
-var d = (i, t, e) => qn(i, typeof t != "symbol" ? t + "" : t, e);
-class x extends Error {
- constructor(e, n) {
- super(n);
- d(this, "timestamp");
- this.type = e, this.timestamp = performance.now();
- }
-}
-class oe extends Error {
- constructor(t) {
- super(), this.type = t;
- }
-}
-class Bn {
- constructor(t, e, n) {
- d(this, "requestControls");
- d(this, "abortController", new AbortController());
- d(this, "expectedBytesLength");
- d(this, "requestByteRange");
- d(this, "onChunkDownloaded");
- this.request = t, this.httpConfig = e, this.onChunkDownloaded = n.getEventDispatcher("onChunkDownloaded");
- const { byteRange: s } = this.request.segment;
- s && (this.requestByteRange = { ...s }), t.loadedBytes !== 0 && (this.requestByteRange = this.requestByteRange ?? { start: 0 }, this.requestByteRange.start = this.requestByteRange.start + t.loadedBytes), this.request.totalBytes && (this.expectedBytesLength = this.request.totalBytes - this.request.loadedBytes), this.requestControls = this.request.start({ downloadSource: "http" }, { abort: () => this.abortController.abort("abort"), notReceivingBytesTimeoutMs: this.httpConfig.httpNotReceivingBytesTimeoutMs }), this.fetch();
- }
- async fetch() {
- var e, n;
- const { segment: t } = this.request;
- try {
- let s = await ((n = (e = this.httpConfig).httpRequestSetup) == null ? void 0 : n.call(e, t.url, t.byteRange, this.abortController.signal, this.requestByteRange));
- if (!s) {
- const h = new Headers(this.requestByteRange ? { Range: `bytes=${this.requestByteRange.start}-${this.requestByteRange.end ?? ""}` } : void 0);
- s = new Request(t.url, { headers: h, signal: this.abortController.signal });
- }
- if (this.abortController.signal.aborted) throw new DOMException("Request aborted before request fetch", "AbortError");
- const r = await window.fetch(s);
- if (this.handleResponseHeaders(r), !r.body) return;
- const { requestControls: o } = this;
- o.firstBytesReceived();
- const a = r.body.getReader();
- for await (const h of async function* (u) {
- for (; ; ) {
- const { done: c, value: l } = await u.read();
- if (c) break;
- yield l;
- }
- }(a)) this.requestControls.addLoadedChunk(h), this.onChunkDownloaded(h.byteLength, "http");
- o.completeOnSuccess();
- } catch (s) {
- this.handleError(s);
- }
- }
- handleResponseHeaders(t) {
- if (!t.ok) throw t.status === 406 ? (this.request.clearLoadedBytes(), new x("http-bytes-mismatch", t.statusText)) : new x("http-error", t.statusText);
- const { requestByteRange: e } = this;
- if (e) if (t.status === 200) {
- if (this.request.segment.byteRange) throw new x("http-unexpected-status-code");
- this.request.clearLoadedBytes();
- } else {
- if (t.status !== 206) throw new x("http-unexpected-status-code", t.statusText);
- const n = t.headers.get("Content-Length");
- if (n && this.expectedBytesLength !== void 0 && this.expectedBytesLength !== +n) throw this.request.clearLoadedBytes(), new x("http-bytes-mismatch", t.statusText);
- const s = t.headers.get("Content-Range"), r = s ? function(o) {
- const a = On.exec(o.trim());
- if (!a) return;
- const [, h, u, c] = a;
- return { from: h ? parseInt(h) : void 0, to: u ? parseInt(u) : void 0, total: c ? parseInt(c) : void 0 };
- }(s) : void 0;
- if (r) {
- const { from: o, to: a, total: h } = r;
- if (h !== void 0 && this.request.totalBytes !== h || o !== void 0 && e.start !== o || a !== void 0 && e.end !== void 0 && e.end !== a) throw this.request.clearLoadedBytes(), new x("http-bytes-mismatch", t.statusText);
- }
- }
- if (t.status === 200 && this.request.totalBytes === void 0) {
- const n = t.headers.get("Content-Length");
- n && this.request.setTotalBytes(+n);
- }
- }
- handleError(t) {
- if (t instanceof Error) {
- if (t.name !== "abort") return;
- const e = t instanceof x ? t : new x("http-error", t.message);
- this.requestControls.abortOnError(e);
- }
- }
-}
-const On = /^bytes (?:(?:(\d+)|)-(?:(\d+)|)|\*)\/(?:(\d+)|\*)$/;
-function Dn(i) {
- return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, "default") ? i.default : i;
-}
-var E, P, je = { exports: {} }, _ = je.exports = {};
-function Ft() {
- throw new Error("setTimeout has not been defined");
-}
-function Ht() {
- throw new Error("clearTimeout has not been defined");
-}
-function We(i) {
- if (E === setTimeout) return setTimeout(i, 0);
- if ((E === Ft || !E) && setTimeout) return E = setTimeout, setTimeout(i, 0);
- try {
- return E(i, 0);
- } catch {
- try {
- return E.call(null, i, 0);
- } catch {
- return E.call(this, i, 0);
- }
- }
-}
-(function() {
- try {
- E = typeof setTimeout == "function" ? setTimeout : Ft;
- } catch {
- E = Ft;
- }
- try {
- P = typeof clearTimeout == "function" ? clearTimeout : Ht;
- } catch {
- P = Ht;
- }
-})();
-var j, q = [], z = !1, pt = -1;
-function Mn() {
- z && j && (z = !1, j.length ? q = j.concat(q) : pt = -1, q.length && Qe());
-}
-function Qe() {
- if (!z) {
- var i = We(Mn);
- z = !0;
- for (var t = q.length; t; ) {
- for (j = q, q = []; ++pt < t; ) j && j[pt].run();
- pt = -1, t = q.length;
- }
- j = null, z = !1, function(e) {
- if (P === clearTimeout) return clearTimeout(e);
- if ((P === Ht || !P) && clearTimeout) return P = clearTimeout, clearTimeout(e);
- try {
- return P(e);
- } catch {
- try {
- return P.call(null, e);
- } catch {
- return P.call(this, e);
- }
- }
- }(i);
- }
-}
-function ae(i, t) {
- this.fun = i, this.array = t;
-}
-function R() {
-}
-_.nextTick = function(i) {
- var t = new Array(arguments.length - 1);
- if (arguments.length > 1) for (var e = 1; e < arguments.length; e++) t[e - 1] = arguments[e];
- q.push(new ae(i, t)), q.length !== 1 || z || We(Qe);
-}, ae.prototype.run = function() {
- this.fun.apply(null, this.array);
-}, _.title = "browser", _.browser = !0, _.env = {}, _.argv = [], _.version = "", _.versions = {}, _.on = R, _.addListener = R, _.once = R, _.off = R, _.removeListener = R, _.removeAllListeners = R, _.emit = R, _.prependListener = R, _.prependOnceListener = R, _.listeners = function(i) {
- return [];
-}, _.binding = function(i) {
- throw new Error("process.binding is not supported");
-}, _.cwd = function() {
- return "/";
-}, _.chdir = function(i) {
- throw new Error("process.chdir is not supported");
-}, _.umask = function() {
- return 0;
-};
-const ft = Dn(je.exports);
-var Nn = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
-function W(i) {
- return i && i.__esModule && Object.prototype.hasOwnProperty.call(i, "default") ? i.default : i;
-}
-var he, ce, $t = { exports: {} };
-function Un() {
- if (ce) return he;
- ce = 1;
- var i = 1e3, t = 60 * i, e = 60 * t, n = 24 * e, s = 7 * n, r = 365.25 * n;
- function o(a, h, u, c) {
- var l = h >= 1.5 * u;
- return Math.round(a / u) + " " + c + (l ? "s" : "");
- }
- return he = function(a, h) {
- h = h || {};
- var u = typeof a;
- if (u === "string" && a.length > 0) return function(c) {
- if (!((c = String(c)).length > 100)) {
- var l = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(c);
- if (l) {
- var g = parseFloat(l[1]);
- switch ((l[2] || "ms").toLowerCase()) {
- case "years":
- case "year":
- case "yrs":
- case "yr":
- case "y":
- return g * r;
- case "weeks":
- case "week":
- case "w":
- return g * s;
- case "days":
- case "day":
- case "d":
- return g * n;
- case "hours":
- case "hour":
- case "hrs":
- case "hr":
- case "h":
- return g * e;
- case "minutes":
- case "minute":
- case "mins":
- case "min":
- case "m":
- return g * t;
- case "seconds":
- case "second":
- case "secs":
- case "sec":
- case "s":
- return g * i;
- case "milliseconds":
- case "millisecond":
- case "msecs":
- case "msec":
- case "ms":
- return g;
- default:
- return;
- }
- }
- }
- }(a);
- if (u === "number" && isFinite(a)) return h.long ? function(c) {
- var l = Math.abs(c);
- return l >= n ? o(c, l, n, "day") : l >= e ? o(c, l, e, "hour") : l >= t ? o(c, l, t, "minute") : l >= i ? o(c, l, i, "second") : c + " ms";
- }(a) : function(c) {
- var l = Math.abs(c);
- return l >= n ? Math.round(c / n) + "d" : l >= e ? Math.round(c / e) + "h" : l >= t ? Math.round(c / t) + "m" : l >= i ? Math.round(c / i) + "s" : c + "ms";
- }(a);
- throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(a));
- };
-}
-var Fn = function(i) {
- function t(s) {
- let r, o, a, h = null;
- function u(...c) {
- if (!u.enabled) return;
- const l = u, g = Number(/* @__PURE__ */ new Date()), m = g - (r || g);
- l.diff = m, l.prev = r, l.curr = g, r = g, c[0] = t.coerce(c[0]), typeof c[0] != "string" && c.unshift("%O");
- let f = 0;
- c[0] = c[0].replace(/%([a-zA-Z%])/g, (v, H) => {
- if (v === "%%") return "%";
- f++;
- const D = t.formatters[H];
- if (typeof D == "function") {
- const Et = c[f];
- v = D.call(l, Et), c.splice(f, 1), f--;
- }
- return v;
- }), t.formatArgs.call(l, c), (l.log || t.log).apply(l, c);
- }
- return u.namespace = s, u.useColors = t.useColors(), u.color = t.selectColor(s), u.extend = e, u.destroy = t.destroy, Object.defineProperty(u, "enabled", { enumerable: !0, configurable: !1, get: () => h !== null ? h : (o !== t.namespaces && (o = t.namespaces, a = t.enabled(s)), a), set: (c) => {
- h = c;
- } }), typeof t.init == "function" && t.init(u), u;
- }
- function e(s, r) {
- const o = t(this.namespace + (r === void 0 ? ":" : r) + s);
- return o.log = this.log, o;
- }
- function n(s) {
- return s.toString().substring(2, s.toString().length - 2).replace(/\.\*\?$/, "*");
- }
- return t.debug = t, t.default = t, t.coerce = function(s) {
- return s instanceof Error ? s.stack || s.message : s;
- }, t.disable = function() {
- const s = [...t.names.map(n), ...t.skips.map(n).map((r) => "-" + r)].join(",");
- return t.enable(""), s;
- }, t.enable = function(s) {
- let r;
- t.save(s), t.namespaces = s, t.names = [], t.skips = [];
- const o = (typeof s == "string" ? s : "").split(/[\s,]+/), a = o.length;
- for (r = 0; r < a; r++) o[r] && ((s = o[r].replace(/\*/g, ".*?"))[0] === "-" ? t.skips.push(new RegExp("^" + s.slice(1) + "$")) : t.names.push(new RegExp("^" + s + "$")));
- }, t.enabled = function(s) {
- if (s[s.length - 1] === "*") return !0;
- let r, o;
- for (r = 0, o = t.skips.length; r < o; r++) if (t.skips[r].test(s)) return !1;
- for (r = 0, o = t.names.length; r < o; r++) if (t.names[r].test(s)) return !0;
- return !1;
- }, t.humanize = Un(), t.destroy = function() {
- console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
- }, Object.keys(i).forEach((s) => {
- t[s] = i[s];
- }), t.names = [], t.skips = [], t.formatters = {}, t.selectColor = function(s) {
- let r = 0;
- for (let o = 0; o < s.length; o++) r = (r << 5) - r + s.charCodeAt(o), r |= 0;
- return t.colors[Math.abs(r) % t.colors.length];
- }, t.enable(t.load()), t;
-};
-(function(i, t) {
- t.formatArgs = function(n) {
- if (n[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + n[0] + (this.useColors ? "%c " : " ") + "+" + i.exports.humanize(this.diff), !this.useColors) return;
- const s = "color: " + this.color;
- n.splice(1, 0, s, "color: inherit");
- let r = 0, o = 0;
- n[0].replace(/%[a-zA-Z%]/g, (a) => {
- a !== "%%" && (r++, a === "%c" && (o = r));
- }), n.splice(o, 0, s);
- }, t.save = function(n) {
- try {
- n ? t.storage.setItem("debug", n) : t.storage.removeItem("debug");
- } catch {
- }
- }, t.load = function() {
- let n;
- try {
- n = t.storage.getItem("debug");
- } catch {
- }
- return !n && ft !== void 0 && "env" in ft && (n = ft.env.DEBUG), n;
- }, t.useColors = function() {
- if (typeof window < "u" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) return !0;
- if (typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) return !1;
- let n;
- return typeof document < "u" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window < "u" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator < "u" && navigator.userAgent && (n = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(n[1], 10) >= 31 || typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
- }, t.storage = function() {
- try {
- return localStorage;
- } catch {
- }
- }(), t.destroy = /* @__PURE__ */ (() => {
- let n = !1;
- return () => {
- n || (n = !0, console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."));
- };
- })(), t.colors = ["#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33"], t.log = console.debug || console.log || (() => {
- }), i.exports = Fn(t);
- const { formatters: e } = i.exports;
- e.j = function(n) {
- try {
- return JSON.stringify(n);
- } catch (s) {
- return "[UnexpectedJSONParseError]: " + s.message;
- }
- };
-})($t, $t.exports);
-var ze = $t.exports;
-const L = W(ze);
-var Ge, jt = { exports: {} }, G = typeof Reflect == "object" ? Reflect : null, de = G && typeof G.apply == "function" ? G.apply : function(i, t, e) {
- return Function.prototype.apply.call(i, t, e);
-};
-Ge = G && typeof G.ownKeys == "function" ? G.ownKeys : Object.getOwnPropertySymbols ? function(i) {
- return Object.getOwnPropertyNames(i).concat(Object.getOwnPropertySymbols(i));
-} : function(i) {
- return Object.getOwnPropertyNames(i);
-};
-var le = Number.isNaN || function(i) {
- return i != i;
-};
-function p() {
- p.init.call(this);
-}
-jt.exports = p, jt.exports.once = function(i, t) {
- return new Promise(function(e, n) {
- function s(o) {
- i.removeListener(t, r), n(o);
- }
- function r() {
- typeof i.removeListener == "function" && i.removeListener("error", s), e([].slice.call(arguments));
- }
- ye(i, t, r, { once: !0 }), t !== "error" && function(o, a, h) {
- typeof o.on == "function" && ye(o, "error", a, h);
- }(i, s, { once: !0 });
- });
-}, p.EventEmitter = p, p.prototype._events = void 0, p.prototype._eventsCount = 0, p.prototype._maxListeners = void 0;
-var ue = 10;
-function yt(i) {
- if (typeof i != "function") throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof i);
-}
-function Je(i) {
- return i._maxListeners === void 0 ? p.defaultMaxListeners : i._maxListeners;
-}
-function ge(i, t, e, n) {
- var s, r, o, a;
- if (yt(e), (r = i._events) === void 0 ? (r = i._events = /* @__PURE__ */ Object.create(null), i._eventsCount = 0) : (r.newListener !== void 0 && (i.emit("newListener", t, e.listener ? e.listener : e), r = i._events), o = r[t]), o === void 0) o = r[t] = e, ++i._eventsCount;
- else if (typeof o == "function" ? o = r[t] = n ? [e, o] : [o, e] : n ? o.unshift(e) : o.push(e), (s = Je(i)) > 0 && o.length > s && !o.warned) {
- o.warned = !0;
- var h = new Error("Possible EventEmitter memory leak detected. " + o.length + " " + String(t) + " listeners added. Use emitter.setMaxListeners() to increase limit");
- h.name = "MaxListenersExceededWarning", h.emitter = i, h.type = t, h.count = o.length, a = h, console && console.warn && console.warn(a);
- }
- return i;
-}
-function Hn() {
- if (!this.fired) return this.target.removeListener(this.type, this.wrapFn), this.fired = !0, arguments.length === 0 ? this.listener.call(this.target) : this.listener.apply(this.target, arguments);
-}
-function me(i, t, e) {
- var n = { fired: !1, wrapFn: void 0, target: i, type: t, listener: e }, s = Hn.bind(n);
- return s.listener = e, n.wrapFn = s, s;
-}
-function pe(i, t, e) {
- var n = i._events;
- if (n === void 0) return [];
- var s = n[t];
- return s === void 0 ? [] : typeof s == "function" ? e ? [s.listener || s] : [s] : e ? function(r) {
- for (var o = new Array(r.length), a = 0; a < o.length; ++a) o[a] = r[a].listener || r[a];
- return o;
- }(s) : Ve(s, s.length);
-}
-function fe(i) {
- var t = this._events;
- if (t !== void 0) {
- var e = t[i];
- if (typeof e == "function") return 1;
- if (e !== void 0) return e.length;
- }
- return 0;
-}
-function Ve(i, t) {
- for (var e = new Array(t), n = 0; n < t; ++n) e[n] = i[n];
- return e;
-}
-function ye(i, t, e, n) {
- if (typeof i.on == "function") n.once ? i.once(t, e) : i.on(t, e);
- else {
- if (typeof i.addEventListener != "function") throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof i);
- i.addEventListener(t, function s(r) {
- n.once && i.removeEventListener(t, s), e(r);
- });
- }
-}
-Object.defineProperty(p, "defaultMaxListeners", { enumerable: !0, get: function() {
- return ue;
-}, set: function(i) {
- if (typeof i != "number" || i < 0 || le(i)) throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + i + ".");
- ue = i;
-} }), p.init = function() {
- this._events !== void 0 && this._events !== Object.getPrototypeOf(this)._events || (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0), this._maxListeners = this._maxListeners || void 0;
-}, p.prototype.setMaxListeners = function(i) {
- if (typeof i != "number" || i < 0 || le(i)) throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + i + ".");
- return this._maxListeners = i, this;
-}, p.prototype.getMaxListeners = function() {
- return Je(this);
-}, p.prototype.emit = function(i) {
- for (var t = [], e = 1; e < arguments.length; e++) t.push(arguments[e]);
- var n = i === "error", s = this._events;
- if (s !== void 0) n = n && s.error === void 0;
- else if (!n) return !1;
- if (n) {
- var r;
- if (t.length > 0 && (r = t[0]), r instanceof Error) throw r;
- var o = new Error("Unhandled error." + (r ? " (" + r.message + ")" : ""));
- throw o.context = r, o;
- }
- var a = s[i];
- if (a === void 0) return !1;
- if (typeof a == "function") de(a, this, t);
- else {
- var h = a.length, u = Ve(a, h);
- for (e = 0; e < h; ++e) de(u[e], this, t);
- }
- return !0;
-}, p.prototype.addListener = function(i, t) {
- return ge(this, i, t, !1);
-}, p.prototype.on = p.prototype.addListener, p.prototype.prependListener = function(i, t) {
- return ge(this, i, t, !0);
-}, p.prototype.once = function(i, t) {
- return yt(t), this.on(i, me(this, i, t)), this;
-}, p.prototype.prependOnceListener = function(i, t) {
- return yt(t), this.prependListener(i, me(this, i, t)), this;
-}, p.prototype.removeListener = function(i, t) {
- var e, n, s, r, o;
- if (yt(t), (n = this._events) === void 0) return this;
- if ((e = n[i]) === void 0) return this;
- if (e === t || e.listener === t) --this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : (delete n[i], n.removeListener && this.emit("removeListener", i, e.listener || t));
- else if (typeof e != "function") {
- for (s = -1, r = e.length - 1; r >= 0; r--) if (e[r] === t || e[r].listener === t) {
- o = e[r].listener, s = r;
- break;
- }
- if (s < 0) return this;
- s === 0 ? e.shift() : function(a, h) {
- for (; h + 1 < a.length; h++) a[h] = a[h + 1];
- a.pop();
- }(e, s), e.length === 1 && (n[i] = e[0]), n.removeListener !== void 0 && this.emit("removeListener", i, o || t);
- }
- return this;
-}, p.prototype.off = p.prototype.removeListener, p.prototype.removeAllListeners = function(i) {
- var t, e, n;
- if ((e = this._events) === void 0) return this;
- if (e.removeListener === void 0) return arguments.length === 0 ? (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0) : e[i] !== void 0 && (--this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : delete e[i]), this;
- if (arguments.length === 0) {
- var s, r = Object.keys(e);
- for (n = 0; n < r.length; ++n) (s = r[n]) !== "removeListener" && this.removeAllListeners(s);
- return this.removeAllListeners("removeListener"), this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0, this;
- }
- if (typeof (t = e[i]) == "function") this.removeListener(i, t);
- else if (t !== void 0) for (n = t.length - 1; n >= 0; n--) this.removeListener(i, t[n]);
- return this;
-}, p.prototype.listeners = function(i) {
- return pe(this, i, !0);
-}, p.prototype.rawListeners = function(i) {
- return pe(this, i, !1);
-}, p.listenerCount = function(i, t) {
- return typeof i.listenerCount == "function" ? i.listenerCount(t) : fe.call(i, t);
-}, p.prototype.listenerCount = fe, p.prototype.eventNames = function() {
- return this._eventsCount > 0 ? Ge(this._events) : [];
-};
-var Ye = jt.exports;
-const Ke = W(Ye);
-var Wt = { exports: {} }, $n = function i(t, e) {
- if (t && e) return i(t)(e);
- if (typeof t != "function") throw new TypeError("need wrapper function");
- return Object.keys(t).forEach(function(s) {
- n[s] = t[s];
- }), n;
- function n() {
- for (var s = new Array(arguments.length), r = 0; r < s.length; r++) s[r] = arguments[r];
- var o = t.apply(this, s), a = s[s.length - 1];
- return typeof o == "function" && o !== a && Object.keys(a).forEach(function(h) {
- o[h] = a[h];
- }), o;
- }
-}, _e = $n;
-function rt(i) {
- var t = function() {
- return t.called ? t.value : (t.called = !0, t.value = i.apply(this, arguments));
- };
- return t.called = !1, t;
-}
-function Se(i) {
- var t = function() {
- if (t.called) throw new Error(t.onceError);
- return t.called = !0, t.value = i.apply(this, arguments);
- }, e = i.name || "Function wrapped with `once`";
- return t.onceError = e + " shouldn't be called more than once", t.called = !1, t;
-}
-Wt.exports = _e(rt), Wt.exports.strict = _e(Se), rt.proto = rt(function() {
- Object.defineProperty(Function.prototype, "once", { value: function() {
- return rt(this);
- }, configurable: !0 }), Object.defineProperty(Function.prototype, "onceStrict", { value: function() {
- return Se(this);
- }, configurable: !0 });
-});
-const jn = W(Wt.exports);
-let we;
-var Ze = typeof queueMicrotask == "function" ? queueMicrotask.bind(typeof window < "u" ? window : Nn) : (i) => (we || (we = Promise.resolve())).then(i).catch((t) => setTimeout(() => {
- throw t;
-}, 0));
-const Qt = W(Ze);
-var Wn = function(i, t) {
- let e, n, s, r = !0;
- Array.isArray(i) ? (e = [], n = i.length) : (s = Object.keys(i), e = {}, n = s.length);
- function o(h) {
- function u() {
- t && t(h, e), t = null;
- }
- r ? Qn(u) : u();
- }
- function a(h, u, c) {
- e[h] = c, (--n == 0 || u) && o(u);
- }
- n ? s ? s.forEach(function(h) {
- i[h](function(u, c) {
- a(h, u, c);
- });
- }) : i.forEach(function(h, u) {
- h(function(c, l) {
- a(u, c, l);
- });
- }) : o(null), r = !1;
-};
-const Qn = Ze, zn = W(Wn), O = typeof window < "u" ? window : self, zt = O.RTCPeerConnection || O.mozRTCPeerConnection || O.webkitRTCPeerConnection, Gn = O.RTCSessionDescription || O.mozRTCSessionDescription || O.webkitRTCSessionDescription, Jn = O.RTCIceCandidate || O.mozRTCIceCandidate || O.webkitRTCIceCandidate;
-var Vn = typeof queueMicrotask == "function" ? queueMicrotask : (i) => Promise.resolve().then(i);
-const be = class {
- constructor(i) {
- if (!(i > 0) || i - 1 & i) throw new Error("Max size for a FixedFIFO should be a power of two");
- this.buffer = new Array(i), this.mask = i - 1, this.top = 0, this.btm = 0, this.next = null;
- }
- clear() {
- this.top = this.btm = 0, this.next = null, this.buffer.fill(void 0);
- }
- push(i) {
- return this.buffer[this.top] === void 0 && (this.buffer[this.top] = i, this.top = this.top + 1 & this.mask, !0);
- }
- shift() {
- const i = this.buffer[this.btm];
- if (i !== void 0) return this.buffer[this.btm] = void 0, this.btm = this.btm + 1 & this.mask, i;
- }
- peek() {
- return this.buffer[this.btm];
- }
- isEmpty() {
- return this.buffer[this.btm] === void 0;
- }
-};
-var Xe = class {
- constructor(i) {
- this.decoder = new TextDecoder(i === "utf16le" ? "utf16-le" : i);
- }
- get remaining() {
- return -1;
- }
- decode(i) {
- return this.decoder.decode(i, { stream: !0 });
- }
- flush() {
- return this.decoder.decode(new Uint8Array(0));
- }
-};
-const Yn = Xe, Kn = Xe, { EventEmitter: Zn } = Ye, ie = new Error("Stream was destroyed"), tn = (new Error("Premature close"), Vn), en = class {
- constructor(i) {
- this.hwm = i || 16, this.head = new be(this.hwm), this.tail = this.head, this.length = 0;
- }
- clear() {
- this.head = this.tail, this.head.clear(), this.length = 0;
- }
- push(i) {
- if (this.length++, !this.head.push(i)) {
- const t = this.head;
- this.head = t.next = new be(2 * this.head.buffer.length), this.head.push(i);
- }
- }
- shift() {
- this.length !== 0 && this.length--;
- const i = this.tail.shift();
- if (i === void 0 && this.tail.next) {
- const t = this.tail.next;
- return this.tail.next = null, this.tail = t, this.tail.shift();
- }
- return i;
- }
- peek() {
- const i = this.tail.peek();
- return i === void 0 && this.tail.next ? this.tail.next.peek() : i;
- }
- isEmpty() {
- return this.length === 0;
- }
-}, Xn = class {
- constructor(i = "utf8") {
- switch (this.encoding = function(t) {
- switch (t = t.toLowerCase()) {
- case "utf8":
- case "utf-8":
- return "utf8";
- case "ucs2":
- case "ucs-2":
- case "utf16le":
- case "utf-16le":
- return "utf16le";
- case "latin1":
- case "binary":
- return "latin1";
- case "base64":
- case "ascii":
- case "hex":
- return t;
- default:
- throw new Error("Unknown encoding: " + t);
- }
- }(i), this.encoding) {
- case "utf8":
- this.decoder = new Kn();
- break;
- case "utf16le":
- case "base64":
- throw new Error("Unsupported encoding: " + this.encoding);
- default:
- this.decoder = new Yn(this.encoding);
- }
- }
- get remaining() {
- return this.decoder.remaining;
- }
- push(i) {
- return typeof i == "string" ? i : this.decoder.decode(i);
- }
- write(i) {
- return this.push(i);
- }
- end(i) {
- let t = "";
- return i && (t = this.push(i)), t += this.decoder.flush(), t;
- }
-}, it = 536870911, nn = 1 ^ it, ts = 2 ^ it, sn = 64, Pt = 128, rn = 256, es = 1024, Ce = 2048, ns = 4096, ss = 8192, St = 16384, qt = 32768, Gt = 131072, is = 131328, rs = 16 ^ it, ve = 536805375, ke = 768 ^ it, on = 536838143, os = 32 ^ it, an = 536739839, as = 1 << 18, wt = 2 << 18, hn = 4 << 18, Te = 8 << 18, hs = 16 << 18, cn = 32 << 18, Jt = 64 << 18, Bt = 128 << 18, xe = 512 << 18, cs = 1024 << 18, ds = 535822335, dn = 503316479, ls = 268435455, bt = 262160, us = 536608751, ln = 8404992, nt = 14, gs = 15, un = 8405006, gn = 33587200, mn = 33587215, ms = 2359296, Ae = 270794767, ot = Symbol.asyncIterator || Symbol("asyncIterator");
-class ps {
- constructor(t, { highWaterMark: e = 16384, map: n = null, mapWritable: s, byteLength: r, byteLengthWritable: o } = {}) {
- this.stream = t, this.queue = new en(), this.highWaterMark = e, this.buffered = 0, this.error = null, this.pipeline = null, this.drains = null, this.byteLength = o || r || _n, this.map = s || n, this.afterWrite = ws.bind(this), this.afterUpdateNextTick = vs.bind(this);
- }
- get ended() {
- return !!(this.stream._duplexState & cn);
- }
- push(t) {
- return !(142606350 & this.stream._duplexState) && (this.map !== null && (t = this.map(t)), this.buffered += this.byteLength(t), this.queue.push(t), this.buffered < this.highWaterMark ? (this.stream._duplexState |= Te, !0) : (this.stream._duplexState |= 6291456, !1));
- }
- shift() {
- const t = this.queue.shift();
- return this.buffered -= this.byteLength(t), this.buffered === 0 && (this.stream._duplexState &= 534773759), t;
- }
- end(t) {
- typeof t == "function" ? this.stream.once("finish", t) : t != null && this.push(t), this.stream._duplexState = (this.stream._duplexState | xe) & ds;
- }
- autoBatch(t, e) {
- const n = [], s = this.stream;
- for (n.push(t); (s._duplexState & Ae) === ms; ) n.push(s._writableState.shift());
- if (s._duplexState & gs) return e(null);
- s._writev(n, e);
- }
- update() {
- const t = this.stream;
- t._duplexState |= wt;
- do {
- for (; (t._duplexState & Ae) === Te; ) {
- const e = this.shift();
- t._duplexState |= 67371008, t._write(e, this.afterWrite);
- }
- 1310720 & t._duplexState || this.updateNonPrimary();
- } while (this.continueUpdate() === !0);
- t._duplexState &= 536346623;
- }
- updateNonPrimary() {
- const t = this.stream;
- if ((144965647 & t._duplexState) === xe) return t._duplexState = t._duplexState | as, void t._final(Ss.bind(this));
- (t._duplexState & nt) != 4 ? (t._duplexState & mn) == 1 && (t._duplexState = (t._duplexState | bt) & nn, t._open(fn.bind(this))) : t._duplexState & gn || (t._duplexState |= bt, t._destroy(pn.bind(this)));
- }
- continueUpdate() {
- return !!(this.stream._duplexState & Bt) && (this.stream._duplexState &= dn, !0);
- }
- updateCallback() {
- (35127311 & this.stream._duplexState) === hn ? this.update() : this.updateNextTick();
- }
- updateNextTick() {
- this.stream._duplexState & Bt || (this.stream._duplexState |= Bt, this.stream._duplexState & wt || tn(this.afterUpdateNextTick));
- }
-}
-class fs {
- constructor(t, { highWaterMark: e = 16384, map: n = null, mapReadable: s, byteLength: r, byteLengthReadable: o } = {}) {
- this.stream = t, this.queue = new en(), this.highWaterMark = e === 0 ? 1 : e, this.buffered = 0, this.readAhead = e > 0, this.error = null, this.pipeline = null, this.byteLength = o || r || _n, this.map = s || n, this.pipeTo = null, this.afterRead = bs.bind(this), this.afterUpdateNextTick = Cs.bind(this);
- }
- get ended() {
- return !!(this.stream._duplexState & St);
- }
- pipe(t, e) {
- if (this.pipeTo !== null) throw new Error("Can only pipe to one destination");
- if (typeof e != "function" && (e = null), this.stream._duplexState |= 512, this.pipeTo = t, this.pipeline = new ys(this.stream, t, e), e && this.stream.on("error", Le), yn(t)) t._writableState.pipeline = this.pipeline, e && t.on("error", Le), t.on("finish", this.pipeline.finished.bind(this.pipeline));
- else {
- const n = this.pipeline.done.bind(this.pipeline, t), s = this.pipeline.done.bind(this.pipeline, t, null);
- t.on("error", n), t.on("close", s), t.on("finish", this.pipeline.finished.bind(this.pipeline));
- }
- t.on("drain", _s.bind(this)), this.stream.emit("piping", t), t.emit("pipe", this.stream);
- }
- push(t) {
- const e = this.stream;
- return t === null ? (this.highWaterMark = 0, e._duplexState = 536805311 & e._duplexState | 1024, !1) : this.map !== null && (t = this.map(t)) === null ? (e._duplexState &= ve, this.buffered < this.highWaterMark) : (this.buffered += this.byteLength(t), this.queue.push(t), e._duplexState = (e._duplexState | Pt) & ve, this.buffered < this.highWaterMark);
- }
- shift() {
- const t = this.queue.shift();
- return this.buffered -= this.byteLength(t), this.buffered === 0 && (this.stream._duplexState &= 536862591), t;
- }
- unshift(t) {
- const e = [this.map !== null ? this.map(t) : t];
- for (; this.buffered > 0; ) e.push(this.shift());
- for (let n = 0; n < e.length - 1; n++) {
- const s = e[n];
- this.buffered += this.byteLength(s), this.queue.push(s);
- }
- this.push(e[e.length - 1]);
- }
- read() {
- const t = this.stream;
- if ((16527 & t._duplexState) === Pt) {
- const e = this.shift();
- return this.pipeTo !== null && this.pipeTo.write(e) === !1 && (t._duplexState &= ke), t._duplexState & Ce && t.emit("data", e), e;
- }
- return this.readAhead === !1 && (t._duplexState |= Gt, this.updateNextTick()), null;
- }
- drain() {
- const t = this.stream;
- for (; (16527 & t._duplexState) === Pt && 768 & t._duplexState; ) {
- const e = this.shift();
- this.pipeTo !== null && this.pipeTo.write(e) === !1 && (t._duplexState &= ke), t._duplexState & Ce && t.emit("data", e);
- }
- }
- update() {
- const t = this.stream;
- t._duplexState |= 32;
- do {
- for (this.drain(); this.buffered < this.highWaterMark && (214047 & t._duplexState) === Gt; ) t._duplexState |= 65552, t._read(this.afterRead), this.drain();
- (12431 & t._duplexState) == 4224 && (t._duplexState |= ss, t.emit("readable")), 80 & t._duplexState || this.updateNonPrimary();
- } while (this.continueUpdate() === !0);
- t._duplexState &= os;
- }
- updateNonPrimary() {
- const t = this.stream;
- (1167 & t._duplexState) === es && (t._duplexState = 536869887 & t._duplexState | 16384, t.emit("end"), (t._duplexState & un) === ln && (t._duplexState |= 4), this.pipeTo !== null && this.pipeTo.end()), (t._duplexState & nt) != 4 ? (t._duplexState & mn) == 1 && (t._duplexState = (t._duplexState | bt) & nn, t._open(fn.bind(this))) : t._duplexState & gn || (t._duplexState |= bt, t._destroy(pn.bind(this)));
- }
- continueUpdate() {
- return !!(this.stream._duplexState & qt) && (this.stream._duplexState &= on, !0);
- }
- updateCallback() {
- (32879 & this.stream._duplexState) === sn ? this.update() : this.updateNextTick();
- }
- updateNextTick() {
- this.stream._duplexState & qt || (this.stream._duplexState |= qt, 32 & this.stream._duplexState || tn(this.afterUpdateNextTick));
- }
-}
-class ys {
- constructor(t, e, n) {
- this.from = t, this.to = e, this.afterPipe = n, this.error = null, this.pipeToFinished = !1;
- }
- finished() {
- this.pipeToFinished = !0;
- }
- done(t, e) {
- e && (this.error = e), t !== this.to || (this.to = null, this.from === null) ? t !== this.from || (this.from = null, this.to === null) ? (this.afterPipe !== null && this.afterPipe(this.error), this.to = this.from = this.afterPipe = null) : t._duplexState & St || this.to.destroy(this.error || new Error("Readable stream closed before ending")) : this.from._duplexState & St && this.pipeToFinished || this.from.destroy(this.error || new Error("Writable stream closed prematurely"));
- }
-}
-function _s() {
- this.stream._duplexState |= 512, this.updateCallback();
-}
-function Ss(i) {
- const t = this.stream;
- i && t.destroy(i), t._duplexState & nt || (t._duplexState |= cn, t.emit("finish")), (t._duplexState & un) === ln && (t._duplexState |= 4), t._duplexState &= 402391039, t._duplexState & wt ? this.updateNextTick() : this.update();
-}
-function pn(i) {
- const t = this.stream;
- i || this.error === ie || (i = this.error), i && t.emit("error", i), t._duplexState |= 8, t.emit("close");
- const e = t._readableState, n = t._writableState;
- if (e !== null && e.pipeline !== null && e.pipeline.done(t, i), n !== null) {
- for (; n.drains !== null && n.drains.length > 0; ) n.drains.shift().resolve(!1);
- n.pipeline !== null && n.pipeline.done(t, i);
- }
-}
-function ws(i) {
- const t = this.stream;
- i && t.destroy(i), t._duplexState &= 469499903, this.drains !== null && function(e) {
- for (let n = 0; n < e.length; n++) --e[n].writes == 0 && (e.shift().resolve(!0), n--);
- }(this.drains), (6553615 & t._duplexState) === hs && (t._duplexState &= 532676607, (t._duplexState & Jt) === Jt && t.emit("drain")), this.updateCallback();
-}
-function bs(i) {
- i && this.stream.destroy(i), this.stream._duplexState &= rs, this.readAhead !== !1 || this.stream._duplexState & rn || (this.stream._duplexState &= an), this.updateCallback();
-}
-function Cs() {
- 32 & this.stream._duplexState || (this.stream._duplexState &= on, this.update());
-}
-function vs() {
- this.stream._duplexState & wt || (this.stream._duplexState &= dn, this.update());
-}
-function fn(i) {
- const t = this.stream;
- i && t.destroy(i), 4 & t._duplexState || (17423 & t._duplexState || (t._duplexState |= sn), 142606351 & t._duplexState || (t._duplexState |= hn), t.emit("open")), t._duplexState &= us, t._writableState !== null && t._writableState.updateCallback(), t._readableState !== null && t._readableState.updateCallback();
-}
-function ks(i) {
- this._readableState !== null && (i === "data" && (this._duplexState |= 133376, this._readableState.updateNextTick()), i === "readable" && (this._duplexState |= ns, this._readableState.updateNextTick())), this._writableState !== null && i === "drain" && (this._duplexState |= Jt, this._writableState.updateNextTick());
-}
-class Ts extends Zn {
- constructor(t) {
- super(), this._duplexState = 0, this._readableState = null, this._writableState = null, t && (t.open && (this._open = t.open), t.destroy && (this._destroy = t.destroy), t.predestroy && (this._predestroy = t.predestroy), t.signal && t.signal.addEventListener("abort", Rs.bind(this))), this.on("newListener", ks);
- }
- _open(t) {
- t(null);
- }
- _destroy(t) {
- t(null);
- }
- _predestroy() {
- }
- get readable() {
- return this._readableState !== null || void 0;
- }
- get writable() {
- return this._writableState !== null || void 0;
- }
- get destroyed() {
- return !!(8 & this._duplexState);
- }
- get destroying() {
- return !!(this._duplexState & nt);
- }
- destroy(t) {
- this._duplexState & nt || (t || (t = ie), this._duplexState = 535822271 & this._duplexState | 4, this._readableState !== null && (this._readableState.highWaterMark = 0, this._readableState.error = t), this._writableState !== null && (this._writableState.highWaterMark = 0, this._writableState.error = t), this._duplexState |= 2, this._predestroy(), this._duplexState &= ts, this._readableState !== null && this._readableState.updateNextTick(), this._writableState !== null && this._writableState.updateNextTick());
- }
-}
-class Ct extends Ts {
- constructor(t) {
- super(t), this._duplexState |= 8519681, this._readableState = new fs(this, t), t && (this._readableState.readAhead === !1 && (this._duplexState &= an), t.read && (this._read = t.read), t.eagerOpen && this._readableState.updateNextTick(), t.encoding && this.setEncoding(t.encoding));
- }
- setEncoding(t) {
- const e = new Xn(t), n = this._readableState.map || As;
- return this._readableState.map = function(s) {
- const r = e.push(s);
- return r === "" && (s.byteLength !== 0 || e.remaining > 0) ? null : n(r);
- }, this;
- }
- _read(t) {
- t(null);
- }
- pipe(t, e) {
- return this._readableState.updateNextTick(), this._readableState.pipe(t, e), t;
- }
- read() {
- return this._readableState.updateNextTick(), this._readableState.read();
- }
- push(t) {
- return this._readableState.updateNextTick(), this._readableState.push(t);
- }
- unshift(t) {
- return this._readableState.updateNextTick(), this._readableState.unshift(t);
- }
- resume() {
- return this._duplexState |= is, this._readableState.updateNextTick(), this;
- }
- pause() {
- return this._duplexState &= this._readableState.readAhead === !1 ? 536739583 : 536870655, this;
- }
- static _fromAsyncIterator(t, e) {
- let n;
- const s = new Ct({ ...e, read(o) {
- t.next().then(r).then(o.bind(null, null)).catch(o);
- }, predestroy() {
- n = t.return();
- }, destroy(o) {
- if (!n) return o(null);
- n.then(o.bind(null, null)).catch(o);
- } });
- return s;
- function r(o) {
- o.done ? s.push(null) : s.push(o.value);
- }
- }
- static from(t, e) {
- if (yn(n = t) && n.readable) return t;
- var n;
- if (t[ot]) return this._fromAsyncIterator(t[ot](), e);
- Array.isArray(t) || (t = t === void 0 ? [] : [t]);
- let s = 0;
- return new Ct({ ...e, read(r) {
- this.push(s === t.length ? null : t[s++]), r(null);
- } });
- }
- static isBackpressured(t) {
- return !!(17422 & t._duplexState) || t._readableState.buffered >= t._readableState.highWaterMark;
- }
- static isPaused(t) {
- return !(t._duplexState & rn);
- }
- [ot]() {
- const t = this;
- let e = null, n = null, s = null;
- return this.on("error", (a) => {
- e = a;
- }), this.on("readable", function() {
- n !== null && r(t.read());
- }), this.on("close", function() {
- n !== null && r(null);
- }), { [ot]() {
- return this;
- }, next: () => new Promise(function(a, h) {
- n = a, s = h;
- const u = t.read();
- u !== null ? r(u) : 8 & t._duplexState && r(null);
- }), return: () => o(null), throw: (a) => o(a) };
- function r(a) {
- s !== null && (e ? s(e) : a !== null || t._duplexState & St ? n({ value: a, done: a === null }) : s(ie), s = n = null);
- }
- function o(a) {
- return t.destroy(a), new Promise((h, u) => {
- if (8 & t._duplexState) return h({ value: void 0, done: !0 });
- t.once("close", function() {
- a ? u(a) : h({ value: void 0, done: !0 });
- });
- });
- }
- }
-}
-class xs extends Ct {
- constructor(t) {
- super(t), this._duplexState = 1 | this._duplexState & Gt, this._writableState = new ps(this, t), t && (t.writev && (this._writev = t.writev), t.write && (this._write = t.write), t.final && (this._final = t.final));
- }
- cork() {
- this._duplexState |= cs;
- }
- uncork() {
- this._duplexState &= ls, this._writableState.updateNextTick();
- }
- _writev(t, e) {
- e(null);
- }
- _write(t, e) {
- this._writableState.autoBatch(t, e);
- }
- _final(t) {
- t(null);
- }
- write(t) {
- return this._writableState.updateNextTick(), this._writableState.push(t);
- }
- end(t) {
- return this._writableState.updateNextTick(), this._writableState.end(t), this;
- }
-}
-function As(i) {
- return i;
-}
-function Ls(i) {
- return !!i._readableState || !!i._writableState;
-}
-function yn(i) {
- return typeof i._duplexState == "number" && Ls(i);
-}
-function _n(i) {
- return function(t) {
- return typeof t == "object" && t !== null && typeof t.byteLength == "number";
- }(i) ? i.byteLength : 1024;
-}
-function Le() {
-}
-function Rs() {
- this.destroy(new Error("Stream aborted."));
-}
-var Sn = xs;
-function Re(i, t) {
- for (const e in t) Object.defineProperty(i, e, { value: t[e], enumerable: !0, configurable: !0 });
- return i;
-}
-const y = W(function(i, t, e) {
- if (!i || typeof i == "string") throw new TypeError("Please pass an Error to err-code");
- e || (e = {}), typeof t == "object" && (e = t, t = ""), t && (e.code = t);
- try {
- return Re(i, e);
- } catch {
- e.message = i.message, e.stack = i.stack;
- const s = function() {
- };
- return s.prototype = Object.create(Object.getPrototypeOf(i)), Re(new s(), e);
- }
-}), vt = "0123456789abcdef", wn = [], kt = [];
-for (let i = 0; i < 256; i++) wn[i] = vt[i >> 4 & 15] + vt[15 & i], i < 16 && (i < 10 ? kt[48 + i] = i : kt[87 + i] = i);
-const V = (i) => {
- const t = i.length;
- let e = "", n = 0;
- for (; n < t; ) e += wn[i[n++]];
- return e;
-}, Vt = (i) => {
- const t = i.length >> 1, e = t << 1, n = new Uint8Array(t);
- let s = 0, r = 0;
- for (; r < e; ) n[s++] = kt[i.charCodeAt(r++)] << 4 | kt[i.charCodeAt(r++)];
- return n;
-};
-for (var Is = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", Es = typeof Uint8Array > "u" ? [] : new Uint8Array(256), at = 0; at < 64; at++) Es[Is.charCodeAt(at)] = at;
-const Ps = new TextDecoder(), bn = (i, t) => Ps.decode(i), qs = new TextEncoder(), re = (i) => qs.encode(i), Q = (i) => {
- let t, e = "", n = 0;
- const s = i.length;
- for (; n < s; ) t = i.charCodeAt(n++), e += vt[t >> 4] + vt[15 & t];
- return e;
-}, tt = (i) => {
- const t = Vt(i);
- if (t.length <= 65536) return String.fromCharCode(...t);
- let e = "", n = 0;
- for (; n < t.length; ) e += String.fromCharCode(...t.subarray(n, n += 65536));
- return e;
-}, Ie = typeof window < "u" ? window : self, Yt = Ie.crypto || Ie.msCrypto || {};
-Yt.subtle || Yt.webkitSubtle;
-const Tt = (i) => {
- const t = new Uint8Array(i);
- return Yt.getRandomValues(t);
-}, Bs = L("simple-peer"), Ot = 65536;
-function Ee(i) {
- return i.replace(/a=ice-options:trickle\s\n/g, "");
-}
-let et = class Kt extends Sn {
- constructor(e) {
- super(e = Object.assign({ allowHalfOpen: !1 }, e));
- d(this, "_pc");
- if (this.__objectMode = !!e.objectMode, this._id = V(Tt(4)).slice(0, 7), this._debug("new peer %o", e), this.channelName = e.initiator ? e.channelName || V(Tt(20)) : null, this.initiator = e.initiator || !1, this.channelConfig = e.channelConfig || Kt.channelConfig, this.channelNegotiated = this.channelConfig.negotiated, this.config = Object.assign({}, Kt.config, e.config), this.offerOptions = e.offerOptions || {}, this.answerOptions = e.answerOptions || {}, this.sdpTransform = e.sdpTransform || ((n) => n), this.trickle = e.trickle === void 0 || e.trickle, this.allowHalfTrickle = e.allowHalfTrickle !== void 0 && e.allowHalfTrickle, this.iceCompleteTimeout = e.iceCompleteTimeout || 5e3, 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, !zt) throw y(typeof window > "u" ? new Error("No WebRTC support: Specify `opts.wrtc` option in this environment") : new Error("No WebRTC support: Not a supported browser"), "ERR_WEBRTC_SUPPORT");
- this._pcReady = !1, this._channelReady = !1, this._iceComplete = !1, this._iceCompleteTimer = null, this._channel = null, this._pendingCandidates = [], this._isNegotiating = !1, this._firstNegotiation = !0, this._batchedNegotiation = !1, this._queuedNegotiation = !1, this._sendersAwaitingStable = [], this._closingInterval = null, this._remoteTracks = [], this._remoteStreams = [], this._chunk = null, this._cb = null, this._interval = null;
- try {
- this._pc = new zt(this.config);
- } catch (n) {
- return void this.__destroy(y(n, "ERR_PC_CONSTRUCTOR"));
- }
- this._isReactNativeWebrtc = typeof this._pc._peerConnectionId == "number", this._pc.oniceconnectionstatechange = () => {
- this._onIceStateChange();
- }, this._pc.onicegatheringstatechange = () => {
- this._onIceStateChange();
- }, this._pc.onconnectionstatechange = () => {
- this._onConnectionStateChange();
- }, this._pc.onsignalingstatechange = () => {
- this._onSignalingStateChange();
- }, this._pc.onicecandidate = (n) => {
- this._onIceCandidate(n);
- }, typeof this._pc.peerIdentity == "object" && this._pc.peerIdentity.catch((n) => {
- this.__destroy(y(n, "ERR_PC_PEER_IDENTITY"));
- }), this.initiator || this.channelNegotiated ? this._setupData({ channel: this._pc.createDataChannel(this.channelName, this.channelConfig) }) : this._pc.ondatachannel = (n) => {
- this._setupData(n);
- }, this._debug("initial negotiation"), this._needsNegotiation(), this._onFinishBound = () => {
- this._onFinish();
- }, this.once("finish", this._onFinishBound);
- }
- get bufferSize() {
- return this._channel && this._channel.bufferedAmount || 0;
- }
- get connected() {
- return this._connected && this._channel.readyState === "open";
- }
- address() {
- return { port: this.localPort, family: this.localFamily, address: this.localAddress };
- }
- signal(e) {
- if (!this._destroying) {
- if (this.destroyed) throw y(new Error("cannot signal after peer is destroyed"), "ERR_DESTROYED");
- if (typeof e == "string") try {
- e = JSON.parse(e);
- } catch {
- e = {};
- }
- this._debug("signal()"), e.renegotiate && this.initiator && (this._debug("got request to renegotiate"), this._needsNegotiation()), e.transceiverRequest && this.initiator && (this._debug("got request for transceiver"), this.addTransceiver(e.transceiverRequest.kind, e.transceiverRequest.init)), e.candidate && (this._pc.remoteDescription && this._pc.remoteDescription.type ? this._addIceCandidate(e.candidate) : this._pendingCandidates.push(e.candidate)), e.sdp && this._pc.setRemoteDescription(new Gn(e)).then(() => {
- this.destroyed || (this._pendingCandidates.forEach((n) => {
- this._addIceCandidate(n);
- }), this._pendingCandidates = [], this._pc.remoteDescription.type === "offer" && this._createAnswer());
- }).catch((n) => {
- this.__destroy(y(n, "ERR_SET_REMOTE_DESCRIPTION"));
- }), e.sdp || e.candidate || e.renegotiate || e.transceiverRequest || this.__destroy(y(new Error("signal() called with invalid signal data"), "ERR_SIGNALING"));
- }
- }
- _addIceCandidate(e) {
- const n = new Jn(e);
- this._pc.addIceCandidate(n).catch((s) => {
- var r;
- !n.address || n.address.endsWith(".local") ? (r = "Ignoring unsupported ICE candidate.", console.warn(r)) : this.__destroy(y(s, "ERR_ADD_ICE_CANDIDATE"));
- });
- }
- send(e) {
- if (!this._destroying) {
- if (this.destroyed) throw y(new Error("cannot send after peer is destroyed"), "ERR_DESTROYED");
- this._channel.send(e);
- }
- }
- _needsNegotiation() {
- this._debug("_needsNegotiation"), this._batchedNegotiation || (this._batchedNegotiation = !0, queueMicrotask(() => {
- this._batchedNegotiation = !1, this.initiator || !this._firstNegotiation ? (this._debug("starting batched negotiation"), this.negotiate()) : this._debug("non-initiator initial negotiation request discarded"), this._firstNegotiation = !1;
- }));
- }
- negotiate() {
- if (!this._destroying) {
- if (this.destroyed) throw y(new Error("cannot negotiate after peer is destroyed"), "ERR_DESTROYED");
- this.initiator ? this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("start negotiation"), setTimeout(() => {
- this._createOffer();
- }, 0)) : this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("requesting negotiation from initiator"), this.emit("signal", { type: "renegotiate", renegotiate: !0 })), this._isNegotiating = !0;
- }
- }
- _final(e) {
- this._readableState.ended || this.push(null), e(null);
- }
- __destroy(e) {
- this.end(), this._destroy(() => {
- }, e);
- }
- _destroy(e, n) {
- this.destroyed || this._destroying || (this._destroying = !0, this._debug("destroying (error: %s)", n && (n.message || n)), setTimeout(() => {
- if (this._connected = !1, this._pcReady = !1, this._channelReady = !1, this._remoteTracks = null, this._remoteStreams = null, this._senderMap = null, clearInterval(this._closingInterval), this._closingInterval = null, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._onFinishBound && this.removeListener("finish", this._onFinishBound), this._onFinishBound = null, this._channel) {
- try {
- this._channel.close();
- } catch {
- }
- this._channel.onmessage = null, this._channel.onopen = null, this._channel.onclose = null, this._channel.onerror = null;
- }
- if (this._pc) {
- try {
- this._pc.close();
- } catch {
- }
- this._pc.oniceconnectionstatechange = null, this._pc.onicegatheringstatechange = null, this._pc.onsignalingstatechange = null, this._pc.onicecandidate = null, this._pc.ontrack = null, this._pc.ondatachannel = null;
- }
- this._pc = null, this._channel = null, n && this.emit("error", n), e();
- }, 0));
- }
- _setupData(e) {
- if (!e.channel) return this.__destroy(y(new Error("Data channel event is missing `channel` property"), "ERR_DATA_CHANNEL"));
- this._channel = e.channel, this._channel.binaryType = "arraybuffer", typeof this._channel.bufferedAmountLowThreshold == "number" && (this._channel.bufferedAmountLowThreshold = Ot), this.channelName = this._channel.label, this._channel.onmessage = (s) => {
- this._onChannelMessage(s);
- }, this._channel.onbufferedamountlow = () => {
- this._onChannelBufferedAmountLow();
- }, this._channel.onopen = () => {
- this._onChannelOpen();
- }, this._channel.onclose = () => {
- this._onChannelClose();
- }, this._channel.onerror = (s) => {
- const r = s.error instanceof Error ? s.error : new Error(`Datachannel error: ${s.message} ${s.filename}:${s.lineno}:${s.colno}`);
- this.__destroy(y(r, "ERR_DATA_CHANNEL"));
- };
- let n = !1;
- this._closingInterval = setInterval(() => {
- this._channel && this._channel.readyState === "closing" ? (n && this._onChannelClose(), n = !0) : n = !1;
- }, 5e3);
- }
- _write(e, n) {
- if (this.destroyed) return n(y(new Error("cannot write after peer is destroyed"), "ERR_DATA_CHANNEL"));
- if (this._connected) {
- try {
- this.send(e);
- } catch (s) {
- return this.__destroy(y(s, "ERR_DATA_CHANNEL"));
- }
- this._channel.bufferedAmount > Ot ? (this._debug("start backpressure: bufferedAmount %d", this._channel.bufferedAmount), this._cb = n) : n(null);
- } else this._debug("write before connect"), this._chunk = e, this._cb = n;
- }
- _onFinish() {
- if (this.destroyed) return;
- const e = () => {
- setTimeout(() => this.__destroy(), 1e3);
- };
- this._connected ? e() : this.once("connect", e);
- }
- _startIceCompleteTimeout() {
- this.destroyed || this._iceCompleteTimer || (this._debug("started iceComplete timeout"), this._iceCompleteTimer = setTimeout(() => {
- this._iceComplete || (this._iceComplete = !0, this._debug("iceComplete timeout completed"), 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 = Ee(e.sdp)), e.sdp = this.sdpTransform(e.sdp);
- const n = () => {
- if (this.destroyed) return;
- const s = this._pc.localDescription || e;
- this._debug("signal"), this.emit("signal", { type: s.type, sdp: s.sdp });
- };
- this._pc.setLocalDescription(e).then(() => {
- this._debug("createOffer success"), this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n));
- }).catch((s) => {
- this.__destroy(y(s, "ERR_SET_LOCAL_DESCRIPTION"));
- });
- }).catch((e) => {
- this.__destroy(y(e, "ERR_CREATE_OFFER"));
- });
- }
- _createAnswer() {
- this.destroyed || this._pc.createAnswer(this.answerOptions).then((e) => {
- if (this.destroyed) return;
- this.trickle || this.allowHalfTrickle || (e.sdp = Ee(e.sdp)), e.sdp = this.sdpTransform(e.sdp);
- const n = () => {
- var r;
- if (this.destroyed) return;
- const s = this._pc.localDescription || e;
- this._debug("signal"), this.emit("signal", { type: s.type, sdp: s.sdp }), this.initiator || ((r = this._requestMissingTransceivers) == null || r.call(this));
- };
- this._pc.setLocalDescription(e).then(() => {
- this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n));
- }).catch((s) => {
- this.__destroy(y(s, "ERR_SET_LOCAL_DESCRIPTION"));
- });
- }).catch((e) => {
- this.__destroy(y(e, "ERR_CREATE_ANSWER"));
- });
- }
- _onConnectionStateChange() {
- this.destroyed || this._destroying || this._pc.connectionState === "failed" && this.__destroy(y(new Error("Connection failed."), "ERR_CONNECTION_FAILURE"));
- }
- _onIceStateChange() {
- if (this.destroyed) return;
- const e = this._pc.iceConnectionState, n = this._pc.iceGatheringState;
- this._debug("iceStateChange (connection: %s) (gathering: %s)", e, n), this.emit("iceStateChange", e, n), e !== "connected" && e !== "completed" || (this._pcReady = !0, this._maybeReady()), e === "failed" && this.__destroy(y(new Error("Ice connection failed."), "ERR_ICE_CONNECTION_FAILURE")), e === "closed" && this.__destroy(y(new Error("Ice connection closed."), "ERR_ICE_CONNECTION_CLOSED"));
- }
- getStats(e) {
- const n = (s) => (Object.prototype.toString.call(s.values) === "[object Array]" && s.values.forEach((r) => {
- Object.assign(s, r);
- }), s);
- this._pc.getStats.length === 0 || this._isReactNativeWebrtc ? this._pc.getStats().then((s) => {
- const r = [];
- s.forEach((o) => {
- r.push(n(o));
- }), e(null, r);
- }, (s) => e(s)) : this._pc.getStats.length > 0 ? this._pc.getStats((s) => {
- if (this.destroyed) return;
- const r = [];
- s.result().forEach((o) => {
- const a = {};
- o.names().forEach((h) => {
- a[h] = o.stat(h);
- }), a.id = o.id, a.type = o.type, a.timestamp = o.timestamp, r.push(n(a));
- }), e(null, r);
- }, (s) => e(s)) : e(null, []);
- }
- _maybeReady() {
- if (this._debug("maybeReady pc %s channel %s", this._pcReady, this._channelReady), this._connected || this._connecting || !this._pcReady || !this._channelReady) return;
- this._connecting = !0;
- const e = () => {
- this.destroyed || this._destroying || this.getStats((n, s) => {
- if (this.destroyed || this._destroying) return;
- n && (s = []);
- const r = {}, o = {}, a = {};
- let h = !1;
- s.forEach((c) => {
- c.type !== "remotecandidate" && c.type !== "remote-candidate" || (r[c.id] = c), c.type !== "localcandidate" && c.type !== "local-candidate" || (o[c.id] = c), c.type !== "candidatepair" && c.type !== "candidate-pair" || (a[c.id] = c);
- });
- const u = (c) => {
- h = !0;
- let l = o[c.localCandidateId];
- l && (l.ip || l.address) ? (this.localAddress = l.ip || l.address, this.localPort = Number(l.port)) : l && l.ipAddress ? (this.localAddress = l.ipAddress, this.localPort = Number(l.portNumber)) : typeof c.googLocalAddress == "string" && (l = c.googLocalAddress.split(":"), this.localAddress = l[0], this.localPort = Number(l[1])), this.localAddress && (this.localFamily = this.localAddress.includes(":") ? "IPv6" : "IPv4");
- let g = r[c.remoteCandidateId];
- g && (g.ip || g.address) ? (this.remoteAddress = g.ip || g.address, this.remotePort = Number(g.port)) : g && g.ipAddress ? (this.remoteAddress = g.ipAddress, this.remotePort = Number(g.portNumber)) : typeof c.googRemoteAddress == "string" && (g = c.googRemoteAddress.split(":"), this.remoteAddress = g[0], this.remotePort = Number(g[1])), this.remoteAddress && (this.remoteFamily = this.remoteAddress.includes(":") ? "IPv6" : "IPv4"), this._debug("connect local: %s:%s remote: %s:%s", this.localAddress, this.localPort, this.remoteAddress, this.remotePort);
- };
- if (s.forEach((c) => {
- c.type === "transport" && c.selectedCandidatePairId && u(a[c.selectedCandidatePairId]), (c.type === "googCandidatePair" && c.googActiveConnection === "true" || (c.type === "candidatepair" || c.type === "candidate-pair") && c.selected) && u(c);
- }), h || Object.keys(a).length && !Object.keys(o).length) {
- if (this._connecting = !1, this._connected = !0, this._chunk) {
- try {
- this.send(this._chunk);
- } catch (l) {
- return this.__destroy(y(l, "ERR_DATA_CHANNEL"));
- }
- this._chunk = null, this._debug('sent chunk from "write before connect"');
- const c = this._cb;
- this._cb = null, c(null);
- }
- typeof this._channel.bufferedAmountLowThreshold != "number" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect");
- } else setTimeout(e, 100);
- });
- };
- e();
- }
- _onInterval() {
- !this._cb || !this._channel || this._channel.bufferedAmount > Ot || this._onChannelBufferedAmountLow();
- }
- _onSignalingStateChange() {
- this.destroyed || (this._pc.signalingState === "stable" && (this._isNegotiating = !1, this._debug("flushing sender queue", this._sendersAwaitingStable), this._sendersAwaitingStable.forEach((e) => {
- this._pc.removeTrack(e), this._queuedNegotiation = !0;
- }), this._sendersAwaitingStable = [], this._queuedNegotiation ? (this._debug("flushing negotiation queue"), this._queuedNegotiation = !1, this._needsNegotiation()) : (this._debug("negotiated"), this.emit("negotiated"))), this._debug("signalingStateChange %s", this._pc.signalingState), 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 n = e.data;
- n instanceof ArrayBuffer ? n = new Uint8Array(n) : this.__objectMode === !1 && (n = re(n)), this.push(n);
- }
- _onChannelBufferedAmountLow() {
- if (this.destroyed || !this._cb) return;
- this._debug("ending backpressure: bufferedAmount %d", this._channel.bufferedAmount);
- const e = this._cb;
- this._cb = null, e(null);
- }
- _onChannelOpen() {
- this._connected || this.destroyed || (this._debug("on channel open"), this._channelReady = !0, this._maybeReady());
- }
- _onChannelClose() {
- this.destroyed || (this._debug("on channel close"), this.__destroy());
- }
- _debug() {
- const e = [].slice.call(arguments);
- e[0] = "[" + this._id + "] " + e[0], Bs.apply(null, e);
- }
-};
-et.WEBRTC_SUPPORT = !!zt, et.config = { iceServers: [{ urls: ["stun:stun.l.google.com:19302", "stun:global.stun.twilio.com:3478"] }], sdpSemantics: "unified-plan" }, et.channelConfig = {};
-const A = {}, Zt = { DEFAULT_ANNOUNCE_PEERS: 50, MAX_ANNOUNCE_PEERS: 82, parseUrl: (i) => {
- const t = new URL(i.replace(/^udp:/, "http:"));
- return i.match(/^udp:/) && Object.defineProperties(t, { href: { value: t.href.replace(/^http/, "udp") }, protocol: { value: t.protocol.replace(/^http/, "udp") }, origin: { value: t.origin.replace(/^http/, "udp") } }), t;
-}, ...Object.freeze(Object.defineProperty({ __proto__: null, default: A }, Symbol.toStringTag, { value: "Module" })) }, Os = L("simple-websocket"), Z = typeof A != "function" ? WebSocket : A;
-class Cn extends Sn {
- constructor(t = {}) {
- if (typeof t == "string" && (t = { url: t }), super(t = Object.assign({ allowHalfOpen: !1 }, t)), this.__objectMode = !!t.objectMode, t.objectMode != null && delete t.objectMode, t.url == null && t.socket == null) throw new Error("Missing required `url` or `socket` option");
- if (t.url != null && t.socket != null) throw new Error("Must specify either `url` or `socket` option, not both");
- if (this._id = V(Tt(4)).slice(0, 7), this._debug("new websocket: %o", t), this.connected = !1, this._chunk = null, this._cb = null, this._interval = null, t.socket) this.url = t.socket.url, this._ws = t.socket, this.connected = t.socket.readyState === Z.OPEN;
- else {
- this.url = t.url;
- try {
- this._ws = typeof A == "function" ? new Z(t.url, { ...t, encoding: void 0 }) : new Z(t.url);
- } catch (e) {
- return void Qt(() => this.destroy(e));
- }
- }
- this._ws.binaryType = "arraybuffer", t.socket && this.connected ? Qt(() => this._handleOpen()) : this._ws.onopen = () => this._handleOpen(), this._ws.onmessage = (e) => this._handleMessage(e), this._ws.onclose = () => this._handleClose(), this._ws.onerror = (e) => this._handleError(e), this._handleFinishBound = () => this._handleFinish(), this.once("finish", this._handleFinishBound);
- }
- send(t) {
- this._ws.send(t);
- }
- _final(t) {
- this._readableState.ended || this.push(null), t(null);
- }
- _destroy(t) {
- if (!this.destroyed) {
- if (this._writableState.ended || this.end(), this.connected = !1, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._handleFinishBound && this.removeListener("finish", this._handleFinishBound), this._handleFinishBound = null, this._ws) {
- const e = this._ws, n = () => {
- e.onclose = null;
- };
- if (e.readyState === Z.CLOSED) n();
- else try {
- e.onclose = n, e.close();
- } catch {
- n();
- }
- e.onopen = null, e.onmessage = null, e.onerror = () => {
- };
- }
- this._ws = null, t();
- }
- }
- _write(t, e) {
- if (this.destroyed) return e(new Error("cannot write after socket is destroyed"));
- if (this.connected) {
- try {
- this.send(t);
- } catch (n) {
- return this.destroy(n);
- }
- typeof A != "function" && this._ws.bufferedAmount > 65536 ? (this._debug("start backpressure: bufferedAmount %d", this._ws.bufferedAmount), this._cb = e) : e(null);
- } else this._debug("write before connect"), this._chunk = t, this._cb = e;
- }
- _handleOpen() {
- if (!this.connected && !this.destroyed) {
- if (this.connected = !0, this._chunk) {
- try {
- this.send(this._chunk);
- } catch (e) {
- return this.destroy(e);
- }
- this._chunk = null, this._debug('sent chunk from "write before connect"');
- const t = this._cb;
- this._cb = null, t(null);
- }
- typeof A != "function" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect");
- }
- }
- _handleMessage(t) {
- if (this.destroyed) return;
- let e = t.data;
- e instanceof ArrayBuffer && (e = new Uint8Array(e)), this.__objectMode === !1 && (e = re(e)), this.push(e);
- }
- _handleClose() {
- this.destroyed || (this._debug("on close"), this.destroy());
- }
- _handleError(t) {
- this.destroy(new Error(`Error connecting to ${this.url}`));
- }
- _handleFinish() {
- if (this.destroyed) return;
- const t = () => {
- setTimeout(() => this.destroy(), 1e3);
- };
- this.connected ? t() : this.once("connect", t);
- }
- _onInterval() {
- if (!this._cb || !this._ws || this._ws.bufferedAmount > 65536) return;
- this._debug("ending backpressure: bufferedAmount %d", this._ws.bufferedAmount);
- const t = this._cb;
- this._cb = null, t(null);
- }
- _debug() {
- const t = [].slice.call(arguments);
- t[0] = "[" + this._id + "] " + t[0], Os.apply(null, t);
- }
-}
-Cn.WEBSOCKET_SUPPORT = !!Z;
-class Ds extends Ke {
- constructor(t, e) {
- super(), this.client = t, this.announceUrl = e, this.interval = null, this.destroyed = !1;
- }
- setInterval(t) {
- t == null && (t = this.DEFAULT_ANNOUNCE_INTERVAL), clearInterval(this.interval), t && (this.interval = setInterval(() => {
- this.announce(this.client._defaultAnnounceOpts());
- }, t), this.interval.unref && this.interval.unref());
- }
-}
-const T = L("bittorrent-tracker:websocket-tracker"), I = {};
-class Xt extends Ds {
- constructor(t, e) {
- super(t, e), T("new websocket tracker %s", e), this.peers = {}, this.socket = null, this.reconnecting = !1, this.retries = 0, this.reconnectTimer = null, this.expectingResponse = !1, this._openSocket();
- }
- announce(t) {
- if (this.destroyed || this.reconnecting) return;
- if (!this.socket.connected) return void this.socket.once("connect", () => {
- this.announce(t);
- });
- const e = Object.assign({}, t, { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary });
- if (this._trackerId && (e.trackerid = this._trackerId), t.event === "stopped" || t.event === "completed") this._send(e);
- else {
- const n = Math.min(t.numwant, 5);
- this._generateOffers(n, (s) => {
- e.numwant = n, e.offers = s, this._send(e);
- });
- }
- }
- scrape(t) {
- if (this.destroyed || this.reconnecting) return;
- if (!this.socket.connected) return void this.socket.once("connect", () => {
- this.scrape(t);
- });
- const e = { action: "scrape", info_hash: Array.isArray(t.infoHash) && t.infoHash.length > 0 ? t.infoHash.map((n) => tt(n)) : t.infoHash && tt(t.infoHash) || this.client._infoHashBinary };
- this._send(e);
- }
- destroy(t = Pe) {
- if (this.destroyed) return t(null);
- this.destroyed = !0, clearInterval(this.interval), clearTimeout(this.reconnectTimer);
- for (const r in this.peers) {
- const o = this.peers[r];
- clearTimeout(o.trackerTimeout), o.destroy();
- }
- if (this.peers = null, this.socket && (this.socket.removeListener("connect", this._onSocketConnectBound), this.socket.removeListener("data", this._onSocketDataBound), this.socket.removeListener("close", this._onSocketCloseBound), this.socket.removeListener("error", this._onSocketErrorBound), this.socket = null), this._onSocketConnectBound = null, this._onSocketErrorBound = null, this._onSocketDataBound = null, this._onSocketCloseBound = null, I[this.announceUrl] && (I[this.announceUrl].consumers -= 1), I[this.announceUrl].consumers > 0) return t();
- let e, n = I[this.announceUrl];
- if (delete I[this.announceUrl], n.on("error", Pe), n.once("close", t), !this.expectingResponse) return s();
- function s() {
- e && (clearTimeout(e), e = null), n.removeListener("data", s), n.destroy(), n = null;
- }
- e = setTimeout(s, Zt.DESTROY_TIMEOUT), n.once("data", s);
- }
- _openSocket() {
- if (this.destroyed = !1, this.peers || (this.peers = {}), this._onSocketConnectBound = () => {
- this._onSocketConnect();
- }, this._onSocketErrorBound = (t) => {
- this._onSocketError(t);
- }, this._onSocketDataBound = (t) => {
- this._onSocketData(t);
- }, this._onSocketCloseBound = () => {
- this._onSocketClose();
- }, this.socket = I[this.announceUrl], this.socket) I[this.announceUrl].consumers += 1, this.socket.connected && this._onSocketConnectBound();
- else {
- const t = new URL(this.announceUrl);
- let e;
- this.client._proxyOpts && (e = t.protocol === "wss:" ? this.client._proxyOpts.httpsAgent : this.client._proxyOpts.httpAgent, !e && this.client._proxyOpts.socksProxy && (e = this.client._proxyOpts.socksProxy)), this.socket = I[this.announceUrl] = new Cn({ url: this.announceUrl, agent: e }), this.socket.consumers = 1, this.socket.once("connect", this._onSocketConnectBound);
- }
- this.socket.on("data", this._onSocketDataBound), this.socket.once("close", this._onSocketCloseBound), this.socket.once("error", this._onSocketErrorBound);
- }
- _onSocketConnect() {
- this.destroyed || this.reconnecting && (this.reconnecting = !1, this.retries = 0, this.announce(this.client._defaultAnnounceOpts()));
- }
- _onSocketData(t) {
- if (!this.destroyed) {
- this.expectingResponse = !1;
- try {
- t = JSON.parse(bn(t));
- } catch {
- return void this.client.emit("warning", new Error("Invalid tracker response"));
- }
- t.action === "announce" ? this._onAnnounceResponse(t) : t.action === "scrape" ? this._onScrapeResponse(t) : this._onSocketError(new Error(`invalid action in WS response: ${t.action}`));
- }
- }
- _onAnnounceResponse(t) {
- if (t.info_hash !== this.client._infoHashBinary) return void T("ignoring websocket data from %s for %s (looking for %s: reused socket)", this.announceUrl, Q(t.info_hash), this.client.infoHash);
- if (t.peer_id && t.peer_id === this.client._peerIdBinary) return;
- T("received %s from %s for %s", JSON.stringify(t), this.announceUrl, this.client.infoHash);
- const e = t["failure reason"];
- if (e) return this.client.emit("warning", new Error(e));
- const n = t["warning message"];
- n && this.client.emit("warning", new Error(n));
- const s = t.interval || t["min interval"];
- s && this.setInterval(1e3 * s);
- const r = t["tracker id"];
- if (r && (this._trackerId = r), t.complete != null) {
- const a = Object.assign({}, t, { announce: this.announceUrl, infoHash: Q(t.info_hash) });
- this.client.emit("update", a);
- }
- let o;
- if (t.offer && t.peer_id && (T("creating peer (from remote offer)"), o = this._createPeer(), o.id = Q(t.peer_id), o.once("signal", (a) => {
- const h = { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary, to_peer_id: t.peer_id, answer: a, offer_id: t.offer_id };
- this._trackerId && (h.trackerid = this._trackerId), this._send(h);
- }), this.client.emit("peer", o), o.signal(t.offer)), t.answer && t.peer_id) {
- const a = Q(t.offer_id);
- o = this.peers[a], o ? (o.id = Q(t.peer_id), this.client.emit("peer", o), o.signal(t.answer), clearTimeout(o.trackerTimeout), o.trackerTimeout = null, delete this.peers[a]) : T(`got unexpected answer: ${JSON.stringify(t.answer)}`);
- }
- }
- _onScrapeResponse(t) {
- t = t.files || {};
- const e = Object.keys(t);
- e.length !== 0 ? e.forEach((n) => {
- const s = Object.assign(t[n], { announce: this.announceUrl, infoHash: Q(n) });
- this.client.emit("scrape", s);
- }) : this.client.emit("warning", new Error("invalid scrape response"));
- }
- _onSocketClose() {
- this.destroyed || (this.destroy(), this._startReconnectTimer());
- }
- _onSocketError(t) {
- this.destroyed || (this.destroy(), this.client.emit("warning", t), this._startReconnectTimer());
- }
- _startReconnectTimer() {
- const t = Math.floor(3e5 * Math.random()) + Math.min(1e4 * Math.pow(2, this.retries), 36e5);
- this.reconnecting = !0, clearTimeout(this.reconnectTimer), this.reconnectTimer = setTimeout(() => {
- this.retries++, this._openSocket();
- }, t), this.reconnectTimer.unref && this.reconnectTimer.unref(), T("reconnecting socket in %s ms", t);
- }
- _send(t) {
- if (this.destroyed) return;
- this.expectingResponse = !0;
- const e = JSON.stringify(t);
- T("send %s", e), this.socket.send(e);
- }
- _generateOffers(t, e) {
- const n = this, s = [];
- T("generating %s offers", t);
- for (let a = 0; a < t; ++a) r();
- function r() {
- const a = V(Tt(20));
- T("creating peer (from _generateOffers)");
- const h = n.peers[a] = n._createPeer({ initiator: !0 });
- h.once("signal", (u) => {
- s.push({ offer: u, offer_id: tt(a) }), o();
- }), h.trackerTimeout = setTimeout(() => {
- T("tracker timeout: destroying peer"), h.trackerTimeout = null, delete n.peers[a], h.destroy();
- }, 5e4), h.trackerTimeout.unref && h.trackerTimeout.unref();
- }
- function o() {
- s.length === t && (T("generated %s offers", t), e(s));
- }
- o();
- }
- _createPeer(t) {
- const e = this;
- t = Object.assign({ trickle: !1, config: e.client._rtcConfig, wrtc: e.client._wrtc }, t);
- const n = new et(t);
- return n.once("error", s), n.once("connect", function r() {
- n.removeListener("error", s), n.removeListener("connect", r);
- }), n;
- function s(r) {
- e.client.emit("warning", new Error(`Connection error: ${r.message}`)), n.destroy();
- }
- }
-}
-function Pe() {
-}
-Xt.prototype.DEFAULT_ANNOUNCE_INTERVAL = 3e4, Xt._socketPool = I;
-const M = L("bittorrent-tracker:client");
-class te extends Ke {
- constructor(t = {}) {
- if (super(), !t.peerId) throw new Error("Option `peerId` is required");
- if (!t.infoHash) throw new Error("Option `infoHash` is required");
- if (!t.announce) throw new Error("Option `announce` is required");
- if (!ft.browser && !t.port) throw new Error("Option `port` is required");
- this.peerId = typeof t.peerId == "string" ? t.peerId : V(t.peerId), this._peerIdBuffer = Vt(this.peerId), this._peerIdBinary = tt(this.peerId), this.infoHash = typeof t.infoHash == "string" ? t.infoHash.toLowerCase() : V(t.infoHash), this._infoHashBuffer = Vt(this.infoHash), this._infoHashBinary = tt(this.infoHash), M("new client %s", this.infoHash), this.destroyed = !1, this._port = t.port, this._getAnnounceOpts = t.getAnnounceOpts, this._rtcConfig = t.rtcConfig, this._userAgent = t.userAgent, this._proxyOpts = t.proxyOpts, this._wrtc = typeof t.wrtc == "function" ? t.wrtc() : t.wrtc;
- let e = typeof t.announce == "string" ? [t.announce] : t.announce == null ? [] : t.announce;
- e = e.map((r) => (ArrayBuffer.isView(r) && (r = bn(r)), r[r.length - 1] === "/" && (r = r.substring(0, r.length - 1)), r)), e = Array.from(new Set(e));
- const n = this._wrtc !== !1 && (!!this._wrtc || et.WEBRTC_SUPPORT), s = (r) => {
- Qt(() => {
- this.emit("warning", r);
- });
- };
- this._trackers = e.map((r) => {
- let o;
- try {
- o = Zt.parseUrl(r);
- } catch {
- return s(new Error(`Invalid tracker URL: ${r}`)), null;
- }
- const a = o.port;
- if (a < 0 || a > 65535) return s(new Error(`Invalid tracker port: ${r}`)), null;
- const h = o.protocol;
- return h !== "http:" && h !== "https:" || typeof A != "function" ? h === "udp:" && typeof A == "function" ? new A(this, r) : h !== "ws:" && h !== "wss:" || !n || h === "ws:" && typeof window < "u" && window.location.protocol === "https:" ? (s(new Error(`Unsupported tracker protocol: ${r}`)), null) : new Xt(this, r) : new A(this, r);
- }).filter(Boolean);
- }
- start(t) {
- (t = this._defaultAnnounceOpts(t)).event = "started", M("send `start` %o", t), this._announce(t), this._trackers.forEach((e) => {
- e.setInterval();
- });
- }
- stop(t) {
- (t = this._defaultAnnounceOpts(t)).event = "stopped", M("send `stop` %o", t), this._announce(t);
- }
- complete(t) {
- t || (t = {}), (t = this._defaultAnnounceOpts(t)).event = "completed", M("send `complete` %o", t), this._announce(t);
- }
- update(t) {
- (t = this._defaultAnnounceOpts(t)).event && delete t.event, M("send `update` %o", t), this._announce(t);
- }
- _announce(t) {
- this._trackers.forEach((e) => {
- e.announce(t);
- });
- }
- scrape(t) {
- M("send `scrape`"), t || (t = {}), this._trackers.forEach((e) => {
- e.scrape(t);
- });
- }
- setInterval(t) {
- M("setInterval %d", t), this._trackers.forEach((e) => {
- e.setInterval(t);
- });
- }
- destroy(t) {
- if (this.destroyed) return;
- this.destroyed = !0, M("destroy");
- const e = this._trackers.map((n) => (s) => {
- n.destroy(s);
- });
- zn(e, t), this._trackers = [], this._getAnnounceOpts = null;
- }
- _defaultAnnounceOpts(t = {}) {
- return t.numwant == null && (t.numwant = Zt.DEFAULT_ANNOUNCE_PEERS), t.uploaded == null && (t.uploaded = 0), t.downloaded == null && (t.downloaded = 0), this._getAnnounceOpts && (t = Object.assign({}, t, this._getAnnounceOpts())), t;
- }
-}
-te.scrape = (i, t) => {
- if (t = jn(t), !i.infoHash) throw new Error("Option `infoHash` is required");
- if (!i.announce) throw new Error("Option `announce` is required");
- const e = Object.assign({}, i, { infoHash: Array.isArray(i.infoHash) ? i.infoHash[0] : i.infoHash, peerId: re("01234567890123456789"), port: 6881 }), n = new te(e);
- n.once("error", t), n.once("warning", t);
- let s = Array.isArray(i.infoHash) ? i.infoHash.length : 1;
- const r = {};
- return n.on("scrape", (o) => {
- if (s -= 1, r[o.infoHash] = o, s === 0) {
- n.destroy();
- const a = Object.keys(r);
- a.length === 1 ? t(null, r[a[0]]) : t(null, r);
- }
- }), n.scrape({ infoHash: i.infoHash }), n;
-};
-var vn = { exports: {} };
-function S(i, t, e, n, s, r, o) {
- var a = i + (t & e | ~t & n) + (s >>> 0) + o;
- return (a << r | a >>> 32 - r) + t;
-}
-function w(i, t, e, n, s, r, o) {
- var a = i + (t & n | e & ~n) + (s >>> 0) + o;
- return (a << r | a >>> 32 - r) + t;
-}
-function b(i, t, e, n, s, r, o) {
- var a = i + (t ^ e ^ n) + (s >>> 0) + o;
- return (a << r | a >>> 32 - r) + t;
-}
-function C(i, t, e, n, s, r, o) {
- var a = i + (e ^ (t | ~n)) + (s >>> 0) + o;
- return (a << r | a >>> 32 - r) + t;
-}
-function ht(i) {
- return String.fromCharCode(255 & i);
-}
-function ct(i) {
- return ht(i) + ht(i >>> 8) + ht(i >>> 16) + ht(i >>> 24);
-}
-var ee = function(i) {
- return unescape(encodeURIComponent(i));
-}, Rt = vn.exports = function(i) {
- return Ms(i).toHex();
-}, _t = Rt.fromBytes = function(i) {
- for (var t = function(m) {
- for (var f = m.length, v = f << 3, H = new Uint32Array(f + 72 >>> 6 << 4), D = 0, Et = m.length; D < Et; ++D) H[D >>> 2] |= m.charCodeAt(D) << ((3 & D) << 3);
- return H[f >> 2] |= 128 << (31 & v), H[H.length - 2] = v, H;
- }(i), e = 1732584193, n = 4023233417, s = 2562383102, r = 271733878, o = 0, a = t.length; o < a; o += 16) {
- var h = e, u = n, c = s, l = r;
- e = S(e, n, s, r, t[o + 0], 7, 3614090360), r = S(r, e, n, s, t[o + 1], 12, 3905402710), s = S(s, r, e, n, t[o + 2], 17, 606105819), n = S(n, s, r, e, t[o + 3], 22, 3250441966), e = S(e, n, s, r, t[o + 4], 7, 4118548399), r = S(r, e, n, s, t[o + 5], 12, 1200080426), s = S(s, r, e, n, t[o + 6], 17, 2821735955), n = S(n, s, r, e, t[o + 7], 22, 4249261313), e = S(e, n, s, r, t[o + 8], 7, 1770035416), r = S(r, e, n, s, t[o + 9], 12, 2336552879), s = S(s, r, e, n, t[o + 10], 17, 4294925233), n = S(n, s, r, e, t[o + 11], 22, 2304563134), e = S(e, n, s, r, t[o + 12], 7, 1804603682), r = S(r, e, n, s, t[o + 13], 12, 4254626195), s = S(s, r, e, n, t[o + 14], 17, 2792965006), e = w(e, n = S(n, s, r, e, t[o + 15], 22, 1236535329), s, r, t[o + 1], 5, 4129170786), r = w(r, e, n, s, t[o + 6], 9, 3225465664), s = w(s, r, e, n, t[o + 11], 14, 643717713), n = w(n, s, r, e, t[o + 0], 20, 3921069994), e = w(e, n, s, r, t[o + 5], 5, 3593408605), r = w(r, e, n, s, t[o + 10], 9, 38016083), s = w(s, r, e, n, t[o + 15], 14, 3634488961), n = w(n, s, r, e, t[o + 4], 20, 3889429448), e = w(e, n, s, r, t[o + 9], 5, 568446438), r = w(r, e, n, s, t[o + 14], 9, 3275163606), s = w(s, r, e, n, t[o + 3], 14, 4107603335), n = w(n, s, r, e, t[o + 8], 20, 1163531501), e = w(e, n, s, r, t[o + 13], 5, 2850285829), r = w(r, e, n, s, t[o + 2], 9, 4243563512), s = w(s, r, e, n, t[o + 7], 14, 1735328473), e = b(e, n = w(n, s, r, e, t[o + 12], 20, 2368359562), s, r, t[o + 5], 4, 4294588738), r = b(r, e, n, s, t[o + 8], 11, 2272392833), s = b(s, r, e, n, t[o + 11], 16, 1839030562), n = b(n, s, r, e, t[o + 14], 23, 4259657740), e = b(e, n, s, r, t[o + 1], 4, 2763975236), r = b(r, e, n, s, t[o + 4], 11, 1272893353), s = b(s, r, e, n, t[o + 7], 16, 4139469664), n = b(n, s, r, e, t[o + 10], 23, 3200236656), e = b(e, n, s, r, t[o + 13], 4, 681279174), r = b(r, e, n, s, t[o + 0], 11, 3936430074), s = b(s, r, e, n, t[o + 3], 16, 3572445317), n = b(n, s, r, e, t[o + 6], 23, 76029189), e = b(e, n, s, r, t[o + 9], 4, 3654602809), r = b(r, e, n, s, t[o + 12], 11, 3873151461), s = b(s, r, e, n, t[o + 15], 16, 530742520), e = C(e, n = b(n, s, r, e, t[o + 2], 23, 3299628645), s, r, t[o + 0], 6, 4096336452), r = C(r, e, n, s, t[o + 7], 10, 1126891415), s = C(s, r, e, n, t[o + 14], 15, 2878612391), n = C(n, s, r, e, t[o + 5], 21, 4237533241), e = C(e, n, s, r, t[o + 12], 6, 1700485571), r = C(r, e, n, s, t[o + 3], 10, 2399980690), s = C(s, r, e, n, t[o + 10], 15, 4293915773), n = C(n, s, r, e, t[o + 1], 21, 2240044497), e = C(e, n, s, r, t[o + 8], 6, 1873313359), r = C(r, e, n, s, t[o + 15], 10, 4264355552), s = C(s, r, e, n, t[o + 6], 15, 2734768916), n = C(n, s, r, e, t[o + 13], 21, 1309151649), e = C(e, n, s, r, t[o + 4], 6, 4149444226), r = C(r, e, n, s, t[o + 11], 10, 3174756917), s = C(s, r, e, n, t[o + 2], 15, 718787259), n = C(n, s, r, e, t[o + 9], 21, 3951481745), e = e + h >>> 0, n = n + u >>> 0, s = s + c >>> 0, r = r + l >>> 0;
- }
- var g = new String(ct(e) + ct(n) + ct(s) + ct(r));
- return g.toHex = function() {
- for (var m = "", f = 0, v = g.length; f < v; ++f) m += (256 + (255 & g.charCodeAt(f))).toString(16).substr(-2);
- return m;
- }, g;
-}, Ms = Rt.fromUtf8 = function(i) {
- return _t(ee(i));
-}, kn = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-function qe(i, t) {
- for (var e = ""; --t >= 0; i >>>= 6) e += kn.charAt(63 & i);
- return e;
-}
-var dt = [0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5, 11], Ns = Rt.salt = function(i) {
- var t = "";
- i || (i = 8);
- do
- t += kn.charAt(64 * Math.random() >>> 0);
- while (--i);
- return t;
-};
-Rt.crypt = function(i, t) {
- if (i.length > 64) throw Error("too long key");
- t || (t = "$1$" + Ns()), i = ee(i);
- for (var e = ee(t.replace(/^\$1\$([^$]+)(?:\$.*)?$/, "$1")), n = _t(i + e + i), s = i + "$1$" + e, r = i.length; r > 16; r -= 16) s += n;
- for (s += n.slice(0, r), r = i.length; r; r >>= 1) s += 1 & r ? "\0" : i.charAt(0);
- n = _t(s);
- for (var o = 0; o < 1e3; ++o) n = _t((1 & o ? i : n) + (o % 3 ? e : "") + (o % 7 ? i : "") + (1 & o ? n : i));
- var a = "$1$" + e + "$";
- for (o = 0; o < 15; o += 3) a += qe(n.charCodeAt(dt[o + 0]) << 16 | n.charCodeAt(dt[o + 1]) << 8 | n.charCodeAt(dt[o + 2]), 4);
- return a + qe(n.charCodeAt(dt[15]), 2);
-};
-const Us = W(vn.exports), Fs = `-PM${function(i) {
- const t = i.split(".");
- return `${t[0].padStart(2, "0")}${t[1].padStart(2, "0")}`;
-}("2.1.0")}-`, Hs = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-function F(i) {
- return `${i.type}-${i.index}`;
-}
-function Be(i) {
- const { externalId: t } = i;
- return `(${F(i.stream)} | ${t})`;
-}
-function Tn(i, t) {
- t === void 0 && (t = i.reduce((s, r) => s + r.byteLength, 0));
- const e = new Uint8Array(t);
- let n = 0;
- for (const s of i) e.set(s, n), n += s.byteLength;
- return e;
-}
-function Oe(i) {
- const t = new TextEncoder(), e = new Uint8Array(i.length);
- return t.encodeInto(i, e), e;
-}
-function* De(i) {
- for (let t = i.length - 1; t >= 0; t--) yield i[t];
-}
-function xn(i) {
- return !!i && typeof i == "object" && !Array.isArray(i);
-}
-function U(i) {
- if (function(t) {
- return Array.isArray(t);
- }(i)) return i.map((t) => U(t));
- if (xn(i)) {
- const t = {};
- for (const e of Object.keys(i)) t[e] = U(i[e]);
- return t;
- }
- return i;
-}
-function K(i, t, e = {}) {
- return typeof i != "object" || i === null || typeof t != "object" || t === null || Object.keys(t).forEach((n) => {
- if (n === "__proto__" || n === "constructor" || n === "prototype") throw new Error(`Attempt to modify restricted property '${String(n)}'`);
- const s = t[n], r = e[n];
- n in i && (i[n] = s === void 0 ? r === void 0 ? void 0 : r : s);
- }), i;
-}
-function Dt(i) {
- const { defaultConfig: t, baseConfig: e = {}, specificStreamConfig: n = {} } = i, s = U({ ...t, ...e, ...n }), r = Object.keys(t), o = {};
- return r.forEach((a) => {
- a in s && (o[a] = s[a]);
- }), o;
-}
-var N = ((i) => (i[i.SegmentsAnnouncement = 0] = "SegmentsAnnouncement", i[i.SegmentRequest = 1] = "SegmentRequest", i[i.SegmentData = 2] = "SegmentData", i[i.SegmentDataSendingCompleted = 3] = "SegmentDataSendingCompleted", i[i.SegmentAbsent = 4] = "SegmentAbsent", i[i.CancelSegmentRequest = 5] = "CancelSegmentRequest", i))(N || {}), J = ((i) => (i[i.Min = -1] = "Min", i[i.Int = 0] = "Int", i[i.SimilarIntArray = 1] = "SimilarIntArray", i[i.String = 2] = "String", i[i.Max = 3] = "Max", i))(J || {});
-function $s(i) {
- const t = i < 0, e = function(r) {
- const o = r.toString(2), a = r < 0 ? o.length : o.length + 1;
- return Math.ceil(a / 8);
- }(i), n = new Uint8Array(e), s = BigInt(e);
- i = function(r) {
- return r < 0 ? -r : r;
- }(i);
- for (let r = 0; r < e; r++) {
- const o = i >> 8n * (s - 1n - BigInt(r)) & 0xffn;
- n[r] = Number(o);
- }
- return t && (n[0] = 128 | n[0]), n;
-}
-function js(i) {
- const t = BigInt(i.length), e = (s, r) => {
- const o = 8n * (t - 1n - BigInt(r));
- return BigInt(s) << o;
- };
- let n = e(127 & i[0], 0);
- for (let s = 1; s < t; s++) n = e(i[s], s) | n;
- return (128 & i[0]) >> 7 && (n = -n), n;
-}
-function Me(i) {
- const t = $s(i), e = 0 | t.length;
- return new Uint8Array([e, ...t]);
-}
-function An(i) {
- const t = i[0];
- if (t >> 4) throw new Error("Trying to deserialize integer with invalid serialized item code");
- const e = 15 & t, n = 1 + e;
- return { number: js(i.slice(1, n)), byteLength: e + 1 };
-}
-function Ws(i) {
- const [t, e] = i;
- if (t >> 4 !== 1) throw new Error("Trying to deserialize similar int array with invalid serialized item code");
- let n = 2;
- const s = [];
- for (let r = 0; r < e; r++) {
- const { number: o, byteLength: a } = An(i.slice(n));
- n += a;
- const h = 0xffn & o, u = -256n & o;
- for (let c = 0; c < h; c++) {
- const l = BigInt(i[n]);
- s.push(u | l), n++;
- }
- }
- return { numbers: s, byteLength: n };
-}
-function Qs(i) {
- const [t, e] = i;
- if (t >> 4 !== 2) throw new Error("Trying to deserialize bytes (sting) with invalid serialized item code.");
- const n = (15 & t) << 8 | e, s = i.slice(2, n + 2);
- return { string: new TextDecoder("utf8").decode(s), byteLength: n + 2 };
-}
-class X {
- constructor() {
- d(this, "bytes", []);
- d(this, "_length", 0);
- }
- push(t) {
- this.addBytes(t, "end");
- }
- unshift(t) {
- this.addBytes(t, "start");
- }
- addBytes(t, e) {
- let n;
- n = t instanceof Uint8Array ? t : Array.isArray(t) ? new Uint8Array(t) : new Uint8Array([t]), this._length += n.length, this.bytes[e === "start" ? "unshift" : "push"](n);
- }
- getBytesChunks() {
- return this.bytes;
- }
- getBuffer() {
- return Tn(this.bytes, this._length);
- }
- get length() {
- return this._length;
- }
-}
-const Y = It("cstr", 4), st = It("cend", 4), ne = It("dstr", 4), se = It("dend", 4), zs = [Y, ne], Gs = [st, se], Ne = Y.length + st.length;
-function Ln(i) {
- const { length: t } = Y, e = i.slice(-t);
- return zs.some((n) => At(i, n, 4)) && Gs.some((n) => At(e, n, 4));
-}
-class xt extends Error {
- constructor(t) {
- super(), this.type = t;
- }
-}
-class Rn {
- constructor(t) {
- d(this, "chunks", new X());
- d(this, "status", "joining");
- this.onComplete = t;
- }
- addCommandChunk(t) {
- if (this.status === "completed") return;
- const e = At(t, Y, 4);
- if (!this.chunks.length && !e) throw new xt("no-first-chunk");
- if (this.chunks.length && e) throw new xt("incomplete-joining");
- this.chunks.push(this.unframeCommandChunk(t)), function(n) {
- return At(n.slice(-4), st, 4);
- }(t) && (this.status = "completed", this.onComplete(this.chunks.getBuffer()));
- }
- unframeCommandChunk(t) {
- return t.slice(4, t.length - 4);
- }
-}
-class lt {
- constructor(t, e) {
- d(this, "bytes", new X());
- d(this, "resultBuffers", []);
- d(this, "status", "creating");
- this.maxChunkLength = e, this.bytes.push(t);
- }
- addInteger(t, e) {
- this.bytes.push(t.charCodeAt(0));
- const n = Me(BigInt(e));
- this.bytes.push(n);
- }
- addSimilarIntArr(t, e) {
- this.bytes.push(t.charCodeAt(0));
- const n = function(s) {
- const r = /* @__PURE__ */ new Map();
- for (const a of s) {
- const h = -256n & a, u = 0xffn & a, c = r.get(h) ?? new X();
- c.length || r.set(h, c), c.push(Number(u));
- }
- const o = new X();
- o.push([16, r.size]);
- for (const [a, h] of r) {
- const { length: u } = h.getBytesChunks(), c = a | 0xffn & BigInt(u);
- h.unshift(Me(c)), o.push(h.getBuffer());
- }
- return o.getBuffer();
- }(e.map((s) => BigInt(s)));
- this.bytes.push(n);
- }
- addString(t, e) {
- this.bytes.push(t.charCodeAt(0));
- const n = function(s) {
- const { length: r } = s, o = new X();
- return o.push([32 | r >> 8 & 15, 255 & r]), o.push(new TextEncoder().encode(s)), o.getBuffer();
- }(e);
- this.bytes.push(n);
- }
- complete() {
- if (!this.bytes.length) throw new Error("Buffer is empty");
- if (this.status === "completed") return;
- this.status = "completed";
- const t = this.bytes.getBuffer();
- if (t.length + Ne <= this.maxChunkLength) return void this.resultBuffers.push(ut(t, Y, st));
- let e = Math.ceil(t.length / this.maxChunkLength);
- Math.ceil(t.length / e) + Ne > this.maxChunkLength && e++;
- for (const [n, s] of function* (r, o) {
- const a = Math.ceil(r.length / o);
- for (let h = 0; h < o; h++) yield [h, r.slice(h * a, (h + 1) * a)];
- }(t, e)) n === 0 ? this.resultBuffers.push(ut(s, Y, se)) : n === e - 1 ? this.resultBuffers.push(ut(s, ne, st)) : this.resultBuffers.push(ut(s, ne, se));
- }
- getResultBuffers() {
- if (this.status === "creating" || !this.resultBuffers.length) throw new Error("Command is not complete.");
- return this.resultBuffers;
- }
-}
-function In(i) {
- const [t] = i, e = { c: t };
- let n = 1;
- for (; n < i.length; ) {
- const s = String.fromCharCode(i[n]);
- switch (n++, Js(i[n])) {
- case J.Int:
- {
- const { number: r, byteLength: o } = An(i.slice(n));
- e[s] = Number(r), n += o;
- }
- break;
- case J.SimilarIntArray:
- {
- const { numbers: r, byteLength: o } = Ws(i.slice(n));
- e[s] = r.map((a) => Number(a)), n += o;
- }
- break;
- case J.String: {
- const { string: r, byteLength: o } = Qs(i.slice(n));
- e[s] = r, n += o;
- }
- }
- }
- return e;
-}
-function Js(i) {
- const t = i >> 4;
- if (t <= J.Min || t >= J.Max) throw new Error("Not existing type");
- return t;
-}
-function It(i, t) {
- if (i.length !== t) throw new Error("Wrong string length");
- const e = new Uint8Array(t);
- for (let n = 0; n < i.length; n++) e[n] = i.charCodeAt(n);
- return e;
-}
-function ut(i, t, e) {
- const n = new Uint8Array(i.length + t.length + e.length);
- return n.set(t), n.set(i, t.length), n.set(e, t.length + i.length), n;
-}
-function At(i, t, e) {
- for (let n = 0; n < e; n++) if (i[n] !== t[n]) return !1;
- return !0;
-}
-function En(i, t) {
- switch (i.c) {
- case N.CancelSegmentRequest:
- case N.SegmentAbsent:
- case N.SegmentDataSendingCompleted:
- return function(e, n) {
- const s = new lt(e.c, n);
- return s.addInteger("i", e.i), s.addInteger("r", e.r), s.complete(), s.getResultBuffers();
- }(i, t);
- case N.SegmentRequest:
- return function(e, n) {
- const s = new lt(e.c, n);
- return s.addInteger("i", e.i), s.addInteger("r", e.r), e.b && s.addInteger("b", e.b), s.complete(), s.getResultBuffers();
- }(i, t);
- case N.SegmentsAnnouncement:
- return function(e, n) {
- const { c: s, p: r, l: o } = e, a = new lt(s, n);
- return o != null && o.length && a.addSimilarIntArr("l", o), r != null && r.length && a.addSimilarIntArr("p", r), a.complete(), a.getResultBuffers();
- }(i, t);
- case N.SegmentData:
- return function(e, n) {
- const s = new lt(e.c, n);
- return s.addInteger("i", e.i), s.addInteger("s", e.s), s.addInteger("r", e.r), s.complete(), s.getResultBuffers();
- }(i, t);
- }
-}
-const Vs = Object.freeze(Object.defineProperty({ __proto__: null, BinaryCommandChunksJoiner: Rn, BinaryCommandJoiningError: xt, PeerCommandType: N, deserializeCommand: In, isCommandChunk: Ln, serializePeerCommand: En }, Symbol.toStringTag, { value: "Module" }));
-class Ys {
- constructor(t, e, n, s) {
- d(this, "commandChunks");
- d(this, "uploadingContext");
- d(this, "onChunkDownloaded");
- d(this, "onChunkUploaded");
- d(this, "onDataReceived", (t) => {
- Ln(t) ? this.receivingCommandBytes(t) : (this.eventHandlers.onSegmentChunkReceived(t), this.onChunkDownloaded(t.byteLength, "p2p", this.connection.idUtf8));
- });
- this.connection = t, this.peerConfig = e, this.eventHandlers = n, this.onChunkDownloaded = s.getEventDispatcher("onChunkDownloaded"), this.onChunkUploaded = s.getEventDispatcher("onChunkUploaded"), t.on("data", this.onDataReceived);
- }
- sendCommand(t) {
- const e = En(t, this.peerConfig.webRtcMaxMessageSize);
- for (const n of e) this.connection.write(n);
- }
- stopUploadingSegmentData() {
- var t;
- (t = this.uploadingContext) == null || t.stopUploading(), this.uploadingContext = void 0;
- }
- getUploadingRequestId() {
- var t;
- return (t = this.uploadingContext) == null ? void 0 : t.requestId;
- }
- async splitSegmentDataToChunksAndUploadAsync(t, e) {
- if (this.uploadingContext) throw new Error("Some segment data is already uploading.");
- const n = function* (c, l) {
- let g = c.byteLength;
- for (; g > 0; ) {
- const m = g >= l ? l : g, f = c.byteLength - g, v = c.slice(f, f + m);
- g -= m, yield v;
- }
- }(t, this.peerConfig.webRtcMaxMessageSize), { promise: s, resolve: r, reject: o } = function() {
- let c, l;
- return { promise: new Promise((g, m) => {
- c = g, l = m;
- }), resolve: c, reject: l };
- }();
- let a = !1;
- const h = { stopUploading: () => {
- a = !1;
- }, requestId: e };
- this.uploadingContext = h;
- const u = () => {
- if (a) for (; ; ) {
- const c = n.next().value;
- if (!c) {
- r();
- break;
- }
- const l = this.connection.write(c);
- if (this.onChunkUploaded(c.byteLength, this.connection.idUtf8), !l) break;
- }
- else o();
- };
- try {
- this.connection.on("drain", u), a = !0, u(), await s;
- } finally {
- this.connection.off("drain", u), this.uploadingContext === h && (this.uploadingContext = void 0);
- }
- }
- receivingCommandBytes(t) {
- this.commandChunks || (this.commandChunks = new Rn((e) => {
- this.commandChunks = void 0;
- const n = In(e);
- this.eventHandlers.onCommandReceived(n);
- }));
- try {
- this.commandChunks.addCommandChunk(t);
- } catch (e) {
- if (!(e instanceof xt)) return;
- this.commandChunks = void 0;
- }
- }
-}
-const { PeerCommandType: k } = Vs;
-class Lt {
- constructor(t, e, n, s, r) {
- d(this, "id");
- d(this, "peerProtocol");
- d(this, "downloadingContext");
- d(this, "loadedSegments", /* @__PURE__ */ new Set());
- d(this, "httpLoadingSegments", /* @__PURE__ */ new Set());
- d(this, "downloadingErrors", []);
- d(this, "logger", L("p2pml-core:peer"));
- d(this, "onPeerClosed");
- d(this, "onCommandReceived", async (t) => {
- var e, n, s;
- switch (t.c) {
- case k.SegmentsAnnouncement:
- this.loadedSegments = new Set(t.l), this.httpLoadingSegments = new Set(t.p), this.eventHandlers.onSegmentsAnnouncement();
- break;
- case k.SegmentRequest:
- this.peerProtocol.stopUploadingSegmentData(), this.eventHandlers.onSegmentRequested(this, t.i, t.r, t.b);
- break;
- case k.SegmentData:
- {
- if (!this.downloadingContext || this.downloadingContext.isSegmentDataCommandReceived) break;
- const { request: r, controls: o, requestId: a } = this.downloadingContext;
- if (r.segment.externalId !== t.i || a !== t.r) break;
- this.downloadingContext.isSegmentDataCommandReceived = !0, o.firstBytesReceived(), r.totalBytes === void 0 ? r.setTotalBytes(t.s) : r.totalBytes - r.loadedBytes !== t.s && (r.clearLoadedBytes(), this.sendCancelSegmentRequestCommand(r.segment, a), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), this.destroy());
- }
- break;
- case k.SegmentDataSendingCompleted: {
- const { downloadingContext: r } = this;
- if (!(r != null && r.isSegmentDataCommandReceived)) return;
- const { request: o, controls: a } = r;
- if (r.request.segment.externalId !== t.i || r.requestId !== t.r) return o.clearLoadedBytes(), this.cancelSegmentDownloading("peer-protocol-violation"), void this.destroy();
- if (o.loadedBytes !== o.totalBytes) return o.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy();
- const h = await ((n = (e = this.peerConfig).validateP2PSegment) == null ? void 0 : n.call(e, o.segment.url, o.segment.byteRange, o.data)) ?? !0;
- if (this.downloadingContext !== r) return;
- if (!h) return o.clearLoadedBytes(), this.cancelSegmentDownloading("p2p-segment-validation-failed"), void this.destroy();
- this.downloadingErrors = [], a.completeOnSuccess(), this.downloadingContext = void 0;
- break;
- }
- case k.SegmentAbsent:
- ((s = this.downloadingContext) == null ? void 0 : s.request.segment.externalId) === t.i && this.downloadingContext.requestId === t.r && (this.cancelSegmentDownloading("peer-segment-absent"), this.loadedSegments.delete(t.i));
- break;
- case k.CancelSegmentRequest:
- if (this.peerProtocol.getUploadingRequestId() !== t.r) break;
- this.peerProtocol.stopUploadingSegmentData();
- break;
- }
- });
- d(this, "onSegmentChunkReceived", (t) => {
- var s;
- if (!((s = this.downloadingContext) != null && s.isSegmentDataCommandReceived)) return;
- const { request: e, controls: n } = this.downloadingContext;
- if (e.totalBytes !== void 0 && e.loadedBytes + t.byteLength > e.totalBytes) return e.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy();
- n.addLoadedChunk(t);
- });
- d(this, "onPeerConnectionClosed", () => {
- this.destroy();
- });
- d(this, "onConnectionError", (t) => {
- this.logger(`peer connection error ${this.id} %O`, t), this.eventTarget.getEventDispatcher("onPeerError")({ peerId: this.id, streamType: this.streamType, error: t });
- const { code: e } = t;
- (e === "ERR_DATA_CHANNEL" || e === "ERR_CONNECTION_FAILURE") && this.destroy();
- });
- d(this, "destroy", () => {
- this.cancelSegmentDownloading("peer-closed"), this.connection.destroy(), this.eventHandlers.onPeerClosed(this), this.onPeerClosed({ peerId: this.id, streamType: this.streamType }), this.logger(`peer closed ${this.id}`);
- });
- this.connection = t, this.eventHandlers = e, this.peerConfig = n, this.streamType = s, this.eventTarget = r, this.onPeerClosed = r.getEventDispatcher("onPeerClose"), this.id = Lt.getPeerIdFromConnection(t), this.peerProtocol = new Ys(t, n, { onSegmentChunkReceived: this.onSegmentChunkReceived, onCommandReceived: this.onCommandReceived }, r), r.getEventDispatcher("onPeerConnect")({ peerId: this.id, streamType: s }), t.on("error", this.onConnectionError), t.on("close", this.onPeerConnectionClosed), t.on("end", this.onPeerConnectionClosed), t.on("finish", this.onPeerConnectionClosed);
- }
- get downloadingSegment() {
- var t;
- return (t = this.downloadingContext) == null ? void 0 : t.request.segment;
- }
- getSegmentStatus(t) {
- const { externalId: e } = t;
- return this.loadedSegments.has(e) ? "loaded" : this.httpLoadingSegments.has(e) ? "http-loading" : void 0;
- }
- downloadSegment(t) {
- if (this.downloadingContext) throw new Error("Some segment already is downloading");
- this.downloadingContext = { request: t, requestId: Math.floor(1e3 * Math.random()), isSegmentDataCommandReceived: !1, controls: t.start({ downloadSource: "p2p", peerId: this.id }, { notReceivingBytesTimeoutMs: this.peerConfig.p2pNotReceivingBytesTimeoutMs, abort: (n) => {
- if (!this.downloadingContext) return;
- const { request: s, requestId: r } = this.downloadingContext;
- this.sendCancelSegmentRequestCommand(s.segment, r), this.downloadingErrors.push(n), this.downloadingContext = void 0, this.downloadingErrors.filter((o) => o.type === "bytes-receiving-timeout").length >= this.peerConfig.p2pErrorRetries && this.destroy();
- } }) };
- const e = { c: k.SegmentRequest, r: this.downloadingContext.requestId, i: t.segment.externalId };
- t.loadedBytes && (e.b = t.loadedBytes), this.peerProtocol.sendCommand(e);
- }
- async uploadSegmentData(t, e, n) {
- const { externalId: s } = t;
- this.logger(`send segment ${t.externalId} to ${this.id}`);
- const r = { c: k.SegmentData, i: s, r: e, s: n.byteLength };
- this.peerProtocol.sendCommand(r);
- try {
- await this.peerProtocol.splitSegmentDataToChunksAndUploadAsync(n, e), this.sendSegmentDataSendingCompletedCommand(t, e), this.logger(`segment ${s} has been sent to ${this.id}`);
- } catch {
- this.logger(`cancel segment uploading ${s}`);
- }
- }
- cancelSegmentDownloading(t) {
- if (!this.downloadingContext) return;
- const { request: e, controls: n } = this.downloadingContext, { segment: s } = e;
- this.logger(`cancel segment request ${s.externalId} (${t})`);
- const r = new x(t);
- n.abortOnError(r), this.downloadingContext = void 0, this.downloadingErrors.push(r);
- }
- sendSegmentsAnnouncementCommand(t, e) {
- const n = { c: k.SegmentsAnnouncement, p: e, l: t };
- this.peerProtocol.sendCommand(n);
- }
- sendSegmentAbsentCommand(t, e) {
- this.peerProtocol.sendCommand({ c: k.SegmentAbsent, i: t, r: e });
- }
- sendCancelSegmentRequestCommand(t, e) {
- this.peerProtocol.sendCommand({ c: k.CancelSegmentRequest, i: t.externalId, r: e });
- }
- sendSegmentDataSendingCompletedCommand(t, e) {
- this.peerProtocol.sendCommand({ c: k.SegmentDataSendingCompleted, r: e, i: t.externalId });
- }
- static getPeerIdFromConnection(t) {
- return function(e) {
- const n = new Uint8Array(e.length / 2);
- for (let s = 0; s < e.length; s += 2) n[s / 2] = parseInt(e.slice(s, s + 2), 16);
- return new TextDecoder().decode(n);
- }(t.id);
- }
-}
-function Ks() {
- const i = /^((?!chrome|android).)*safari/i.test(navigator.userAgent), t = /\b(iPad|iPhone|Macintosh).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
- return i || t;
-}
-class Zs {
- constructor(t, e, n, s, r) {
- d(this, "streamShortId");
- d(this, "client");
- d(this, "_peers", /* @__PURE__ */ new Map());
- d(this, "logger", L("p2pml-core:p2p-tracker-client"));
- d(this, "onReceivePeerConnection", (t) => {
- const e = Lt.getPeerIdFromConnection(t);
- let n = this._peers.get(e);
- n != null && n.peer ? t.destroy() : (n || (n = { potentialConnections: /* @__PURE__ */ new Set() }, t.idUtf8 = e, n.potentialConnections.add(t), this._peers.set(e, n)), t.on("connect", () => {
- if (!n.peer) {
- for (const s of n.potentialConnections) s !== t && s.destroy();
- n.potentialConnections.clear(), n.peer = new Lt(t, { onPeerClosed: this.onPeerClosed, onSegmentRequested: this.eventHandlers.onSegmentRequested, onSegmentsAnnouncement: this.eventHandlers.onSegmentsAnnouncement }, this.config, this.stream.type, this.eventTarget), this.logger(`connected with peer: ${n.peer.id} ${this.streamShortId}`), this.eventHandlers.onPeerConnected(n.peer);
- }
- }));
- });
- d(this, "onTrackerClientWarning", (t) => {
- this.logger(`tracker warning (${this.streamShortId}: ${t})`), this.eventTarget.getEventDispatcher("onTrackerWarning")({ streamType: this.stream.type, warning: t });
- });
- d(this, "onTrackerClientError", (t) => {
- this.logger(`tracker error (${this.streamShortId}: ${t})`), this.eventTarget.getEventDispatcher("onTrackerError")({ streamType: this.stream.type, error: t });
- });
- d(this, "onPeerClosed", (t) => {
- this.logger(`peer closed: ${t.id}`), this._peers.delete(t.id);
- });
- this.stream = e, this.eventHandlers = n, this.config = s, this.eventTarget = r;
- const o = function(h) {
- const u = Us.fromUtf8(h).slice(1);
- return btoa(u);
- }(t);
- this.streamShortId = F(e);
- const a = function(h) {
- const u = [h], c = 20 - h.length;
- for (let l = 0; l < c; l++) u.push(Hs[Math.floor(62 * Math.random())]);
- return u.join("");
- }(s.trackerClientVersionPrefix);
- this.client = new te({ infoHash: Oe(o), peerId: Oe(a), announce: Ks() ? s.announceTrackers.slice(0, 1) : s.announceTrackers, rtcConfig: this.config.rtcConfig }), this.client.on("peer", this.onReceivePeerConnection), this.client.on("warning", this.onTrackerClientWarning), this.client.on("error", this.onTrackerClientError), this.logger(`create new client;
-stream: ${this.streamShortId}; hash: ${o}
-peerId: ${a}`);
- }
- start() {
- this.client.start();
- }
- destroy() {
- this.client.destroy();
- for (const { peer: t, potentialConnections: e } of this._peers.values()) {
- t == null || t.destroy();
- for (const n of e) n.destroy();
- }
- this._peers.clear(), this.logger(`destroy client; stream: ${this.streamShortId}`);
- }
- *peers() {
- for (const t of this._peers.values()) t.peer && (yield t.peer);
- }
-}
-function B(i, t) {
- return `v2-${i}-${function(e) {
- return `${e.type}-${e.index}`;
- }(t)}`;
-}
-function Ue(i, t) {
- for (const e of i.values()) {
- const n = e.segments.get(t);
- if (n) return n;
- }
-}
-function Mt(i, t, e, n, s) {
- const { highDemandTimeWindow: r, httpDownloadTimeWindow: o, p2pDownloadTimeWindow: a } = function(h, u) {
- const { highDemandTimeWindow: c, httpDownloadTimeWindow: l, p2pDownloadTimeWindow: g } = h, m = { highDemandTimeWindow: c, httpDownloadTimeWindow: l, p2pDownloadTimeWindow: g };
- return u <= 5 ? (m.httpDownloadTimeWindow = 0, m.p2pDownloadTimeWindow = 0) : u <= 10 && (m.p2pDownloadTimeWindow = m.httpDownloadTimeWindow), m;
- }(e, s);
- return { isHighDemand: Nt(i, t, r), isHttpDownloadable: Nt(i, t, o), isP2PDownloadable: Nt(i, t, a) && n.isSegmentLoadingOrLoadedBySomeone(i) };
-}
-function Nt(i, t, e) {
- const { startTime: n, endTime: s } = i, { position: r, rate: o } = t;
- return !(r + e * o < n || r > s);
-}
-class Xs {
- constructor(t, e, n, s, r, o, a) {
- d(this, "trackerClient");
- d(this, "isAnnounceMicrotaskCreated", !1);
- d(this, "onPeerConnected", (t) => {
- if (this.config.isP2PUploadDisabled) return;
- const { httpLoading: e, loaded: n } = this.getSegmentsAnnouncement();
- t.sendSegmentsAnnouncementCommand(n, e);
- });
- d(this, "broadcastAnnouncement", (t = !1) => {
- if (t) return void this.sendSegmentsAnnouncement([], []);
- if (this.isAnnounceMicrotaskCreated || this.config.isP2PUploadDisabled) return;
- const { loaded: e, httpLoading: n } = this.getSegmentsAnnouncement();
- this.sendSegmentsAnnouncement(e, n);
- });
- d(this, "sendSegmentsAnnouncement", (t, e) => {
- this.isAnnounceMicrotaskCreated = !0, queueMicrotask(() => {
- for (const n of this.trackerClient.peers()) n.sendSegmentsAnnouncementCommand(t, e);
- this.isAnnounceMicrotaskCreated = !1;
- });
- });
- d(this, "onSegmentRequested", async (t, e, n, s) => {
- const r = function(u, c) {
- for (const l of u.segments.values()) if (l.externalId === c) return l;
- }(this.stream, e);
- if (!r) return;
- if (this.config.isP2PUploadDisabled) return void t.sendSegmentAbsentCommand(e, n);
- const o = this.config.swarmId ?? this.streamManifestUrl, a = B(o, this.stream), h = await this.segmentStorage.getSegmentData(o, a, r.externalId);
- h ? await t.uploadSegmentData(r, n, s !== void 0 ? h.slice(s) : h) : t.sendSegmentAbsentCommand(e, n);
- });
- this.streamManifestUrl = t, this.stream = e, this.requests = n, this.segmentStorage = s, this.config = r, this.eventTarget = o, this.onSegmentAnnouncement = a;
- const h = B(this.config.swarmId ?? this.streamManifestUrl, this.stream);
- this.trackerClient = new Zs(h, this.stream, { onPeerConnected: this.onPeerConnected, onSegmentRequested: this.onSegmentRequested, onSegmentsAnnouncement: this.onSegmentAnnouncement }, this.config, this.eventTarget), this.eventTarget.addEventListener(`onStorageUpdated-${h}`, this.broadcastAnnouncement), this.segmentStorage.setSegmentChangeCallback((u) => {
- this.eventTarget.dispatchEvent(`onStorageUpdated-${u}`);
- }), this.trackerClient.start();
- }
- downloadSegment(t) {
- const e = [];
- for (const o of this.trackerClient.peers()) o.downloadingSegment || o.getSegmentStatus(t) !== "loaded" || e.push(o);
- if (e.length === 0) return;
- const n = (s = e)[Math.floor(Math.random() * s.length)];
- var s;
- const r = this.requests.getOrCreateRequest(t);
- n.downloadSegment(r);
- }
- isSegmentLoadingOrLoadedBySomeone(t) {
- for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t)) return !0;
- return !1;
- }
- isSegmentLoadedBySomeone(t) {
- for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t) === "loaded") return !0;
- return !1;
- }
- get connectedPeerCount() {
- let t = 0;
- for (const e of this.trackerClient.peers()) t++;
- return t;
- }
- getSegmentsAnnouncement() {
- const t = this.config.swarmId ?? this.streamManifestUrl, e = B(t, this.stream), n = this.segmentStorage.getStoredSegmentIds(t, e), s = [];
- for (const r of this.requests.httpRequests()) {
- const o = this.stream.segments.get(r.segment.runtimeId);
- o && s.push(o.externalId);
- }
- return { loaded: n, httpLoading: s };
- }
- destroy() {
- const t = B(this.config.swarmId ?? this.streamManifestUrl, this.stream);
- this.eventTarget.removeEventListener(`onStorageUpdated-${t}`, this.broadcastAnnouncement), this.trackerClient.destroy();
- }
-}
-class ti {
- constructor(t, e, n, s, r, o, a) {
- d(this, "loaders", /* @__PURE__ */ new Map());
- d(this, "_currentLoaderItem");
- d(this, "logger", L("p2pml-core:p2p-loaders-container"));
- this.streamManifestUrl = t, this.requests = n, this.segmentStorage = s, this.config = r, this.eventTarget = o, this.onSegmentAnnouncement = a, this._currentLoaderItem = this.findOrCreateLoaderForStream(e), this.logger(`set current p2p loader: ${F(e)}`);
- }
- createLoader(t) {
- if (this.loaders.has(t.runtimeId)) throw new Error("Loader for this stream already exists");
- const e = new Xs(this.streamManifestUrl, t, this.requests, this.segmentStorage, this.config, this.eventTarget, () => {
- this._currentLoaderItem.loader === e && this.onSegmentAnnouncement();
- }), n = F(t);
- return this.logger(`created new loader: ${n}`), { loader: e, stream: t, loggerInfo: F(t) };
- }
- findOrCreateLoaderForStream(t) {
- const e = this.loaders.get(t.runtimeId);
- if (e) return clearTimeout(e.destroyTimeoutId), e.destroyTimeoutId = void 0, e;
- {
- const n = this.createLoader(t);
- return this.loaders.set(t.runtimeId, n), n;
- }
- }
- changeCurrentLoader(t) {
- const e = this.config.swarmId ?? this.streamManifestUrl, n = B(e, this._currentLoaderItem.stream);
- this.segmentStorage.getStoredSegmentIds(e, n).length ? this.setLoaderDestroyTimeout(this._currentLoaderItem) : this.destroyAndRemoveLoader(this._currentLoaderItem), this._currentLoaderItem = this.findOrCreateLoaderForStream(t), this.logger(`change current p2p loader: ${F(t)}`);
- }
- setLoaderDestroyTimeout(t) {
- t.destroyTimeoutId = window.setTimeout(() => this.destroyAndRemoveLoader(t), this.config.p2pInactiveLoaderDestroyTimeoutMs);
- }
- destroyAndRemoveLoader(t) {
- t.loader.destroy(), this.loaders.delete(t.stream.runtimeId), this.logger("destroy p2p loader: ", t.loggerInfo);
- }
- get currentLoader() {
- return this._currentLoaderItem.loader;
- }
- destroy() {
- for (const { loader: t, destroyTimeoutId: e } of this.loaders.values()) t.destroy(), clearTimeout(e);
- this.loaders.clear();
- }
-}
-let ei = class {
- constructor(i, t, e, n, s, r) {
- d(this, "currentAttempt");
- d(this, "_failedAttempts", new ni());
- d(this, "finalData");
- d(this, "bytes", []);
- d(this, "_loadedBytes", 0);
- d(this, "_totalBytes");
- d(this, "_status", "not-started");
- d(this, "progress");
- d(this, "notReceivingBytesTimeout");
- d(this, "_abortRequestCallback");
- d(this, "_logger");
- d(this, "_isHandledByProcessQueue", !1);
- d(this, "onSegmentError");
- d(this, "onSegmentAbort");
- d(this, "onSegmentStart");
- d(this, "onSegmentLoaded");
- d(this, "abortOnTimeout", () => {
- var t;
- if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt) return;
- this.setStatus("failed");
- const i = new x("bytes-receiving-timeout");
- (t = this._abortRequestCallback) == null || t.call(this, i), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${i.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: i }), this.onSegmentError({ segment: this.segment, error: i, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback();
- });
- d(this, "abortOnError", (i) => {
- this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.setStatus("failed"), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${i.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: i }), this.onSegmentError({ segment: this.segment, error: i, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback());
- });
- d(this, "completeOnSuccess", () => {
- this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear(), this.setStatus("succeed"), this._totalBytes = this._loadedBytes, this.onSegmentLoaded({ segmentUrl: this.segment.url, bytesLength: this.data.byteLength, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.logger(`${this.currentAttempt.downloadSource} ${this.segment.externalId} succeed`), this.requestProcessQueueCallback());
- });
- d(this, "addLoadedChunk", (i) => {
- if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt || !this.progress) return;
- this.notReceivingBytesTimeout.restart();
- const { byteLength: t } = i, { all: e, http: n } = this.bandwidthCalculators;
- e.addBytes(t), this.currentAttempt.downloadSource === "http" && n.addBytes(t), this.bytes.push(i), this.progress.lastLoadedChunkTimestamp = performance.now(), this.progress.loadedBytes += t, this._loadedBytes += t;
- });
- d(this, "firstBytesReceived", () => {
- this.throwErrorIfNotLoadingStatus(), this.notReceivingBytesTimeout.restart();
- });
- this.segment = i, this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.playbackConfig = s, this.onSegmentError = r.getEventDispatcher("onSegmentError"), this.onSegmentAbort = r.getEventDispatcher("onSegmentAbort"), this.onSegmentStart = r.getEventDispatcher("onSegmentStart"), this.onSegmentLoaded = r.getEventDispatcher("onSegmentLoaded");
- const { byteRange: o } = this.segment;
- if (o) {
- const { end: h, start: u } = o;
- this._totalBytes = h - u + 1;
- }
- this.notReceivingBytesTimeout = new si(this.abortOnTimeout);
- const { type: a } = this.segment.stream;
- this._logger = L(`p2pml-core:request-${a}`);
- }
- clearLoadedBytes() {
- this._loadedBytes = 0, this.bytes = [], this._totalBytes = void 0, this.finalData = void 0;
- }
- get status() {
- return this._status;
- }
- setStatus(i) {
- this._status = i, this._isHandledByProcessQueue = !1;
- }
- get downloadSource() {
- var i;
- return (i = this.currentAttempt) == null ? void 0 : i.downloadSource;
- }
- get loadedBytes() {
- return this._loadedBytes;
- }
- get totalBytes() {
- return this._totalBytes;
- }
- get data() {
- return this.finalData || (this.finalData = Tn(this.bytes)), this.finalData;
- }
- get failedAttempts() {
- return this._failedAttempts;
- }
- get isHandledByProcessQueue() {
- return this._isHandledByProcessQueue;
- }
- markHandledByProcessQueue() {
- this._isHandledByProcessQueue = !0;
- }
- setTotalBytes(i) {
- if (this._totalBytes !== void 0) throw new Error("Request total bytes value is already set");
- this._totalBytes = i;
- }
- start(i, t) {
- if (this._status === "succeed") throw new Error(`Request ${this.segment.externalId} has been already succeed.`);
- if (this._status === "loading") throw new Error(`Request ${this.segment.externalId} has been already started.`);
- this.setStatus("loading"), this.currentAttempt = { ...i }, this.progress = { startFromByte: this._loadedBytes, loadedBytes: 0, startTimestamp: performance.now() }, this.manageBandwidthCalculatorsState("start");
- const { notReceivingBytesTimeoutMs: e, abort: n } = t;
- return this._abortRequestCallback = n, e !== void 0 && this.notReceivingBytesTimeout.start(e), this.logger(`${i.downloadSource} ${this.segment.externalId} started`), this.onSegmentStart({ segment: this.segment, downloadSource: i.downloadSource, peerId: i.downloadSource === "p2p" ? i.peerId : void 0 }), { firstBytesReceived: this.firstBytesReceived, addLoadedChunk: this.addLoadedChunk, completeOnSuccess: this.completeOnSuccess, abortOnError: this.abortOnError };
- }
- abortFromProcessQueue() {
- var i, t, e, n;
- this.throwErrorIfNotLoadingStatus(), this.setStatus("aborted"), this.logger(`${(i = this.currentAttempt) == null ? void 0 : i.downloadSource} ${this.segment.externalId} aborted`), (t = this._abortRequestCallback) == null || t.call(this, new x("abort")), this.onSegmentAbort({ segment: this.segment, downloadSource: (e = this.currentAttempt) == null ? void 0 : e.downloadSource, peerId: ((n = this.currentAttempt) == null ? void 0 : n.downloadSource) === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this._abortRequestCallback = void 0, this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear();
- }
- throwErrorIfNotLoadingStatus() {
- if (this._status !== "loading") throw new Error(`Request has been already ${this.status}.`);
- }
- logger(i) {
- var t;
- this._logger.color = ((t = this.currentAttempt) == null ? void 0 : t.downloadSource) === "http" ? "green" : "red", this._logger(i), this._logger.color = "";
- }
- manageBandwidthCalculatorsState(i) {
- var s;
- const { all: t, http: e } = this.bandwidthCalculators, n = i === "start" ? "startLoading" : "stopLoading";
- ((s = this.currentAttempt) == null ? void 0 : s.downloadSource) === "http" && e[n](), t[n]();
- }
-};
-class ni {
- constructor() {
- d(this, "attempts", []);
- }
- add(t) {
- this.attempts.push(t);
- }
- get httpAttemptsCount() {
- return this.attempts.reduce((t, e) => e.downloadSource === "http" ? t + 1 : t, 0);
- }
- get lastAttempt() {
- return this.attempts[this.attempts.length - 1];
- }
- clear() {
- this.attempts = [];
- }
-}
-class si {
- constructor(t) {
- d(this, "timeoutId");
- d(this, "ms");
- this.action = t;
- }
- start(t) {
- if (this.timeoutId) throw new Error("Timeout is already started.");
- this.ms = t, this.timeoutId = window.setTimeout(this.action, this.ms);
- }
- restart(t) {
- this.timeoutId && clearTimeout(this.timeoutId), t && (this.ms = t), this.ms && (this.timeoutId = window.setTimeout(this.action, this.ms));
- }
- clear() {
- clearTimeout(this.timeoutId), this.timeoutId = void 0;
- }
-}
-class ii {
- constructor(t, e, n, s, r) {
- d(this, "requests", /* @__PURE__ */ new Map());
- this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.config = s, this.eventTarget = r;
- }
- get executingHttpCount() {
- let t = 0;
- for (const e of this.httpRequests()) e.status === "loading" && t++;
- return t;
- }
- get executingP2PCount() {
- let t = 0;
- for (const e of this.p2pRequests()) e.status === "loading" && t++;
- return t;
- }
- get(t) {
- return this.requests.get(t);
- }
- getOrCreateRequest(t) {
- let e = this.requests.get(t);
- return e || (e = new ei(t, this.requestProcessQueueCallback, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), this.requests.set(t, e)), e;
- }
- remove(t) {
- this.requests.delete(t.segment);
- }
- items() {
- return this.requests.values();
- }
- *httpRequests() {
- for (const t of this.requests.values()) t.downloadSource === "http" && (yield t);
- }
- *p2pRequests() {
- for (const t of this.requests.values()) t.downloadSource === "p2p" && (yield t);
- }
- destroy() {
- for (const t of this.requests.values()) t.status === "loading" && t.abortFromProcessQueue();
- this.requests.clear();
- }
-}
-class ri {
- constructor(t, e) {
- d(this, "_status", "pending");
- d(this, "_shouldBeStartedImmediately", !1);
- this.segment = t, this.engineCallbacks = e;
- }
- get status() {
- return this._status;
- }
- get shouldBeStartedImmediately() {
- return this._shouldBeStartedImmediately;
- }
- resolve(t, e) {
- this._status === "pending" && (this._status = "succeed", this.engineCallbacks.onSuccess({ data: t, bandwidth: e }));
- }
- reject() {
- this._status === "pending" && (this._status = "failed", this.engineCallbacks.onError(new oe("failed")));
- }
- abort() {
- this._status === "pending" && (this._status = "aborted", this.engineCallbacks.onError(new oe("aborted")));
- }
- markAsShouldBeStartedImmediately() {
- this._shouldBeStartedImmediately = !0;
- }
-}
-function* Fe(i, t, e, n, s) {
- const { runtimeId: r, stream: o } = i, a = o.segments.get(r);
- if (!a) return;
- const h = o.segments.values();
- let u;
- do {
- const l = h.next();
- if (l.done) return;
- u = l.value;
- } while (u !== a);
- const c = Mt(u, t, e, n, s);
- if (Ut(c)) {
- const l = h.next();
- if (l.done) return;
- const g = l.value, m = Mt(g, t, e, n, s);
- if (Ut(m)) return;
- c.isHighDemand = !0, yield { segment: u, statuses: c }, yield { segment: g, statuses: m };
- } else yield { segment: u, statuses: c };
- for (const l of h) {
- const g = Mt(l, t, e, n, s);
- if (Ut(g)) break;
- yield { segment: l, statuses: g };
- }
-}
-function Ut(i) {
- const { isHighDemand: t = !1, isHttpDownloadable: e = !1, isP2PDownloadable: n = !1 } = i;
- return !t && !e && !n;
-}
-class oi {
- constructor(t, e, n, s, r, o, a) {
- d(this, "requests");
- d(this, "engineRequest");
- d(this, "p2pLoaders");
- d(this, "playback");
- d(this, "segmentAvgDuration");
- d(this, "logger");
- d(this, "storageCleanUpIntervalId");
- d(this, "levelChangedTimestamp");
- d(this, "lastQueueProcessingTimeStamp");
- d(this, "randomHttpDownloadInterval");
- d(this, "isProcessQueueMicrotaskCreated", !1);
- d(this, "requestProcessQueueMicrotask", (t = !0) => {
- const e = performance.now();
- !t && this.lastQueueProcessingTimeStamp !== void 0 && e - this.lastQueueProcessingTimeStamp <= 1e3 || this.isProcessQueueMicrotaskCreated || (this.isProcessQueueMicrotaskCreated = !0, queueMicrotask(() => {
- try {
- this.processQueue(), this.lastQueueProcessingTimeStamp = e;
- } finally {
- this.isProcessQueueMicrotaskCreated = !1;
- }
- }));
- });
- this.streamManifestUrl = t, this.lastRequestedSegment = e, this.streamDetails = n, this.config = s, this.bandwidthCalculators = r, this.segmentStorage = o, this.eventTarget = a;
- const h = this.lastRequestedSegment.stream;
- this.playback = { position: this.lastRequestedSegment.startTime, rate: 1 }, this.segmentAvgDuration = function(u) {
- const { segments: c } = u;
- let l = 0;
- const { size: g } = c;
- for (const m of c.values()) l += m.endTime - m.startTime;
- return l / g;
- }(h), this.requests = new ii(this.requestProcessQueueMicrotask, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), this.p2pLoaders = new ti(this.streamManifestUrl, this.lastRequestedSegment.stream, this.requests, this.segmentStorage, this.config, this.eventTarget, this.requestProcessQueueMicrotask), this.logger = L(`p2pml-core:hybrid-loader-${h.type}`), this.logger.color = "coral", this.setIntervalLoading();
- }
- setIntervalLoading() {
- const t = this.p2pLoaders.currentLoader.connectedPeerCount, e = 1e3 * Math.random() * t + 1e3;
- this.randomHttpDownloadInterval = window.setTimeout(() => {
- this.loadRandomThroughHttp(), this.setIntervalLoading();
- }, e);
- }
- async loadSegment(t, e) {
- var a;
- this.logger(`requests: ${Be(t)}`);
- const { stream: n } = t;
- n !== this.lastRequestedSegment.stream && (this.logger(`stream changed to ${F(n)}`), this.p2pLoaders.changeCurrentLoader(n)), this.lastRequestedSegment = t;
- const s = this.config.swarmId ?? this.streamManifestUrl, r = B(s, n);
- this.segmentStorage.onSegmentRequested(s, r, t.externalId, t.startTime, t.endTime, n.type, this.streamDetails.isLive);
- const o = new ri(t, e);
- try {
- if (this.segmentStorage.hasSegment(s, r, t.externalId)) {
- const h = await this.segmentStorage.getSegmentData(s, r, t.externalId);
- if (h) {
- const { queueDownloadRatio: u } = this.generateQueue();
- return void o.resolve(h, this.getBandwidth(u));
- }
- }
- (a = this.engineRequest) == null || a.abort(), this.engineRequest = o;
- } catch {
- o.reject();
- } finally {
- this.requestProcessQueueMicrotask();
- }
- }
- processRequests(t, e) {
- var o;
- const { stream: n } = this.lastRequestedSegment, { httpErrorRetries: s } = this.config, r = performance.now();
- for (const a of this.requests.items()) {
- const { downloadSource: h, status: u, segment: c, isHandledByProcessQueue: l } = a, g = ((o = this.engineRequest) == null ? void 0 : o.segment) === c ? this.engineRequest : void 0;
- switch (u) {
- case "loading":
- t.has(c.runtimeId) || g || (a.abortFromProcessQueue(), this.requests.remove(a));
- break;
- case "succeed": {
- if (!h) break;
- h === "http" && this.p2pLoaders.currentLoader.broadcastAnnouncement(), g && (g.resolve(a.data, this.getBandwidth(e)), this.engineRequest = void 0), this.requests.remove(a);
- const f = this.config.swarmId ?? this.streamManifestUrl, v = B(f, n);
- this.segmentStorage.storeSegment(f, v, c.externalId, a.data, c.startTime, c.endTime, c.stream.type, this.streamDetails.isLive);
- break;
- }
- case "failed":
- h !== "http" || l || this.p2pLoaders.currentLoader.broadcastAnnouncement(), g || n.segments.has(a.segment.runtimeId) || this.requests.remove(a), a.failedAttempts.httpAttemptsCount >= s && g && (this.engineRequest = void 0, g.reject());
- break;
- case "not-started":
- case "aborted":
- this.requests.remove(a);
- }
- a.markHandledByProcessQueue();
- const { lastAttempt: m } = a.failedAttempts;
- m && r - m.error.timestamp > 6e4 && a.failedAttempts.clear();
- }
- }
- processQueue() {
- var a;
- const { queue: t, queueSegmentIds: e, queueDownloadRatio: n } = this.generateQueue();
- this.processRequests(e, n);
- const { simultaneousHttpDownloads: s, simultaneousP2PDownloads: r, httpErrorRetries: o } = this.config;
- if ((a = this.engineRequest) != null && a.shouldBeStartedImmediately && this.engineRequest.status === "pending" && this.requests.executingHttpCount < s) {
- const { segment: h } = this.engineRequest, u = this.requests.get(h);
- (!u || u.status === "not-started" || u.status === "failed" && u.failedAttempts.httpAttemptsCount < this.config.httpErrorRetries) && this.loadThroughHttp(h);
- }
- for (const h of t) {
- const { statuses: u, segment: c } = h, l = this.requests.get(c);
- if (u.isHighDemand) {
- if ((l == null ? void 0 : l.downloadSource) === "http" && l.status === "loading" || (l == null ? void 0 : l.downloadSource) === "http" && l.status === "failed" && l.failedAttempts.httpAttemptsCount >= o) continue;
- const g = (l == null ? void 0 : l.status) === "loading" && l.downloadSource === "p2p";
- if (this.requests.executingHttpCount < s) {
- g && l.abortFromProcessQueue(), this.loadThroughHttp(c);
- continue;
- }
- if (this.abortLastHttpLoadingInQueueAfterItem(t, c) && this.requests.executingHttpCount < s) {
- g && l.abortFromProcessQueue(), this.loadThroughHttp(c);
- continue;
- }
- if (g) continue;
- if (this.requests.executingP2PCount < r) {
- this.loadThroughP2P(c);
- continue;
- }
- if (this.abortLastP2PLoadingInQueueAfterItem(t, c) && this.requests.executingP2PCount < r) {
- this.loadThroughP2P(c);
- continue;
- }
- } else if (u.isP2PDownloadable) {
- if ((l == null ? void 0 : l.status) === "loading") continue;
- (this.requests.executingP2PCount < r || this.p2pLoaders.currentLoader.isSegmentLoadedBySomeone(c) && this.abortLastP2PLoadingInQueueAfterItem(t, c) && this.requests.executingP2PCount < r) && this.loadThroughP2P(c);
- }
- }
- }
- abortSegmentRequest(t) {
- var e;
- ((e = this.engineRequest) == null ? void 0 : e.segment.runtimeId) === t && (this.engineRequest.abort(), this.logger("abort: ", Be(this.engineRequest.segment)), this.engineRequest = void 0, this.requestProcessQueueMicrotask());
- }
- loadThroughHttp(t) {
- const e = this.requests.getOrCreateRequest(t);
- new Bn(e, this.config, this.eventTarget), this.p2pLoaders.currentLoader.broadcastAnnouncement();
- }
- loadThroughP2P(t) {
- this.p2pLoaders.currentLoader.downloadSegment(t);
- }
- loadRandomThroughHttp() {
- const t = this.getAvailableStorageCapacityPercent();
- if (t <= 10) return;
- const { simultaneousHttpDownloads: e, httpErrorRetries: n } = this.config, s = this.p2pLoaders.currentLoader;
- if (this.requests.executingHttpCount >= e || !s.connectedPeerCount) return;
- const r = [];
- for (const { segment: c, statuses: l } of Fe(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader, t)) {
- const g = this.config.swarmId ?? this.streamManifestUrl, m = B(g, c.stream);
- if (!l.isHttpDownloadable || l.isP2PDownloadable || this.segmentStorage.hasSegment(g, m, c.externalId)) continue;
- const f = this.requests.get(c);
- f && (f.status === "loading" || f.status === "succeed" || f.failedAttempts.httpAttemptsCount >= n) || r.push(c);
- }
- if (!r.length || e - this.requests.executingHttpCount === 0) return;
- const o = s.connectedPeerCount + 1, a = Math.min(r.length, e * o), h = function(c) {
- for (let l = c.length - 1; l > 0; l--) {
- const g = Math.floor(Math.random() * (l + 1));
- [c[l], c[g]] = [c[g], c[l]];
- }
- return c;
- }(Array.from({ length: a }, (c, l) => l));
- let u = a / o;
- for (const c of h) {
- if (this.requests.executingHttpCount >= e) break;
- if (u >= 1 || Math.random() <= u) {
- const l = r[c];
- this.loadThroughHttp(l);
- }
- if (u--, u <= 0) break;
- }
- }
- abortLastHttpLoadingInQueueAfterItem(t, e) {
- for (const { segment: n } of De(t)) {
- if (n === e) break;
- const s = this.requests.get(n);
- if ((s == null ? void 0 : s.downloadSource) === "http" && s.status === "loading") return s.abortFromProcessQueue(), !0;
- }
- return !1;
- }
- abortLastP2PLoadingInQueueAfterItem(t, e) {
- for (const { segment: n } of De(t)) {
- if (n === e) break;
- const s = this.requests.get(n);
- if ((s == null ? void 0 : s.downloadSource) === "p2p" && s.status === "loading") return s.abortFromProcessQueue(), !0;
- }
- return !1;
- }
- getAvailableStorageCapacityPercent() {
- const { totalCapacity: t, usedCapacity: e } = this.segmentStorage.getUsage();
- return 100 - e / t * 100;
- }
- generateQueue() {
- var o;
- const t = [], e = /* @__PURE__ */ new Set();
- let n = 0, s = 0;
- const r = this.getAvailableStorageCapacityPercent();
- for (const a of Fe(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader, r)) {
- n++;
- const { segment: h } = a, u = this.config.swarmId ?? this.streamManifestUrl, c = B(u, h.stream);
- this.segmentStorage.hasSegment(u, c, h.externalId) || ((o = this.requests.get(h)) == null ? void 0 : o.status) === "succeed" ? s++ : (t.push(a), e.add(h.runtimeId));
- }
- return { queue: t, queueSegmentIds: e, maxPossibleLength: n, alreadyLoadedCount: s, queueDownloadRatio: n !== 0 ? s / n : 0 };
- }
- getBandwidth(t) {
- const { http: e, all: n } = this.bandwidthCalculators, { activeLevelBitrate: s } = this.streamDetails;
- if (this.streamDetails.activeLevelBitrate === 0) return n.getBandwidthLoadingOnly(3);
- const r = Math.max(n.getBandwidth(30, this.levelChangedTimestamp), n.getBandwidth(60, this.levelChangedTimestamp), n.getBandwidth(90, this.levelChangedTimestamp));
- if (t >= 0.8 || r >= 0.9 * s) return Math.max(n.getBandwidthLoadingOnly(1), n.getBandwidthLoadingOnly(3), n.getBandwidthLoadingOnly(5));
- const o = Math.max(e.getBandwidthLoadingOnly(1), e.getBandwidthLoadingOnly(3), e.getBandwidthLoadingOnly(5));
- return Math.max(r, o);
- }
- notifyLevelChanged() {
- this.levelChangedTimestamp = performance.now();
- }
- sendBroadcastAnnouncement(t = !1) {
- this.p2pLoaders.currentLoader.broadcastAnnouncement(t);
- }
- updatePlayback(t, e) {
- var o;
- const n = this.playback.rate !== e, s = this.playback.position !== t;
- if (!n && !s) return;
- const r = Math.abs(t - this.playback.position) / this.segmentAvgDuration > 0.5;
- s && (this.playback.position = t), n && e !== 0 && (this.playback.rate = e), r && (this.logger("position significantly changed"), (o = this.engineRequest) == null || o.markAsShouldBeStartedImmediately()), this.segmentStorage.onPlaybackUpdated(t, e), this.requestProcessQueueMicrotask(r);
- }
- updateStream(t) {
- t === this.lastRequestedSegment.stream && (this.logger(`update stream: ${F(t)}`), this.requestProcessQueueMicrotask());
- }
- destroy() {
- var t;
- clearInterval(this.storageCleanUpIntervalId), clearInterval(this.randomHttpDownloadInterval), this.storageCleanUpIntervalId = void 0, (t = this.engineRequest) == null || t.abort(), this.requests.destroy(), this.p2pLoaders.destroy();
- }
-}
-class He {
- constructor(t = 2e4) {
- d(this, "loadingsCount", 0);
- d(this, "bytes", []);
- d(this, "loadingOnlyTimestamps", []);
- d(this, "timestamps", []);
- d(this, "noLoadingsTime", 0);
- d(this, "loadingsStoppedAt", 0);
- this.clearThresholdMs = t;
- }
- addBytes(t, e = performance.now()) {
- this.bytes.push(t), this.loadingOnlyTimestamps.push(e - this.noLoadingsTime), this.timestamps.push(e);
- }
- startLoading(t = performance.now()) {
- this.clearStale(), this.loadingsCount === 0 && this.loadingsStoppedAt !== 0 && (this.noLoadingsTime += t - this.loadingsStoppedAt), this.loadingsCount++;
- }
- stopLoading(t = performance.now()) {
- this.loadingsCount > 0 && (this.loadingsCount--, this.loadingsCount === 0 && (this.loadingsStoppedAt = t));
- }
- getBandwidthLoadingOnly(t, e = Number.NEGATIVE_INFINITY) {
- if (!this.loadingOnlyTimestamps.length) return 0;
- const n = 1e3 * t, s = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1];
- let r = s;
- const o = s - n;
- let a = 0;
- for (let h = this.bytes.length - 1; h >= 0; h--) {
- const u = this.loadingOnlyTimestamps[h];
- if (u < o || this.timestamps[h] < e) break;
- r = u, a += this.bytes[h];
- }
- return 8e3 * a / (s - r);
- }
- getBandwidth(t, e = Number.NEGATIVE_INFINITY, n = performance.now()) {
- if (!this.timestamps.length) return 0;
- const s = n - 1e3 * t;
- let r = n, o = 0;
- for (let a = this.bytes.length - 1; a >= 0; a--) {
- const h = this.timestamps[a];
- if (h < s || h < e) break;
- r = h, o += this.bytes[a];
- }
- return 8e3 * o / (n - r);
- }
- clearStale() {
- if (!this.loadingOnlyTimestamps.length) return;
- const t = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1] - this.clearThresholdMs;
- let e = 0;
- for (const n of this.loadingOnlyTimestamps) {
- if (n > t) break;
- e++;
- }
- this.bytes.splice(0, e), this.loadingOnlyTimestamps.splice(0, e), this.timestamps.splice(0, e);
- }
-}
-const gt = (i, t) => `${i}|${t}`, mt = 1048576;
-class ai {
- constructor() {
- d(this, "userAgent", navigator.userAgent);
- d(this, "segmentMemoryStorageLimit", 4096);
- d(this, "currentStorageUsage", 0);
- d(this, "cache", /* @__PURE__ */ new Map());
- d(this, "logger");
- d(this, "coreConfig");
- d(this, "mainStreamConfig");
- d(this, "secondaryStreamConfig");
- d(this, "currentPlayback");
- d(this, "lastRequestedSegment");
- d(this, "segmentChangeCallback");
- this.logger = L("p2pml-core:segment-memory-storage"), this.logger.color = "RebeccaPurple";
- }
- async initialize(t, e, n) {
- this.coreConfig = t, this.mainStreamConfig = e, this.secondaryStreamConfig = n, this.setMemoryStorageLimit(), this.logger("initialized");
- }
- onPlaybackUpdated(t, e) {
- this.currentPlayback = { position: t, rate: e };
- }
- onSegmentRequested(t, e, n, s, r, o, a) {
- this.lastRequestedSegment = { streamId: e, segmentId: n, startTime: s, endTime: r, swarmId: t, streamType: o, isLiveStream: a };
- }
- async storeSegment(t, e, n, s, r, o, a, h) {
- this.clear(h, s.byteLength);
- const u = gt(e, n);
- if (this.cache.set(u, { data: s, segmentId: n, streamId: e, startTime: r, endTime: o, streamType: a }), this.increaseStorageUsage(s.byteLength), this.logger(`add segment: ${n} to ${e}`), !this.segmentChangeCallback) throw new Error("dispatchStorageUpdatedEvent is not set");
- this.segmentChangeCallback(e);
- }
- async getSegmentData(t, e, n) {
- const s = gt(e, n), r = this.cache.get(s);
- if (r !== void 0) return r.data;
- }
- getUsage() {
- if (!this.lastRequestedSegment || !this.currentPlayback) return { totalCapacity: this.segmentMemoryStorageLimit, usedCapacity: this.currentStorageUsage };
- const t = this.currentPlayback.position;
- let e = 0;
- for (const { endTime: n, data: s } of this.cache.values()) t > n || (e += s.byteLength);
- return { totalCapacity: this.segmentMemoryStorageLimit, usedCapacity: e / mt };
- }
- hasSegment(t, e, n) {
- const s = gt(e, n);
- return this.cache.get(s) !== void 0;
- }
- getStoredSegmentIds(t, e) {
- const n = [];
- for (const { segmentId: s, streamId: r } of this.cache.values()) r === e && n.push(s);
- return n;
- }
- clear(t, e) {
- if (!(this.currentPlayback && this.mainStreamConfig && this.secondaryStreamConfig && this.coreConfig) || !this.isMemoryLimitReached(e) && !t) return;
- const n = /* @__PURE__ */ new Set(), s = Array.from(this.cache.values()).sort((r, o) => r.startTime - o.startTime);
- for (const r of s) {
- const { streamId: o, segmentId: a, data: h } = r, u = gt(o, a);
- if (this.shouldRemoveSegment(r, t, this.currentPlayback.position) && (this.cache.delete(u), n.add(o), this.decreaseStorageUsage(h.byteLength), this.logger(`Removed segment ${a} from stream ${o}`), !this.isMemoryLimitReached(e) && !t)) break;
- }
- this.sendUpdatesToAffectedStreams(n);
- }
- isMemoryLimitReached(t) {
- return this.currentStorageUsage + t / mt > this.segmentMemoryStorageLimit;
- }
- setSegmentChangeCallback(t) {
- this.segmentChangeCallback = t;
- }
- sendUpdatesToAffectedStreams(t) {
- t.size !== 0 && t.forEach((e) => {
- if (!this.segmentChangeCallback) throw new Error("dispatchStorageUpdatedEvent is not set");
- this.segmentChangeCallback(e);
- });
- }
- shouldRemoveSegment(t, e, n) {
- const { endTime: s, streamType: r } = t, o = this.getStreamTimeWindow(r, "highDemandTimeWindow");
- return !(n <= s) && (!e || n > o + s);
- }
- increaseStorageUsage(t) {
- this.currentStorageUsage += t / mt;
- }
- decreaseStorageUsage(t) {
- this.currentStorageUsage -= t / mt;
- }
- setMemoryStorageLimit() {
- var e;
- var t;
- (e = this.coreConfig) != null && e.segmentMemoryStorageLimit ? this.segmentMemoryStorageLimit = this.coreConfig.segmentMemoryStorageLimit : (t = this.userAgent, /Android/i.test(t) && !/Chrome|Firefox/i.test(t) || ((n) => /iPad|iPhone/i.test(n))(this.userAgent) ? this.segmentMemoryStorageLimit = 1024 : ((n) => /Android/i.test(n))(this.userAgent) && (this.segmentMemoryStorageLimit = 2048));
- }
- getStreamTimeWindow(t, e) {
- const n = t === "main" ? this.mainStreamConfig : this.secondaryStreamConfig;
- return (n == null ? void 0 : n[e]) ?? 0;
- }
- destroy() {
- this.cache.clear();
- }
-}
-class hi {
- constructor() {
- d(this, "events", /* @__PURE__ */ new Map());
- }
- dispatchEvent(t, ...e) {
- const n = this.events.get(t);
- if (n) for (const s of n) s(...e);
- }
- getEventDispatcher(t) {
- let e = this.events.get(t);
- e || (e = [], this.events.set(t, e));
- const n = e;
- return (...s) => {
- for (const r of n) r(...s);
- };
- }
- addEventListener(t, e) {
- const n = this.events.get(t);
- n ? n.push(e) : this.events.set(t, [e]);
- }
- removeEventListener(t, e) {
- const n = this.events.get(t);
- if (n) {
- const s = n.indexOf(e);
- s !== -1 && n.splice(s, 1);
- }
- }
-}
-const $ = class $ {
- constructor(t) {
- d(this, "eventTarget", new hi());
- d(this, "manifestResponseUrl");
- d(this, "streams", /* @__PURE__ */ new Map());
- d(this, "mainStreamConfig");
- d(this, "secondaryStreamConfig");
- d(this, "commonCoreConfig");
- d(this, "bandwidthCalculators", { all: new He(), http: new He() });
- d(this, "segmentStorage");
- d(this, "mainStreamLoader");
- d(this, "secondaryStreamLoader");
- d(this, "streamDetails", { isLive: !1, activeLevelBitrate: 0 });
- const e = function n(s) {
- if (xn(s)) {
- const r = {};
- return Object.keys(s).forEach((o) => {
- if (s[o] !== void 0) {
- const a = n(s[o]);
- a !== void 0 && (r[o] = a);
- }
- }), r;
- }
- return s;
- }(t ?? {});
- this.commonCoreConfig = Dt({ defaultConfig: $.DEFAULT_COMMON_CORE_CONFIG, baseConfig: e }), this.mainStreamConfig = Dt({ defaultConfig: $.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e.mainStream }), this.secondaryStreamConfig = Dt({ defaultConfig: $.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e.secondaryStream });
- }
- getConfig() {
- return { ...U(this.commonCoreConfig), mainStream: U(this.mainStreamConfig), secondaryStream: U(this.secondaryStreamConfig) };
- }
- applyDynamicConfig(t) {
- const { mainStream: e, secondaryStream: n } = t, s = U(this.mainStreamConfig), r = U(this.secondaryStreamConfig);
- this.overrideAllConfigs(t, e, n), this.processSpecificDynamicConfigParams(s, t, "main"), this.processSpecificDynamicConfigParams(r, t, "secondary");
- }
- processSpecificDynamicConfigParams(t, e, n) {
- const s = this.getUpdatedStreamProperty("isP2PDisabled", e, n);
- s && t.isP2PDisabled !== s && this.destroyStreamLoader(n);
- const r = this.getUpdatedStreamProperty("isP2PUploadDisabled", e, n);
- if (r !== void 0 && t.isP2PUploadDisabled !== r) {
- const o = n === "main" ? this.mainStreamLoader : this.secondaryStreamLoader;
- o == null || o.sendBroadcastAnnouncement(r);
- }
- }
- getUpdatedStreamProperty(t, e, n) {
- const s = n === "main" ? e.mainStream : e.secondaryStream;
- return (s == null ? void 0 : s[t]) ?? e[t];
- }
- addEventListener(t, e) {
- this.eventTarget.addEventListener(t, e);
- }
- removeEventListener(t, e) {
- this.eventTarget.removeEventListener(t, e);
- }
- setManifestResponseUrl(t) {
- this.manifestResponseUrl = t.split("?")[0];
- }
- hasSegment(t) {
- return !!Ue(this.streams, t);
- }
- getStream(t) {
- return this.streams.get(t);
- }
- addStreamIfNoneExists(t) {
- this.streams.has(t.runtimeId) || this.streams.set(t.runtimeId, { ...t, segments: /* @__PURE__ */ new Map() });
- }
- updateStream(t, e, n) {
- var r, o;
- const s = this.streams.get(t);
- if (s) {
- if (e) for (const a of e) s.segments.has(a.runtimeId) || s.segments.set(a.runtimeId, { ...a, stream: s });
- if (n) for (const a of n) s.segments.delete(a);
- (r = this.mainStreamLoader) == null || r.updateStream(s), (o = this.secondaryStreamLoader) == null || o.updateStream(s);
- }
- }
- async loadSegment(t, e) {
- if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined");
- await this.initializeSegmentStorage();
- const n = this.identifySegment(t);
- this.getStreamHybridLoader(n).loadSegment(n, e);
- }
- abortSegmentLoading(t) {
- var e, n;
- (e = this.mainStreamLoader) == null || e.abortSegmentRequest(t), (n = this.secondaryStreamLoader) == null || n.abortSegmentRequest(t);
- }
- updatePlayback(t, e) {
- var n, s;
- (n = this.mainStreamLoader) == null || n.updatePlayback(t, e), (s = this.secondaryStreamLoader) == null || s.updatePlayback(t, e);
- }
- setActiveLevelBitrate(t) {
- var e, n;
- t !== this.streamDetails.activeLevelBitrate && (this.streamDetails.activeLevelBitrate = t, (e = this.mainStreamLoader) == null || e.notifyLevelChanged(), (n = this.secondaryStreamLoader) == null || n.notifyLevelChanged());
- }
- setIsLive(t) {
- this.streamDetails.isLive = t;
- }
- isSegmentLoadable(t) {
- try {
- const e = this.identifySegment(t);
- return (e.stream.type !== "main" || !this.mainStreamConfig.isP2PDisabled) && (e.stream.type !== "secondary" || !this.secondaryStreamConfig.isP2PDisabled);
- } catch {
- return !1;
- }
- }
- destroy() {
- var t, e, n;
- this.streams.clear(), (t = this.mainStreamLoader) == null || t.destroy(), (e = this.secondaryStreamLoader) == null || e.destroy(), (n = this.segmentStorage) == null || n.destroy(), this.mainStreamLoader = void 0, this.secondaryStreamLoader = void 0, this.segmentStorage = void 0, this.manifestResponseUrl = void 0, this.streamDetails = { isLive: !1, activeLevelBitrate: 0 };
- }
- async initializeSegmentStorage() {
- if (this.segmentStorage) return;
- const { isLive: t } = this.streamDetails, e = this.commonCoreConfig.customSegmentStorageFactory;
- if (e && typeof e != "function") throw new Error("Storage configuration is invalid");
- const n = e ? e(t) : new ai();
- await n.initialize(this.commonCoreConfig, this.mainStreamConfig, this.secondaryStreamConfig), this.segmentStorage = n;
- }
- identifySegment(t) {
- if (!this.manifestResponseUrl) throw new Error("Manifest response url is undefined");
- const e = Ue(this.streams, t);
- if (!e) throw new Error(`Not found segment with id: ${t}`);
- return e;
- }
- overrideAllConfigs(t, e, n) {
- K(this.commonCoreConfig, t), K(this.mainStreamConfig, t), K(this.secondaryStreamConfig, t), e && K(this.mainStreamConfig, e), n && K(this.secondaryStreamConfig, n);
- }
- destroyStreamLoader(t) {
- var e, n;
- t === "main" ? ((e = this.mainStreamLoader) == null || e.destroy(), this.mainStreamLoader = void 0) : ((n = this.secondaryStreamLoader) == null || n.destroy(), this.secondaryStreamLoader = void 0);
- }
- getStreamHybridLoader(t) {
- return t.stream.type === "main" ? (this.mainStreamLoader ?? (this.mainStreamLoader = this.createNewHybridLoader(t)), this.mainStreamLoader) : (this.secondaryStreamLoader ?? (this.secondaryStreamLoader = this.createNewHybridLoader(t)), this.secondaryStreamLoader);
- }
- createNewHybridLoader(t) {
- if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined");
- if (!this.segmentStorage) throw new Error("Segment storage is not initialized");
- const e = t.stream.type === "main" ? this.mainStreamConfig : this.secondaryStreamConfig;
- return new oi(this.manifestResponseUrl, t, this.streamDetails, e, this.bandwidthCalculators, this.segmentStorage, this.eventTarget);
- }
-};
-d($, "DEFAULT_COMMON_CORE_CONFIG", { segmentMemoryStorageLimit: void 0, customSegmentStorageFactory: void 0 }), d($, "DEFAULT_STREAM_CONFIG", { isP2PUploadDisabled: !1, isP2PDisabled: !1, simultaneousHttpDownloads: 2, simultaneousP2PDownloads: 3, highDemandTimeWindow: 15, httpDownloadTimeWindow: 3e3, p2pDownloadTimeWindow: 6e3, webRtcMaxMessageSize: 65535, p2pNotReceivingBytesTimeoutMs: 2e3, p2pInactiveLoaderDestroyTimeoutMs: 3e4, httpNotReceivingBytesTimeoutMs: 3e3, httpErrorRetries: 3, p2pErrorRetries: 3, trackerClientVersionPrefix: Fs, announceTrackers: ["wss://tracker.novage.com.ua", "wss://tracker.webtorrent.dev", "wss://tracker.openwebtorrent.com"], rtcConfig: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }, { urls: "stun:global.stun.twilio.com:3478" }] }, validateP2PSegment: void 0, httpRequestSetup: void 0, swarmId: void 0 });
-let $e = $;
-const di = ze.debug;
-export {
- $e as Core,
- oe as CoreRequestError,
- x as RequestError,
- di as debug
-};
-//# sourceMappingURL=p2p-media-loader-core.es.min.js.map
diff --git a/resources/p2p-media-loader-core/2.2.0/p2p-media-loader-core.min.jsm b/resources/p2p-media-loader-core/2.2.0/p2p-media-loader-core.min.jsm
new file mode 100644
index 00000000..0c8c4255
--- /dev/null
+++ b/resources/p2p-media-loader-core/2.2.0/p2p-media-loader-core.min.jsm
@@ -0,0 +1,3420 @@
+var os = Object.defineProperty;
+var as = (r, t, e) => t in r ? os(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
+var y = (r, t, e) => as(r, typeof t != "symbol" ? t + "" : t, e);
+class N extends Error {
+ constructor(e, n) {
+ super(n);
+ y(this, "timestamp");
+ this.type = e, this.timestamp = performance.now();
+ }
+}
+class De extends Error {
+ constructor(t) {
+ super(), this.type = t;
+ }
+}
+class hs {
+ constructor(t, e, n) {
+ y(this, "requestControls");
+ y(this, "abortController", new AbortController());
+ y(this, "expectedBytesLength");
+ y(this, "requestByteRange");
+ y(this, "onChunkDownloaded");
+ this.request = t, this.httpConfig = e, this.onChunkDownloaded = n.getEventDispatcher("onChunkDownloaded");
+ const { byteRange: s } = this.request.segment;
+ s && (this.requestByteRange = { ...s }), t.loadedBytes !== 0 && (this.requestByteRange = this.requestByteRange ?? { start: 0 }, this.requestByteRange.start = this.requestByteRange.start + t.loadedBytes), this.request.totalBytes && (this.expectedBytesLength = this.request.totalBytes - this.request.loadedBytes), this.requestControls = this.request.start({ downloadSource: "http" }, { abort: () => this.abortController.abort("abort"), notReceivingBytesTimeoutMs: this.httpConfig.httpNotReceivingBytesTimeoutMs }), this.fetch();
+ }
+ async fetch() {
+ var e, n, s, o;
+ const { segment: t } = this.request;
+ try {
+ let h = await ((n = (e = this.httpConfig).httpRequestSetup) == null ? void 0 : n.call(e, t.url, t.byteRange, this.abortController.signal, this.requestByteRange));
+ if (!h) {
+ const u = new Headers(this.requestByteRange ? { Range: `bytes=${this.requestByteRange.start}-${this.requestByteRange.end ?? ""}` } : void 0);
+ h = new Request(t.url, { headers: u, signal: this.abortController.signal });
+ }
+ if (this.abortController.signal.aborted) throw new DOMException("Request aborted before request fetch", "AbortError");
+ const a = await window.fetch(h);
+ if (this.handleResponseHeaders(a), !a.body) return;
+ const { requestControls: g } = this;
+ g.firstBytesReceived();
+ const S = a.body.getReader();
+ for await (const u of async function* (f) {
+ for (; ; ) {
+ const { done: b, value: x } = await f.read();
+ if (b) break;
+ yield x;
+ }
+ }(S)) this.requestControls.addLoadedChunk(u), this.onChunkDownloaded(u.byteLength, "http");
+ if (!(await ((o = (s = this.httpConfig).validateHTTPSegment) == null ? void 0 : o.call(s, t.url, t.byteRange, this.request.data)) ?? !0)) throw this.request.clearLoadedBytes(), new N("http-segment-validation-failed");
+ g.completeOnSuccess();
+ } catch (h) {
+ this.handleError(h);
+ }
+ }
+ handleResponseHeaders(t) {
+ if (!t.ok) throw t.status === 406 ? (this.request.clearLoadedBytes(), new N("http-bytes-mismatch", t.statusText)) : new N("http-error", t.statusText);
+ const { requestByteRange: e } = this;
+ if (e) if (t.status === 200) {
+ if (this.request.segment.byteRange) throw new N("http-unexpected-status-code");
+ this.request.clearLoadedBytes();
+ } else {
+ if (t.status !== 206) throw new N("http-unexpected-status-code", t.statusText);
+ const n = t.headers.get("Content-Length");
+ if (n && this.expectedBytesLength !== void 0 && this.expectedBytesLength !== +n) throw this.request.clearLoadedBytes(), new N("http-bytes-mismatch", t.statusText);
+ const s = t.headers.get("Content-Range"), o = s ? function(h) {
+ const a = ds.exec(h.trim());
+ if (!a) return;
+ const [, g, S, u] = a;
+ return { from: g ? parseInt(g) : void 0, to: S ? parseInt(S) : void 0, total: u ? parseInt(u) : void 0 };
+ }(s) : void 0;
+ if (o) {
+ const { from: h, to: a } = o, g = a !== void 0 && h !== void 0 ? a - h + 1 : void 0;
+ if (g !== void 0 && this.expectedBytesLength !== g || h !== void 0 && e.start !== h || a !== void 0 && e.end !== void 0 && e.end !== a) throw this.request.clearLoadedBytes(), new N("http-bytes-mismatch", t.statusText);
+ }
+ }
+ if (t.status === 200 && this.request.totalBytes === void 0) {
+ const n = t.headers.get("Content-Length");
+ n && this.request.setTotalBytes(+n);
+ }
+ }
+ handleError(t) {
+ if (t instanceof Error) {
+ if (t.name !== "abort") return;
+ const e = t instanceof N ? t : new N("http-error", t.message);
+ this.requestControls.abortOnError(e);
+ }
+ }
+}
+const ds = /^bytes (?:(?:(\d+)|)-(?:(\d+)|)|\*)\/(?:(\d+)|\*)$/;
+function cs(r) {
+ return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r;
+}
+var G, Y, vn = { exports: {} }, q = vn.exports = {};
+function ae() {
+ throw new Error("setTimeout has not been defined");
+}
+function he() {
+ throw new Error("clearTimeout has not been defined");
+}
+function kn(r) {
+ if (G === setTimeout) return setTimeout(r, 0);
+ if ((G === ae || !G) && setTimeout) return G = setTimeout, setTimeout(r, 0);
+ try {
+ return G(r, 0);
+ } catch {
+ try {
+ return G.call(null, r, 0);
+ } catch {
+ return G.call(this, r, 0);
+ }
+ }
+}
+(function() {
+ try {
+ G = typeof setTimeout == "function" ? setTimeout : ae;
+ } catch {
+ G = ae;
+ }
+ try {
+ Y = typeof clearTimeout == "function" ? clearTimeout : he;
+ } catch {
+ Y = he;
+ }
+})();
+var it, J = [], ut = !1, Dt = -1;
+function us() {
+ ut && it && (ut = !1, it.length ? J = it.concat(J) : Dt = -1, J.length && Tn());
+}
+function Tn() {
+ if (!ut) {
+ var r = kn(us);
+ ut = !0;
+ for (var t = J.length; t; ) {
+ for (it = J, J = []; ++Dt < t; ) it && it[Dt].run();
+ Dt = -1, t = J.length;
+ }
+ it = null, ut = !1, function(e) {
+ if (Y === clearTimeout) return clearTimeout(e);
+ if ((Y === he || !Y) && clearTimeout) return Y = clearTimeout, clearTimeout(e);
+ try {
+ return Y(e);
+ } catch {
+ try {
+ return Y.call(null, e);
+ } catch {
+ return Y.call(this, e);
+ }
+ }
+ }(r);
+ }
+}
+function Ne(r, t) {
+ this.fun = r, this.array = t;
+}
+function Q() {
+}
+q.nextTick = function(r) {
+ var t = new Array(arguments.length - 1);
+ if (arguments.length > 1) for (var e = 1; e < arguments.length; e++) t[e - 1] = arguments[e];
+ J.push(new Ne(r, t)), J.length !== 1 || ut || kn(Tn);
+}, Ne.prototype.run = function() {
+ this.fun.apply(null, this.array);
+}, q.title = "browser", q.browser = !0, q.env = {}, q.argv = [], q.version = "", q.versions = {}, q.on = Q, q.addListener = Q, q.once = Q, q.off = Q, q.removeListener = Q, q.removeAllListeners = Q, q.emit = Q, q.prependListener = Q, q.prependOnceListener = Q, q.listeners = function(r) {
+ return [];
+}, q.binding = function(r) {
+ throw new Error("process.binding is not supported");
+}, q.cwd = function() {
+ return "/";
+}, q.chdir = function(r) {
+ throw new Error("process.chdir is not supported");
+}, q.umask = function() {
+ return 0;
+};
+const Nt = cs(vn.exports);
+var ls = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
+function ot(r) {
+ return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r;
+}
+var Me, Fe, Ue, He, $e, Xt = { exports: {} };
+function gs() {
+ if (Fe) return Me;
+ Fe = 1;
+ var r = 1e3, t = 60 * r, e = 60 * t, n = 24 * e, s = 7 * n, o = 365.25 * n;
+ function h(a, g, S, u) {
+ var f = g >= 1.5 * S;
+ return Math.round(a / S) + " " + u + (f ? "s" : "");
+ }
+ return Me = function(a, g) {
+ g = g || {};
+ var S = typeof a;
+ if (S === "string" && a.length > 0) return function(u) {
+ if (!((u = String(u)).length > 100)) {
+ var f = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(u);
+ if (f) {
+ var b = parseFloat(f[1]);
+ switch ((f[2] || "ms").toLowerCase()) {
+ case "years":
+ case "year":
+ case "yrs":
+ case "yr":
+ case "y":
+ return b * o;
+ case "weeks":
+ case "week":
+ case "w":
+ return b * s;
+ case "days":
+ case "day":
+ case "d":
+ return b * n;
+ case "hours":
+ case "hour":
+ case "hrs":
+ case "hr":
+ case "h":
+ return b * e;
+ case "minutes":
+ case "minute":
+ case "mins":
+ case "min":
+ case "m":
+ return b * t;
+ case "seconds":
+ case "second":
+ case "secs":
+ case "sec":
+ case "s":
+ return b * r;
+ case "milliseconds":
+ case "millisecond":
+ case "msecs":
+ case "msec":
+ case "ms":
+ return b;
+ default:
+ return;
+ }
+ }
+ }
+ }(a);
+ if (S === "number" && isFinite(a)) return g.long ? function(u) {
+ var f = Math.abs(u);
+ return f >= n ? h(u, f, n, "day") : f >= e ? h(u, f, e, "hour") : f >= t ? h(u, f, t, "minute") : f >= r ? h(u, f, r, "second") : u + " ms";
+ }(a) : function(u) {
+ var f = Math.abs(u);
+ return f >= n ? Math.round(u / n) + "d" : f >= e ? Math.round(u / e) + "h" : f >= t ? Math.round(u / t) + "m" : f >= r ? Math.round(u / r) + "s" : u + "ms";
+ }(a);
+ throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(a));
+ };
+}
+var xn = ($e || ($e = 1, function(r, t) {
+ t.formatArgs = function(n) {
+ if (n[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + n[0] + (this.useColors ? "%c " : " ") + "+" + r.exports.humanize(this.diff), !this.useColors) return;
+ const s = "color: " + this.color;
+ n.splice(1, 0, s, "color: inherit");
+ let o = 0, h = 0;
+ n[0].replace(/%[a-zA-Z%]/g, (a) => {
+ a !== "%%" && (o++, a === "%c" && (h = o));
+ }), n.splice(h, 0, s);
+ }, t.save = function(n) {
+ try {
+ n ? t.storage.setItem("debug", n) : t.storage.removeItem("debug");
+ } catch {
+ }
+ }, t.load = function() {
+ let n;
+ try {
+ n = t.storage.getItem("debug");
+ } catch {
+ }
+ return !n && Nt !== void 0 && "env" in Nt && (n = Nt.env.DEBUG), n;
+ }, t.useColors = function() {
+ if (typeof window < "u" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) return !0;
+ if (typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) return !1;
+ let n;
+ return typeof document < "u" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window < "u" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator < "u" && navigator.userAgent && (n = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(n[1], 10) >= 31 || typeof navigator < "u" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
+ }, t.storage = function() {
+ try {
+ return localStorage;
+ } catch {
+ }
+ }(), t.destroy = /* @__PURE__ */ (() => {
+ let n = !1;
+ return () => {
+ n || (n = !0, console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."));
+ };
+ })(), t.colors = ["#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33"], t.log = console.debug || console.log || (() => {
+ }), r.exports = (He || (He = 1, Ue = function(n) {
+ function s(a) {
+ let g, S, u, f = null;
+ function b(...x) {
+ if (!b.enabled) return;
+ const C = b, d = Number(/* @__PURE__ */ new Date()), l = d - (g || d);
+ C.diff = l, C.prev = g, C.curr = d, g = d, x[0] = s.coerce(x[0]), typeof x[0] != "string" && x.unshift("%O");
+ let c = 0;
+ x[0] = x[0].replace(/%([a-zA-Z%])/g, (m, p) => {
+ if (m === "%%") return "%";
+ c++;
+ const _ = s.formatters[p];
+ if (typeof _ == "function") {
+ const T = x[c];
+ m = _.call(C, T), x.splice(c, 1), c--;
+ }
+ return m;
+ }), s.formatArgs.call(C, x), (C.log || s.log).apply(C, x);
+ }
+ return b.namespace = a, b.useColors = s.useColors(), b.color = s.selectColor(a), b.extend = o, b.destroy = s.destroy, Object.defineProperty(b, "enabled", { enumerable: !0, configurable: !1, get: () => f !== null ? f : (S !== s.namespaces && (S = s.namespaces, u = s.enabled(a)), u), set: (x) => {
+ f = x;
+ } }), typeof s.init == "function" && s.init(b), b;
+ }
+ function o(a, g) {
+ const S = s(this.namespace + (g === void 0 ? ":" : g) + a);
+ return S.log = this.log, S;
+ }
+ function h(a, g) {
+ let S = 0, u = 0, f = -1, b = 0;
+ for (; S < a.length; ) if (u < g.length && (g[u] === a[S] || g[u] === "*")) g[u] === "*" ? (f = u, b = S, u++) : (S++, u++);
+ else {
+ if (f === -1) return !1;
+ u = f + 1, b++, S = b;
+ }
+ for (; u < g.length && g[u] === "*"; ) u++;
+ return u === g.length;
+ }
+ return s.debug = s, s.default = s, s.coerce = function(a) {
+ return a instanceof Error ? a.stack || a.message : a;
+ }, s.disable = function() {
+ const a = [...s.names, ...s.skips.map((g) => "-" + g)].join(",");
+ return s.enable(""), a;
+ }, s.enable = function(a) {
+ s.save(a), s.namespaces = a, s.names = [], s.skips = [];
+ const g = (typeof a == "string" ? a : "").trim().replace(" ", ",").split(",").filter(Boolean);
+ for (const S of g) S[0] === "-" ? s.skips.push(S.slice(1)) : s.names.push(S);
+ }, s.enabled = function(a) {
+ for (const g of s.skips) if (h(a, g)) return !1;
+ for (const g of s.names) if (h(a, g)) return !0;
+ return !1;
+ }, s.humanize = gs(), s.destroy = function() {
+ console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
+ }, Object.keys(n).forEach((a) => {
+ s[a] = n[a];
+ }), s.names = [], s.skips = [], s.formatters = {}, s.selectColor = function(a) {
+ let g = 0;
+ for (let S = 0; S < a.length; S++) g = (g << 5) - g + a.charCodeAt(S), g |= 0;
+ return s.colors[Math.abs(g) % s.colors.length];
+ }, s.enable(s.load()), s;
+ }), Ue)(t);
+ const { formatters: e } = r.exports;
+ e.j = function(n) {
+ try {
+ return JSON.stringify(n);
+ } catch (s) {
+ return "[UnexpectedJSONParseError]: " + s.message;
+ }
+ };
+}(Xt, Xt.exports)), Xt.exports);
+const H = ot(xn);
+var je, Lt = { exports: {} };
+function An() {
+ if (je) return Lt.exports;
+ je = 1;
+ var r, t = typeof Reflect == "object" ? Reflect : null, e = t && typeof t.apply == "function" ? t.apply : function(d, l, c) {
+ return Function.prototype.apply.call(d, l, c);
+ };
+ r = t && typeof t.ownKeys == "function" ? t.ownKeys : Object.getOwnPropertySymbols ? function(d) {
+ return Object.getOwnPropertyNames(d).concat(Object.getOwnPropertySymbols(d));
+ } : function(d) {
+ return Object.getOwnPropertyNames(d);
+ };
+ var n = Number.isNaN || function(d) {
+ return d != d;
+ };
+ function s() {
+ s.init.call(this);
+ }
+ Lt.exports = s, Lt.exports.once = function(d, l) {
+ return new Promise(function(c, m) {
+ function p(T) {
+ d.removeListener(l, _), m(T);
+ }
+ function _() {
+ typeof d.removeListener == "function" && d.removeListener("error", p), c([].slice.call(arguments));
+ }
+ C(d, l, _, { once: !0 }), l !== "error" && function(T, I, B) {
+ typeof T.on == "function" && C(T, "error", I, B);
+ }(d, p, { once: !0 });
+ });
+ }, s.EventEmitter = s, s.prototype._events = void 0, s.prototype._eventsCount = 0, s.prototype._maxListeners = void 0;
+ var o = 10;
+ function h(d) {
+ if (typeof d != "function") throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof d);
+ }
+ function a(d) {
+ return d._maxListeners === void 0 ? s.defaultMaxListeners : d._maxListeners;
+ }
+ function g(d, l, c, m) {
+ var p, _, T, I;
+ if (h(c), (_ = d._events) === void 0 ? (_ = d._events = /* @__PURE__ */ Object.create(null), d._eventsCount = 0) : (_.newListener !== void 0 && (d.emit("newListener", l, c.listener ? c.listener : c), _ = d._events), T = _[l]), T === void 0) T = _[l] = c, ++d._eventsCount;
+ else if (typeof T == "function" ? T = _[l] = m ? [c, T] : [T, c] : m ? T.unshift(c) : T.push(c), (p = a(d)) > 0 && T.length > p && !T.warned) {
+ T.warned = !0;
+ var B = new Error("Possible EventEmitter memory leak detected. " + T.length + " " + String(l) + " listeners added. Use emitter.setMaxListeners() to increase limit");
+ B.name = "MaxListenersExceededWarning", B.emitter = d, B.type = l, B.count = T.length, I = B, console && console.warn && console.warn(I);
+ }
+ return d;
+ }
+ function S() {
+ if (!this.fired) return this.target.removeListener(this.type, this.wrapFn), this.fired = !0, arguments.length === 0 ? this.listener.call(this.target) : this.listener.apply(this.target, arguments);
+ }
+ function u(d, l, c) {
+ var m = { fired: !1, wrapFn: void 0, target: d, type: l, listener: c }, p = S.bind(m);
+ return p.listener = c, m.wrapFn = p, p;
+ }
+ function f(d, l, c) {
+ var m = d._events;
+ if (m === void 0) return [];
+ var p = m[l];
+ return p === void 0 ? [] : typeof p == "function" ? c ? [p.listener || p] : [p] : c ? function(_) {
+ for (var T = new Array(_.length), I = 0; I < T.length; ++I) T[I] = _[I].listener || _[I];
+ return T;
+ }(p) : x(p, p.length);
+ }
+ function b(d) {
+ var l = this._events;
+ if (l !== void 0) {
+ var c = l[d];
+ if (typeof c == "function") return 1;
+ if (c !== void 0) return c.length;
+ }
+ return 0;
+ }
+ function x(d, l) {
+ for (var c = new Array(l), m = 0; m < l; ++m) c[m] = d[m];
+ return c;
+ }
+ function C(d, l, c, m) {
+ if (typeof d.on == "function") m.once ? d.once(l, c) : d.on(l, c);
+ else {
+ if (typeof d.addEventListener != "function") throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof d);
+ d.addEventListener(l, function p(_) {
+ m.once && d.removeEventListener(l, p), c(_);
+ });
+ }
+ }
+ return Object.defineProperty(s, "defaultMaxListeners", { enumerable: !0, get: function() {
+ return o;
+ }, set: function(d) {
+ if (typeof d != "number" || d < 0 || n(d)) throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + d + ".");
+ o = d;
+ } }), s.init = function() {
+ this._events !== void 0 && this._events !== Object.getPrototypeOf(this)._events || (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0), this._maxListeners = this._maxListeners || void 0;
+ }, s.prototype.setMaxListeners = function(d) {
+ if (typeof d != "number" || d < 0 || n(d)) throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + d + ".");
+ return this._maxListeners = d, this;
+ }, s.prototype.getMaxListeners = function() {
+ return a(this);
+ }, s.prototype.emit = function(d) {
+ for (var l = [], c = 1; c < arguments.length; c++) l.push(arguments[c]);
+ var m = d === "error", p = this._events;
+ if (p !== void 0) m = m && p.error === void 0;
+ else if (!m) return !1;
+ if (m) {
+ var _;
+ if (l.length > 0 && (_ = l[0]), _ instanceof Error) throw _;
+ var T = new Error("Unhandled error." + (_ ? " (" + _.message + ")" : ""));
+ throw T.context = _, T;
+ }
+ var I = p[d];
+ if (I === void 0) return !1;
+ if (typeof I == "function") e(I, this, l);
+ else {
+ var B = I.length, at = x(I, B);
+ for (c = 0; c < B; ++c) e(at[c], this, l);
+ }
+ return !0;
+ }, s.prototype.addListener = function(d, l) {
+ return g(this, d, l, !1);
+ }, s.prototype.on = s.prototype.addListener, s.prototype.prependListener = function(d, l) {
+ return g(this, d, l, !0);
+ }, s.prototype.once = function(d, l) {
+ return h(l), this.on(d, u(this, d, l)), this;
+ }, s.prototype.prependOnceListener = function(d, l) {
+ return h(l), this.prependListener(d, u(this, d, l)), this;
+ }, s.prototype.removeListener = function(d, l) {
+ var c, m, p, _, T;
+ if (h(l), (m = this._events) === void 0) return this;
+ if ((c = m[d]) === void 0) return this;
+ if (c === l || c.listener === l) --this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : (delete m[d], m.removeListener && this.emit("removeListener", d, c.listener || l));
+ else if (typeof c != "function") {
+ for (p = -1, _ = c.length - 1; _ >= 0; _--) if (c[_] === l || c[_].listener === l) {
+ T = c[_].listener, p = _;
+ break;
+ }
+ if (p < 0) return this;
+ p === 0 ? c.shift() : function(I, B) {
+ for (; B + 1 < I.length; B++) I[B] = I[B + 1];
+ I.pop();
+ }(c, p), c.length === 1 && (m[d] = c[0]), m.removeListener !== void 0 && this.emit("removeListener", d, T || l);
+ }
+ return this;
+ }, s.prototype.off = s.prototype.removeListener, s.prototype.removeAllListeners = function(d) {
+ var l, c, m;
+ if ((c = this._events) === void 0) return this;
+ if (c.removeListener === void 0) return arguments.length === 0 ? (this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0) : c[d] !== void 0 && (--this._eventsCount == 0 ? this._events = /* @__PURE__ */ Object.create(null) : delete c[d]), this;
+ if (arguments.length === 0) {
+ var p, _ = Object.keys(c);
+ for (m = 0; m < _.length; ++m) (p = _[m]) !== "removeListener" && this.removeAllListeners(p);
+ return this.removeAllListeners("removeListener"), this._events = /* @__PURE__ */ Object.create(null), this._eventsCount = 0, this;
+ }
+ if (typeof (l = c[d]) == "function") this.removeListener(d, l);
+ else if (l !== void 0) for (m = l.length - 1; m >= 0; m--) this.removeListener(d, l[m]);
+ return this;
+ }, s.prototype.listeners = function(d) {
+ return f(this, d, !0);
+ }, s.prototype.rawListeners = function(d) {
+ return f(this, d, !1);
+ }, s.listenerCount = function(d, l) {
+ return typeof d.listenerCount == "function" ? d.listenerCount(l) : b.call(d, l);
+ }, s.prototype.listenerCount = b, s.prototype.eventNames = function() {
+ return this._eventsCount > 0 ? r(this._events) : [];
+ }, Lt.exports;
+}
+const Ln = ot(An());
+var We, Qe, ze, It = { exports: {} }, ms = function() {
+ if (ze) return It.exports;
+ ze = 1;
+ var r = (Qe || (Qe = 1, We = function n(s, o) {
+ if (s && o) return n(s)(o);
+ if (typeof s != "function") throw new TypeError("need wrapper function");
+ return Object.keys(s).forEach(function(a) {
+ h[a] = s[a];
+ }), h;
+ function h() {
+ for (var a = new Array(arguments.length), g = 0; g < a.length; g++) a[g] = arguments[g];
+ var S = s.apply(this, a), u = a[a.length - 1];
+ return typeof S == "function" && S !== u && Object.keys(u).forEach(function(f) {
+ S[f] = u[f];
+ }), S;
+ }
+ }), We);
+ function t(n) {
+ var s = function() {
+ return s.called ? s.value : (s.called = !0, s.value = n.apply(this, arguments));
+ };
+ return s.called = !1, s;
+ }
+ function e(n) {
+ var s = function() {
+ if (s.called) throw new Error(s.onceError);
+ return s.called = !0, s.value = n.apply(this, arguments);
+ }, o = n.name || "Function wrapped with `once`";
+ return s.onceError = o + " shouldn't be called more than once", s.called = !1, s;
+ }
+ return It.exports = r(t), It.exports.strict = r(e), t.proto = t(function() {
+ Object.defineProperty(Function.prototype, "once", { value: function() {
+ return t(this);
+ }, configurable: !0 }), Object.defineProperty(Function.prototype, "onceStrict", { value: function() {
+ return e(this);
+ }, configurable: !0 });
+ }), It.exports;
+}();
+const ps = ot(ms);
+var Ge, Ye, te, Je;
+function In() {
+ if (Ye) return Ge;
+ let r;
+ return Ye = 1, Ge = typeof queueMicrotask == "function" ? queueMicrotask.bind(typeof window < "u" ? window : ls) : (t) => (r || (r = Promise.resolve())).then(t).catch((e) => setTimeout(() => {
+ throw e;
+ }, 0));
+}
+var fs = function() {
+ if (Je) return te;
+ Je = 1, te = function(t, e) {
+ let n, s, o, h = !0;
+ Array.isArray(t) ? (n = [], s = t.length) : (o = Object.keys(t), n = {}, s = o.length);
+ function a(S) {
+ function u() {
+ e && e(S, n), e = null;
+ }
+ h ? r(u) : u();
+ }
+ function g(S, u, f) {
+ n[S] = f, (--s == 0 || u) && a(u);
+ }
+ s ? o ? o.forEach(function(S) {
+ t[S](function(u, f) {
+ g(S, u, f);
+ });
+ }) : t.forEach(function(S, u) {
+ S(function(f, b) {
+ g(u, f, b);
+ });
+ }) : a(null), h = !1;
+ };
+ const r = In();
+ return te;
+}();
+const _s = ot(fs), K = typeof window < "u" ? window : self, de = K.RTCPeerConnection || K.mozRTCPeerConnection || K.webkitRTCPeerConnection, ys = K.RTCSessionDescription || K.mozRTCSessionDescription || K.webkitRTCSessionDescription, Ss = K.RTCIceCandidate || K.mozRTCIceCandidate || K.webkitRTCIceCandidate;
+var Ve, Ke, Ze, Xe, tn, en, nn, sn, rn, on;
+function ws() {
+ if (Xe) return Ze;
+ Xe = 1;
+ const r = Ke ? Ve : (Ke = 1, Ve = class {
+ constructor(t) {
+ if (!(t > 0) || t - 1 & t) throw new Error("Max size for a FixedFIFO should be a power of two");
+ this.buffer = new Array(t), this.mask = t - 1, this.top = 0, this.btm = 0, this.next = null;
+ }
+ clear() {
+ this.top = this.btm = 0, this.next = null, this.buffer.fill(void 0);
+ }
+ push(t) {
+ return this.buffer[this.top] === void 0 && (this.buffer[this.top] = t, this.top = this.top + 1 & this.mask, !0);
+ }
+ shift() {
+ const t = this.buffer[this.btm];
+ if (t !== void 0) return this.buffer[this.btm] = void 0, this.btm = this.btm + 1 & this.mask, t;
+ }
+ peek() {
+ return this.buffer[this.btm];
+ }
+ isEmpty() {
+ return this.buffer[this.btm] === void 0;
+ }
+ });
+ return Ze = class {
+ constructor(t) {
+ this.hwm = t || 16, this.head = new r(this.hwm), this.tail = this.head, this.length = 0;
+ }
+ clear() {
+ this.head = this.tail, this.head.clear(), this.length = 0;
+ }
+ push(t) {
+ if (this.length++, !this.head.push(t)) {
+ const e = this.head;
+ this.head = e.next = new r(2 * this.head.buffer.length), this.head.push(t);
+ }
+ }
+ shift() {
+ this.length !== 0 && this.length--;
+ const t = this.tail.shift();
+ if (t === void 0 && this.tail.next) {
+ const e = this.tail.next;
+ return this.tail.next = null, this.tail = e, this.tail.shift();
+ }
+ return t;
+ }
+ peek() {
+ const t = this.tail.peek();
+ return t === void 0 && this.tail.next ? this.tail.next.peek() : t;
+ }
+ isEmpty() {
+ return this.length === 0;
+ }
+ };
+}
+function an() {
+ return en ? tn : (en = 1, tn = class {
+ constructor(r) {
+ this.decoder = new TextDecoder(r === "utf16le" ? "utf16-le" : r);
+ }
+ get remaining() {
+ return -1;
+ }
+ decode(r) {
+ return this.decoder.decode(r, { stream: !0 });
+ }
+ flush() {
+ return this.decoder.decode(new Uint8Array(0));
+ }
+ });
+}
+function bs() {
+ if (sn) return nn;
+ sn = 1;
+ const r = an(), t = an();
+ return nn = class {
+ constructor(e = "utf8") {
+ switch (this.encoding = function(n) {
+ switch (n = n.toLowerCase()) {
+ case "utf8":
+ case "utf-8":
+ return "utf8";
+ case "ucs2":
+ case "ucs-2":
+ case "utf16le":
+ case "utf-16le":
+ return "utf16le";
+ case "latin1":
+ case "binary":
+ return "latin1";
+ case "base64":
+ case "ascii":
+ case "hex":
+ return n;
+ default:
+ throw new Error("Unknown encoding: " + n);
+ }
+ }(e), this.encoding) {
+ case "utf8":
+ this.decoder = new t();
+ break;
+ case "utf16le":
+ case "base64":
+ throw new Error("Unsupported encoding: " + this.encoding);
+ default:
+ this.decoder = new r(this.encoding);
+ }
+ }
+ get remaining() {
+ return this.decoder.remaining;
+ }
+ push(e) {
+ return typeof e == "string" ? e : this.decoder.decode(e);
+ }
+ write(e) {
+ return this.push(e);
+ }
+ end(e) {
+ let n = "";
+ return e && (n = this.push(e)), n += this.decoder.flush(), n;
+ }
+ };
+}
+var hn, dn, En = function() {
+ if (on) return rn;
+ on = 1;
+ const { EventEmitter: r } = An(), t = new Error("Stream was destroyed"), e = new Error("Premature close"), n = ws(), s = bs(), o = 536870911, h = 1 ^ o, a = 2 ^ o, g = 32, S = 64, u = 128, f = 256, b = 1024, x = 2048, C = 4096, d = 8192, l = 16384, c = 32768, m = 131072, p = 131328, _ = 16 ^ o, T = 536805375, I = 768 ^ o, B = 536838143, at = 536739839, zt = 1 << 18, $ = 2 << 18, j = 4 << 18, F = 8 << 18, ht = 16 << 18, Z = 32 << 18, W = 64 << 18, pt = 128 << 18, Hn = 256 << 18, we = 512 << 18, be = 1024 << 18, $n = 535822335, Ce = 503316479, ve = 268435455, xt = 262160, jn = 536608751, ke = 8404992, ft = 14, Wn = 15, Te = 8405006, Gt = 33587200, xe = 33587215, Qn = 2359296, Ae = 270794767, At = Symbol.asyncIterator || Symbol("asyncIterator");
+ class Le {
+ constructor(i, { highWaterMark: w = 16384, map: k = null, mapWritable: A, byteLength: L, byteLengthWritable: E } = {}) {
+ this.stream = i, this.queue = new n(), this.highWaterMark = w, this.buffered = 0, this.error = null, this.pipeline = null, this.drains = null, this.byteLength = E || L || Be, this.map = A || k, this.afterWrite = Kn.bind(this), this.afterUpdateNextTick = ts.bind(this);
+ }
+ get ended() {
+ return !!(this.stream._duplexState & Z);
+ }
+ push(i) {
+ return !(142606350 & this.stream._duplexState) && (this.map !== null && (i = this.map(i)), this.buffered += this.byteLength(i), this.queue.push(i), this.buffered < this.highWaterMark ? (this.stream._duplexState |= F, !0) : (this.stream._duplexState |= 6291456, !1));
+ }
+ shift() {
+ const i = this.queue.shift();
+ return this.buffered -= this.byteLength(i), this.buffered === 0 && (this.stream._duplexState &= 534773759), i;
+ }
+ end(i) {
+ typeof i == "function" ? this.stream.once("finish", i) : i != null && this.push(i), this.stream._duplexState = (this.stream._duplexState | we) & $n;
+ }
+ autoBatch(i, w) {
+ const k = [], A = this.stream;
+ for (k.push(i); (A._duplexState & Ae) === Qn; ) k.push(A._writableState.shift());
+ if (A._duplexState & Wn) return w(null);
+ A._writev(k, w);
+ }
+ update() {
+ const i = this.stream;
+ i._duplexState |= $;
+ do {
+ for (; (i._duplexState & Ae) === F; ) {
+ const w = this.shift();
+ i._duplexState |= 67371008, i._write(w, this.afterWrite);
+ }
+ 1310720 & i._duplexState || this.updateNonPrimary();
+ } while (this.continueUpdate() === !0);
+ i._duplexState &= 536346623;
+ }
+ updateNonPrimary() {
+ const i = this.stream;
+ if ((144965647 & i._duplexState) === we) return i._duplexState = i._duplexState | zt, void i._final(Vn.bind(this));
+ (i._duplexState & ft) != 4 ? (i._duplexState & xe) == 1 && (i._duplexState = (i._duplexState | xt) & h, i._open(Ee.bind(this))) : i._duplexState & Gt || (i._duplexState |= xt, i._destroy(Ie.bind(this)));
+ }
+ continueUpdate() {
+ return !!(this.stream._duplexState & pt) && (this.stream._duplexState &= Ce, !0);
+ }
+ updateCallback() {
+ (35127311 & this.stream._duplexState) === j ? this.update() : this.updateNextTick();
+ }
+ updateNextTick() {
+ this.stream._duplexState & pt || (this.stream._duplexState |= pt, this.stream._duplexState & $ || queueMicrotask(this.afterUpdateNextTick));
+ }
+ }
+ class zn {
+ constructor(i, { highWaterMark: w = 16384, map: k = null, mapReadable: A, byteLength: L, byteLengthReadable: E } = {}) {
+ this.stream = i, this.queue = new n(), this.highWaterMark = w === 0 ? 1 : w, this.buffered = 0, this.readAhead = w > 0, this.error = null, this.pipeline = null, this.byteLength = E || L || Be, this.map = A || k, this.pipeTo = null, this.afterRead = Zn.bind(this), this.afterUpdateNextTick = Xn.bind(this);
+ }
+ get ended() {
+ return !!(this.stream._duplexState & l);
+ }
+ pipe(i, w) {
+ if (this.pipeTo !== null) throw new Error("Can only pipe to one destination");
+ if (typeof w != "function" && (w = null), this.stream._duplexState |= 512, this.pipeTo = i, this.pipeline = new Yn(this.stream, i, w), w && this.stream.on("error", Oe), yt(i)) i._writableState.pipeline = this.pipeline, w && i.on("error", Oe), i.on("finish", this.pipeline.finished.bind(this.pipeline));
+ else {
+ const k = this.pipeline.done.bind(this.pipeline, i), A = this.pipeline.done.bind(this.pipeline, i, null);
+ i.on("error", k), i.on("close", A), i.on("finish", this.pipeline.finished.bind(this.pipeline));
+ }
+ i.on("drain", Jn.bind(this)), this.stream.emit("piping", i), i.emit("pipe", this.stream);
+ }
+ push(i) {
+ const w = this.stream;
+ return i === null ? (this.highWaterMark = 0, w._duplexState = 536805311 & w._duplexState | 1024, !1) : this.map !== null && (i = this.map(i)) === null ? (w._duplexState &= T, this.buffered < this.highWaterMark) : (this.buffered += this.byteLength(i), this.queue.push(i), w._duplexState = (w._duplexState | u) & T, this.buffered < this.highWaterMark);
+ }
+ shift() {
+ const i = this.queue.shift();
+ return this.buffered -= this.byteLength(i), this.buffered === 0 && (this.stream._duplexState &= 536862591), i;
+ }
+ unshift(i) {
+ const w = [this.map !== null ? this.map(i) : i];
+ for (; this.buffered > 0; ) w.push(this.shift());
+ for (let k = 0; k < w.length - 1; k++) {
+ const A = w[k];
+ this.buffered += this.byteLength(A), this.queue.push(A);
+ }
+ this.push(w[w.length - 1]);
+ }
+ read() {
+ const i = this.stream;
+ if ((16527 & i._duplexState) === u) {
+ const w = this.shift();
+ return this.pipeTo !== null && this.pipeTo.write(w) === !1 && (i._duplexState &= I), i._duplexState & x && i.emit("data", w), w;
+ }
+ return this.readAhead === !1 && (i._duplexState |= m, this.updateNextTick()), null;
+ }
+ drain() {
+ const i = this.stream;
+ for (; (16527 & i._duplexState) === u && 768 & i._duplexState; ) {
+ const w = this.shift();
+ this.pipeTo !== null && this.pipeTo.write(w) === !1 && (i._duplexState &= I), i._duplexState & x && i.emit("data", w);
+ }
+ }
+ update() {
+ const i = this.stream;
+ i._duplexState |= g;
+ do {
+ for (this.drain(); this.buffered < this.highWaterMark && (214047 & i._duplexState) === m; ) i._duplexState |= 65552, i._read(this.afterRead), this.drain();
+ (12431 & i._duplexState) == 4224 && (i._duplexState |= d, i.emit("readable")), 80 & i._duplexState || this.updateNonPrimary();
+ } while (this.continueUpdate() === !0);
+ i._duplexState &= 536870879;
+ }
+ updateNonPrimary() {
+ const i = this.stream;
+ (1167 & i._duplexState) === b && (i._duplexState = 536869887 & i._duplexState | 16384, i.emit("end"), (i._duplexState & Te) === ke && (i._duplexState |= 4), this.pipeTo !== null && this.pipeTo.end()), (i._duplexState & ft) != 4 ? (i._duplexState & xe) == 1 && (i._duplexState = (i._duplexState | xt) & h, i._open(Ee.bind(this))) : i._duplexState & Gt || (i._duplexState |= xt, i._destroy(Ie.bind(this)));
+ }
+ continueUpdate() {
+ return !!(this.stream._duplexState & c) && (this.stream._duplexState &= B, !0);
+ }
+ updateCallback() {
+ (32879 & this.stream._duplexState) === S ? this.update() : this.updateNextTick();
+ }
+ updateNextTickIfOpen() {
+ 32769 & this.stream._duplexState || (this.stream._duplexState |= c, this.stream._duplexState & g || queueMicrotask(this.afterUpdateNextTick));
+ }
+ updateNextTick() {
+ this.stream._duplexState & c || (this.stream._duplexState |= c, this.stream._duplexState & g || queueMicrotask(this.afterUpdateNextTick));
+ }
+ }
+ class Gn {
+ constructor(i) {
+ this.data = null, this.afterTransform = es.bind(i), this.afterFinal = null;
+ }
+ }
+ class Yn {
+ constructor(i, w, k) {
+ this.from = i, this.to = w, this.afterPipe = k, this.error = null, this.pipeToFinished = !1;
+ }
+ finished() {
+ this.pipeToFinished = !0;
+ }
+ done(i, w) {
+ w && (this.error = w), i !== this.to || (this.to = null, this.from === null) ? i !== this.from || (this.from = null, this.to === null) ? (this.afterPipe !== null && this.afterPipe(this.error), this.to = this.from = this.afterPipe = null) : i._duplexState & l || this.to.destroy(this.error || new Error("Readable stream closed before ending")) : this.from._duplexState & l && this.pipeToFinished || this.from.destroy(this.error || new Error("Writable stream closed prematurely"));
+ }
+ }
+ function Jn() {
+ this.stream._duplexState |= 512, this.updateCallback();
+ }
+ function Vn(v) {
+ const i = this.stream;
+ v && i.destroy(v), i._duplexState & ft || (i._duplexState |= Z, i.emit("finish")), (i._duplexState & Te) === ke && (i._duplexState |= 4), i._duplexState &= 402391039, i._duplexState & $ ? this.updateNextTick() : this.update();
+ }
+ function Ie(v) {
+ const i = this.stream;
+ v || this.error === t || (v = this.error), v && i.emit("error", v), i._duplexState |= 8, i.emit("close");
+ const w = i._readableState, k = i._writableState;
+ if (w !== null && w.pipeline !== null && w.pipeline.done(i, v), k !== null) {
+ for (; k.drains !== null && k.drains.length > 0; ) k.drains.shift().resolve(!1);
+ k.pipeline !== null && k.pipeline.done(i, v);
+ }
+ }
+ function Kn(v) {
+ const i = this.stream;
+ v && i.destroy(v), i._duplexState &= 469499903, this.drains !== null && function(w) {
+ for (let k = 0; k < w.length; k++) --w[k].writes == 0 && (w.shift().resolve(!0), k--);
+ }(this.drains), (6553615 & i._duplexState) === ht && (i._duplexState &= 532676607, (i._duplexState & W) === W && i.emit("drain")), this.updateCallback();
+ }
+ function Zn(v) {
+ v && this.stream.destroy(v), this.stream._duplexState &= _, this.readAhead !== !1 || this.stream._duplexState & f || (this.stream._duplexState &= at), this.updateCallback();
+ }
+ function Xn() {
+ this.stream._duplexState & g || (this.stream._duplexState &= B, this.update());
+ }
+ function ts() {
+ this.stream._duplexState & $ || (this.stream._duplexState &= Ce, this.update());
+ }
+ function Ee(v) {
+ const i = this.stream;
+ v && i.destroy(v), 4 & i._duplexState || (17423 & i._duplexState || (i._duplexState |= S), 142606351 & i._duplexState || (i._duplexState |= j), i.emit("open")), i._duplexState &= jn, i._writableState !== null && i._writableState.updateCallback(), i._readableState !== null && i._readableState.updateCallback();
+ }
+ function es(v, i) {
+ i != null && this.push(i), this._writableState.afterWrite(v);
+ }
+ function ns(v) {
+ this._readableState !== null && (v === "data" && (this._duplexState |= 133376, this._readableState.updateNextTick()), v === "readable" && (this._duplexState |= C, this._readableState.updateNextTick())), this._writableState !== null && v === "drain" && (this._duplexState |= W, this._writableState.updateNextTick());
+ }
+ class Yt extends r {
+ constructor(i) {
+ super(), this._duplexState = 0, this._readableState = null, this._writableState = null, i && (i.open && (this._open = i.open), i.destroy && (this._destroy = i.destroy), i.predestroy && (this._predestroy = i.predestroy), i.signal && i.signal.addEventListener("abort", is.bind(this))), this.on("newListener", ns);
+ }
+ _open(i) {
+ i(null);
+ }
+ _destroy(i) {
+ i(null);
+ }
+ _predestroy() {
+ }
+ get readable() {
+ return this._readableState !== null || void 0;
+ }
+ get writable() {
+ return this._writableState !== null || void 0;
+ }
+ get destroyed() {
+ return !!(8 & this._duplexState);
+ }
+ get destroying() {
+ return !!(this._duplexState & ft);
+ }
+ destroy(i) {
+ this._duplexState & ft || (i || (i = t), this._duplexState = 535822271 & this._duplexState | 4, this._readableState !== null && (this._readableState.highWaterMark = 0, this._readableState.error = i), this._writableState !== null && (this._writableState.highWaterMark = 0, this._writableState.error = i), this._duplexState |= 2, this._predestroy(), this._duplexState &= a, this._readableState !== null && this._readableState.updateNextTick(), this._writableState !== null && this._writableState.updateNextTick());
+ }
+ }
+ class _t extends Yt {
+ constructor(i) {
+ super(i), this._duplexState |= 8519681, this._readableState = new zn(this, i), i && (this._readableState.readAhead === !1 && (this._duplexState &= at), i.read && (this._read = i.read), i.eagerOpen && this._readableState.updateNextTick(), i.encoding && this.setEncoding(i.encoding));
+ }
+ setEncoding(i) {
+ const w = new s(i), k = this._readableState.map || rs;
+ return this._readableState.map = function(A) {
+ const L = w.push(A);
+ return L === "" && (A.byteLength !== 0 || w.remaining > 0) ? null : k(L);
+ }, this;
+ }
+ _read(i) {
+ i(null);
+ }
+ pipe(i, w) {
+ return this._readableState.updateNextTick(), this._readableState.pipe(i, w), i;
+ }
+ read() {
+ return this._readableState.updateNextTick(), this._readableState.read();
+ }
+ push(i) {
+ return this._readableState.updateNextTickIfOpen(), this._readableState.push(i);
+ }
+ unshift(i) {
+ return this._readableState.updateNextTickIfOpen(), this._readableState.unshift(i);
+ }
+ resume() {
+ return this._duplexState |= p, this._readableState.updateNextTick(), this;
+ }
+ pause() {
+ return this._duplexState &= this._readableState.readAhead === !1 ? 536739583 : 536870655, this;
+ }
+ static _fromAsyncIterator(i, w) {
+ let k;
+ const A = new _t({ ...w, read(E) {
+ i.next().then(L).then(E.bind(null, null)).catch(E);
+ }, predestroy() {
+ k = i.return();
+ }, destroy(E) {
+ if (!k) return E(null);
+ k.then(E.bind(null, null)).catch(E);
+ } });
+ return A;
+ function L(E) {
+ E.done ? A.push(null) : A.push(E.value);
+ }
+ }
+ static from(i, w) {
+ if (yt(k = i) && k.readable) return i;
+ var k;
+ if (i[At]) return this._fromAsyncIterator(i[At](), w);
+ Array.isArray(i) || (i = i === void 0 ? [] : [i]);
+ let A = 0;
+ return new _t({ ...w, read(L) {
+ this.push(A === i.length ? null : i[A++]), L(null);
+ } });
+ }
+ static isBackpressured(i) {
+ return !!(17422 & i._duplexState) || i._readableState.buffered >= i._readableState.highWaterMark;
+ }
+ static isPaused(i) {
+ return !(i._duplexState & f);
+ }
+ [At]() {
+ const i = this;
+ let w = null, k = null, A = null;
+ return this.on("error", (O) => {
+ w = O;
+ }), this.on("readable", function() {
+ k !== null && L(i.read());
+ }), this.on("close", function() {
+ k !== null && L(null);
+ }), { [At]() {
+ return this;
+ }, next: () => new Promise(function(O, st) {
+ k = O, A = st;
+ const R = i.read();
+ R !== null ? L(R) : 8 & i._duplexState && L(null);
+ }), return: () => E(null), throw: (O) => E(O) };
+ function L(O) {
+ A !== null && (w ? A(w) : O !== null || i._duplexState & l ? k({ value: O, done: O === null }) : A(t), A = k = null);
+ }
+ function E(O) {
+ return i.destroy(O), new Promise((st, R) => {
+ if (8 & i._duplexState) return st({ value: void 0, done: !0 });
+ i.once("close", function() {
+ O ? R(O) : st({ value: void 0, done: !0 });
+ });
+ });
+ }
+ }
+ }
+ class Jt extends Yt {
+ constructor(i) {
+ super(i), this._duplexState |= 16385, this._writableState = new Le(this, i), i && (i.writev && (this._writev = i.writev), i.write && (this._write = i.write), i.final && (this._final = i.final), i.eagerOpen && this._writableState.updateNextTick());
+ }
+ cork() {
+ this._duplexState |= be;
+ }
+ uncork() {
+ this._duplexState &= ve, this._writableState.updateNextTick();
+ }
+ _writev(i, w) {
+ w(null);
+ }
+ _write(i, w) {
+ this._writableState.autoBatch(i, w);
+ }
+ _final(i) {
+ i(null);
+ }
+ static isBackpressured(i) {
+ return !!(146800654 & i._duplexState);
+ }
+ static drained(i) {
+ if (i.destroyed) return Promise.resolve(!1);
+ const w = i._writableState;
+ var k;
+ const A = ((k = i)._writev !== Jt.prototype._writev && k._writev !== Vt.prototype._writev ? Math.min(1, w.queue.length) : w.queue.length) + (i._duplexState & Hn ? 1 : 0);
+ return A === 0 ? Promise.resolve(!0) : (w.drains === null && (w.drains = []), new Promise((L) => {
+ w.drains.push({ writes: A, resolve: L });
+ }));
+ }
+ write(i) {
+ return this._writableState.updateNextTick(), this._writableState.push(i);
+ }
+ end(i) {
+ return this._writableState.updateNextTick(), this._writableState.end(i), this;
+ }
+ }
+ class Vt extends _t {
+ constructor(i) {
+ super(i), this._duplexState = 1 | this._duplexState & m, this._writableState = new Le(this, i), i && (i.writev && (this._writev = i.writev), i.write && (this._write = i.write), i.final && (this._final = i.final));
+ }
+ cork() {
+ this._duplexState |= be;
+ }
+ uncork() {
+ this._duplexState &= ve, this._writableState.updateNextTick();
+ }
+ _writev(i, w) {
+ w(null);
+ }
+ _write(i, w) {
+ this._writableState.autoBatch(i, w);
+ }
+ _final(i) {
+ i(null);
+ }
+ write(i) {
+ return this._writableState.updateNextTick(), this._writableState.push(i);
+ }
+ end(i) {
+ return this._writableState.updateNextTick(), this._writableState.end(i), this;
+ }
+ }
+ class Re extends Vt {
+ constructor(i) {
+ super(i), this._transformState = new Gn(this), i && (i.transform && (this._transform = i.transform), i.flush && (this._flush = i.flush));
+ }
+ _write(i, w) {
+ this._readableState.buffered >= this._readableState.highWaterMark ? this._transformState.data = i : this._transform(i, this._transformState.afterTransform);
+ }
+ _read(i) {
+ if (this._transformState.data !== null) {
+ const w = this._transformState.data;
+ this._transformState.data = null, i(null), this._transform(w, this._transformState.afterTransform);
+ } else i(null);
+ }
+ destroy(i) {
+ super.destroy(i), this._transformState.data !== null && (this._transformState.data = null, this._transformState.afterTransform());
+ }
+ _transform(i, w) {
+ w(null, i);
+ }
+ _flush(i) {
+ i(null);
+ }
+ _final(i) {
+ this._transformState.afterFinal = i, this._flush(ss.bind(this));
+ }
+ }
+ function ss(v, i) {
+ const w = this._transformState.afterFinal;
+ if (v) return w(v);
+ i != null && this.push(i), this.push(null), w(null);
+ }
+ function Pe(v, ...i) {
+ const w = Array.isArray(v) ? [...v, ...i] : [v, ...i], k = w.length && typeof w[w.length - 1] == "function" ? w.pop() : null;
+ if (w.length < 2) throw new Error("Pipeline requires at least 2 streams");
+ let A = w[0], L = null, E = null;
+ for (let R = 1; R < w.length; R++) L = w[R], yt(A) ? A.pipe(L, st) : (O(A, !0, R > 1, st), A.pipe(L)), A = L;
+ if (k) {
+ let R = !1;
+ const St = yt(L) || !(!L._writableState || !L._writableState.autoDestroy);
+ L.on("error", (Kt) => {
+ E === null && (E = Kt);
+ }), L.on("finish", () => {
+ R = !0, St || k(E);
+ }), St && L.on("close", () => k(E || (R ? null : e)));
+ }
+ return L;
+ function O(R, St, Kt, Zt) {
+ R.on("error", Zt), R.on("close", function() {
+ if (R._readableState && !R._readableState.ended || Kt && R._writableState && !R._writableState.ended) return Zt(e);
+ });
+ }
+ function st(R) {
+ if (R && !E) {
+ E = R;
+ for (const St of w) St.destroy(R);
+ }
+ }
+ }
+ function rs(v) {
+ return v;
+ }
+ function qe(v) {
+ return !!v._readableState || !!v._writableState;
+ }
+ function yt(v) {
+ return typeof v._duplexState == "number" && qe(v);
+ }
+ function Be(v) {
+ return function(i) {
+ return typeof i == "object" && i !== null && typeof i.byteLength == "number";
+ }(v) ? v.byteLength : 1024;
+ }
+ function Oe() {
+ }
+ function is() {
+ this.destroy(new Error("Stream aborted."));
+ }
+ return rn = { pipeline: Pe, pipelinePromise: function(...v) {
+ return new Promise((i, w) => Pe(...v, (k) => {
+ if (k) return w(k);
+ i();
+ }));
+ }, isStream: qe, isStreamx: yt, isEnded: function(v) {
+ return !!v._readableState && v._readableState.ended;
+ }, isFinished: function(v) {
+ return !!v._writableState && v._writableState.ended;
+ }, isDisturbed: function(v) {
+ return !!(1 & ~v._duplexState) || !!(v._duplexState & Gt);
+ }, getStreamError: function(v, i = {}) {
+ const w = v._readableState && v._readableState.error || v._writableState && v._writableState.error;
+ return i.all || w !== t ? w : null;
+ }, Stream: Yt, Writable: Jt, Readable: _t, Duplex: Vt, Transform: Re, PassThrough: class extends Re {
+ } };
+}();
+const P = ot(function() {
+ if (dn) return hn;
+ function r(t, e) {
+ for (const n in e) Object.defineProperty(t, n, { value: e[n], enumerable: !0, configurable: !0 });
+ return t;
+ }
+ return dn = 1, hn = function(t, e, n) {
+ if (!t || typeof t == "string") throw new TypeError("Please pass an Error to err-code");
+ n || (n = {}), typeof e == "object" && (n = e, e = ""), e && (n.code = e);
+ try {
+ return r(t, n);
+ } catch {
+ n.message = t.message, n.stack = t.stack;
+ const o = function() {
+ };
+ return o.prototype = Object.create(Object.getPrototypeOf(t)), r(new o(), n);
+ }
+ };
+}()), Mt = "0123456789abcdef", Rn = [], Ft = [];
+for (let r = 0; r < 256; r++) Rn[r] = Mt[r >> 4 & 15] + Mt[15 & r], r < 16 && (r < 10 ? Ft[48 + r] = r : Ft[87 + r] = r);
+const gt = (r) => {
+ const t = r.length;
+ let e = "", n = 0;
+ for (; n < t; ) e += Rn[r[n++]];
+ return e;
+}, ce = (r) => {
+ const t = r.length >> 1, e = t << 1, n = new Uint8Array(t);
+ let s = 0, o = 0;
+ for (; o < e; ) n[s++] = Ft[r.charCodeAt(o++)] << 4 | Ft[r.charCodeAt(o++)];
+ return n;
+};
+for (var Cs = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", vs = typeof Uint8Array > "u" ? [] : new Uint8Array(256), Et = 0; Et < 64; Et++) vs[Cs.charCodeAt(Et)] = Et;
+const ks = new TextDecoder(), Pn = (r, t) => ks.decode(r), Ts = new TextEncoder(), Se = (r) => Ts.encode(r), dt = (r) => {
+ let t, e = "", n = 0;
+ const s = r.length;
+ for (; n < s; ) t = r.charCodeAt(n++), e += Mt[t >> 4] + Mt[15 & t];
+ return e;
+}, vt = (r) => {
+ const t = ce(r);
+ if (t.length <= 65536) return String.fromCharCode(...t);
+ let e = "", n = 0;
+ for (; n < t.length; ) e += String.fromCharCode(...t.subarray(n, n += 65536));
+ return e;
+}, cn = typeof window < "u" ? window : self, ue = cn.crypto || cn.msCrypto || {};
+ue.subtle || ue.webkitSubtle;
+const Ut = (r) => {
+ const t = new Uint8Array(r);
+ return ue.getRandomValues(t);
+}, xs = H("simple-peer"), ee = 65536;
+function un(r) {
+ return r.replace(/a=ice-options:trickle\s\n/g, "");
+}
+let kt = class le extends En.Duplex {
+ constructor(e) {
+ super(e = Object.assign({ allowHalfOpen: !1 }, e));
+ y(this, "_pc");
+ if (this.__objectMode = !!e.objectMode, this._id = gt(Ut(4)).slice(0, 7), this._debug("new peer %o", e), this.channelName = e.initiator ? e.channelName || gt(Ut(20)) : null, this.initiator = e.initiator || !1, this.channelConfig = e.channelConfig || le.channelConfig, this.channelNegotiated = this.channelConfig.negotiated, this.config = Object.assign({}, le.config, e.config), this.offerOptions = e.offerOptions || {}, this.answerOptions = e.answerOptions || {}, this.sdpTransform = e.sdpTransform || ((n) => n), this.trickle = e.trickle === void 0 || e.trickle, this.allowHalfTrickle = e.allowHalfTrickle !== void 0 && e.allowHalfTrickle, this.iceCompleteTimeout = e.iceCompleteTimeout || 5e3, 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, !de) throw P(typeof window > "u" ? new Error("No WebRTC support: Specify `opts.wrtc` option in this environment") : new Error("No WebRTC support: Not a supported browser"), "ERR_WEBRTC_SUPPORT");
+ this._pcReady = !1, this._channelReady = !1, this._iceComplete = !1, this._iceCompleteTimer = null, this._channel = null, this._pendingCandidates = [], this._isNegotiating = !1, this._firstNegotiation = !0, this._batchedNegotiation = !1, this._queuedNegotiation = !1, this._sendersAwaitingStable = [], this._closingInterval = null, this._remoteTracks = [], this._remoteStreams = [], this._chunk = null, this._cb = null, this._interval = null;
+ try {
+ this._pc = new de(this.config);
+ } catch (n) {
+ return void this.__destroy(P(n, "ERR_PC_CONSTRUCTOR"));
+ }
+ this._isReactNativeWebrtc = typeof this._pc._peerConnectionId == "number", this._pc.oniceconnectionstatechange = () => {
+ this._onIceStateChange();
+ }, this._pc.onicegatheringstatechange = () => {
+ this._onIceStateChange();
+ }, this._pc.onconnectionstatechange = () => {
+ this._onConnectionStateChange();
+ }, this._pc.onsignalingstatechange = () => {
+ this._onSignalingStateChange();
+ }, this._pc.onicecandidate = (n) => {
+ this._onIceCandidate(n);
+ }, typeof this._pc.peerIdentity == "object" && this._pc.peerIdentity.catch((n) => {
+ this.__destroy(P(n, "ERR_PC_PEER_IDENTITY"));
+ }), this.initiator || this.channelNegotiated ? this._setupData({ channel: this._pc.createDataChannel(this.channelName, this.channelConfig) }) : this._pc.ondatachannel = (n) => {
+ this._setupData(n);
+ }, this._debug("initial negotiation"), this._needsNegotiation(), this._onFinishBound = () => {
+ this._onFinish();
+ }, this.once("finish", this._onFinishBound);
+ }
+ get bufferSize() {
+ return this._channel && this._channel.bufferedAmount || 0;
+ }
+ get connected() {
+ return this._connected && this._channel.readyState === "open";
+ }
+ address() {
+ return { port: this.localPort, family: this.localFamily, address: this.localAddress };
+ }
+ signal(e) {
+ if (!this._destroying) {
+ if (this.destroyed) throw P(new Error("cannot signal after peer is destroyed"), "ERR_DESTROYED");
+ if (typeof e == "string") try {
+ e = JSON.parse(e);
+ } catch {
+ e = {};
+ }
+ this._debug("signal()"), e.renegotiate && this.initiator && (this._debug("got request to renegotiate"), this._needsNegotiation()), e.transceiverRequest && this.initiator && (this._debug("got request for transceiver"), this.addTransceiver(e.transceiverRequest.kind, e.transceiverRequest.init)), e.candidate && (this._pc.remoteDescription && this._pc.remoteDescription.type ? this._addIceCandidate(e.candidate) : this._pendingCandidates.push(e.candidate)), e.sdp && this._pc.setRemoteDescription(new ys(e)).then(() => {
+ this.destroyed || (this._pendingCandidates.forEach((n) => {
+ this._addIceCandidate(n);
+ }), this._pendingCandidates = [], this._pc.remoteDescription.type === "offer" && this._createAnswer());
+ }).catch((n) => {
+ this.__destroy(P(n, "ERR_SET_REMOTE_DESCRIPTION"));
+ }), e.sdp || e.candidate || e.renegotiate || e.transceiverRequest || this.__destroy(P(new Error("signal() called with invalid signal data"), "ERR_SIGNALING"));
+ }
+ }
+ _addIceCandidate(e) {
+ const n = new Ss(e);
+ this._pc.addIceCandidate(n).catch((s) => {
+ var o;
+ !n.address || n.address.endsWith(".local") ? (o = "Ignoring unsupported ICE candidate.", console.warn(o)) : this.__destroy(P(s, "ERR_ADD_ICE_CANDIDATE"));
+ });
+ }
+ send(e) {
+ if (!this._destroying) {
+ if (this.destroyed) throw P(new Error("cannot send after peer is destroyed"), "ERR_DESTROYED");
+ this._channel.send(e);
+ }
+ }
+ _needsNegotiation() {
+ this._debug("_needsNegotiation"), this._batchedNegotiation || (this._batchedNegotiation = !0, queueMicrotask(() => {
+ this._batchedNegotiation = !1, this.initiator || !this._firstNegotiation ? (this._debug("starting batched negotiation"), this.negotiate()) : this._debug("non-initiator initial negotiation request discarded"), this._firstNegotiation = !1;
+ }));
+ }
+ negotiate() {
+ if (!this._destroying) {
+ if (this.destroyed) throw P(new Error("cannot negotiate after peer is destroyed"), "ERR_DESTROYED");
+ this.initiator ? this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("start negotiation"), setTimeout(() => {
+ this._createOffer();
+ }, 0)) : this._isNegotiating ? (this._queuedNegotiation = !0, this._debug("already negotiating, queueing")) : (this._debug("requesting negotiation from initiator"), this.emit("signal", { type: "renegotiate", renegotiate: !0 })), this._isNegotiating = !0;
+ }
+ }
+ _final(e) {
+ this._readableState.ended || this.push(null), e(null);
+ }
+ __destroy(e) {
+ this.end(), this._destroy(() => {
+ }, e);
+ }
+ _destroy(e, n) {
+ this.destroyed || this._destroying || (this._destroying = !0, this._debug("destroying (error: %s)", n && (n.message || n)), setTimeout(() => {
+ if (this._connected = !1, this._pcReady = !1, this._channelReady = !1, this._remoteTracks = null, this._remoteStreams = null, this._senderMap = null, clearInterval(this._closingInterval), this._closingInterval = null, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._onFinishBound && this.removeListener("finish", this._onFinishBound), this._onFinishBound = null, this._channel) {
+ try {
+ this._channel.close();
+ } catch {
+ }
+ this._channel.onmessage = null, this._channel.onopen = null, this._channel.onclose = null, this._channel.onerror = null;
+ }
+ if (this._pc) {
+ try {
+ this._pc.close();
+ } catch {
+ }
+ this._pc.oniceconnectionstatechange = null, this._pc.onicegatheringstatechange = null, this._pc.onsignalingstatechange = null, this._pc.onicecandidate = null, this._pc.ontrack = null, this._pc.ondatachannel = null;
+ }
+ this._pc = null, this._channel = null, n && this.emit("error", n), e();
+ }, 0));
+ }
+ _setupData(e) {
+ if (!e.channel) return this.__destroy(P(new Error("Data channel event is missing `channel` property"), "ERR_DATA_CHANNEL"));
+ this._channel = e.channel, this._channel.binaryType = "arraybuffer", typeof this._channel.bufferedAmountLowThreshold == "number" && (this._channel.bufferedAmountLowThreshold = ee), this.channelName = this._channel.label, this._channel.onmessage = (s) => {
+ this._onChannelMessage(s);
+ }, this._channel.onbufferedamountlow = () => {
+ this._onChannelBufferedAmountLow();
+ }, this._channel.onopen = () => {
+ this._onChannelOpen();
+ }, this._channel.onclose = () => {
+ this._onChannelClose();
+ }, this._channel.onerror = (s) => {
+ const o = s.error instanceof Error ? s.error : new Error(`Datachannel error: ${s.message} ${s.filename}:${s.lineno}:${s.colno}`);
+ this.__destroy(P(o, "ERR_DATA_CHANNEL"));
+ };
+ let n = !1;
+ this._closingInterval = setInterval(() => {
+ this._channel && this._channel.readyState === "closing" ? (n && this._onChannelClose(), n = !0) : n = !1;
+ }, 5e3);
+ }
+ _write(e, n) {
+ if (this.destroyed) return n(P(new Error("cannot write after peer is destroyed"), "ERR_DATA_CHANNEL"));
+ if (this._connected) {
+ try {
+ this.send(e);
+ } catch (s) {
+ return this.__destroy(P(s, "ERR_DATA_CHANNEL"));
+ }
+ this._channel.bufferedAmount > ee ? (this._debug("start backpressure: bufferedAmount %d", this._channel.bufferedAmount), this._cb = n) : n(null);
+ } else this._debug("write before connect"), this._chunk = e, this._cb = n;
+ }
+ _onFinish() {
+ if (this.destroyed) return;
+ const e = () => {
+ setTimeout(() => this.__destroy(), 1e3);
+ };
+ this._connected ? e() : this.once("connect", e);
+ }
+ _startIceCompleteTimeout() {
+ this.destroyed || this._iceCompleteTimer || (this._debug("started iceComplete timeout"), this._iceCompleteTimer = setTimeout(() => {
+ this._iceComplete || (this._iceComplete = !0, this._debug("iceComplete timeout completed"), 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 = un(e.sdp)), e.sdp = this.sdpTransform(e.sdp);
+ const n = () => {
+ if (this.destroyed) return;
+ const s = this._pc.localDescription || e;
+ this._debug("signal"), this.emit("signal", { type: s.type, sdp: s.sdp });
+ };
+ this._pc.setLocalDescription(e).then(() => {
+ this._debug("createOffer success"), this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n));
+ }).catch((s) => {
+ this.__destroy(P(s, "ERR_SET_LOCAL_DESCRIPTION"));
+ });
+ }).catch((e) => {
+ this.__destroy(P(e, "ERR_CREATE_OFFER"));
+ });
+ }
+ _createAnswer() {
+ this.destroyed || this._pc.createAnswer(this.answerOptions).then((e) => {
+ if (this.destroyed) return;
+ this.trickle || this.allowHalfTrickle || (e.sdp = un(e.sdp)), e.sdp = this.sdpTransform(e.sdp);
+ const n = () => {
+ var o;
+ if (this.destroyed) return;
+ const s = this._pc.localDescription || e;
+ this._debug("signal"), this.emit("signal", { type: s.type, sdp: s.sdp }), this.initiator || ((o = this._requestMissingTransceivers) == null || o.call(this));
+ };
+ this._pc.setLocalDescription(e).then(() => {
+ this.destroyed || (this.trickle || this._iceComplete ? n() : this.once("_iceComplete", n));
+ }).catch((s) => {
+ this.__destroy(P(s, "ERR_SET_LOCAL_DESCRIPTION"));
+ });
+ }).catch((e) => {
+ this.__destroy(P(e, "ERR_CREATE_ANSWER"));
+ });
+ }
+ _onConnectionStateChange() {
+ this.destroyed || this._destroying || this._pc.connectionState === "failed" && this.__destroy(P(new Error("Connection failed."), "ERR_CONNECTION_FAILURE"));
+ }
+ _onIceStateChange() {
+ if (this.destroyed) return;
+ const e = this._pc.iceConnectionState, n = this._pc.iceGatheringState;
+ this._debug("iceStateChange (connection: %s) (gathering: %s)", e, n), this.emit("iceStateChange", e, n), e !== "connected" && e !== "completed" || (this._pcReady = !0, this._maybeReady()), e === "failed" && this.__destroy(P(new Error("Ice connection failed."), "ERR_ICE_CONNECTION_FAILURE")), e === "closed" && this.__destroy(P(new Error("Ice connection closed."), "ERR_ICE_CONNECTION_CLOSED"));
+ }
+ getStats(e) {
+ const n = (s) => (Object.prototype.toString.call(s.values) === "[object Array]" && s.values.forEach((o) => {
+ Object.assign(s, o);
+ }), s);
+ this._pc.getStats.length === 0 || this._isReactNativeWebrtc ? this._pc.getStats().then((s) => {
+ const o = [];
+ s.forEach((h) => {
+ o.push(n(h));
+ }), e(null, o);
+ }, (s) => e(s)) : this._pc.getStats.length > 0 ? this._pc.getStats((s) => {
+ if (this.destroyed) return;
+ const o = [];
+ s.result().forEach((h) => {
+ const a = {};
+ h.names().forEach((g) => {
+ a[g] = h.stat(g);
+ }), a.id = h.id, a.type = h.type, a.timestamp = h.timestamp, o.push(n(a));
+ }), e(null, o);
+ }, (s) => e(s)) : e(null, []);
+ }
+ _maybeReady() {
+ if (this._debug("maybeReady pc %s channel %s", this._pcReady, this._channelReady), this._connected || this._connecting || !this._pcReady || !this._channelReady) return;
+ this._connecting = !0;
+ const e = () => {
+ this.destroyed || this._destroying || this.getStats((n, s) => {
+ if (this.destroyed || this._destroying) return;
+ n && (s = []);
+ const o = {}, h = {}, a = {};
+ let g = !1;
+ s.forEach((u) => {
+ u.type !== "remotecandidate" && u.type !== "remote-candidate" || (o[u.id] = u), u.type !== "localcandidate" && u.type !== "local-candidate" || (h[u.id] = u), u.type !== "candidatepair" && u.type !== "candidate-pair" || (a[u.id] = u);
+ });
+ const S = (u) => {
+ g = !0;
+ let f = h[u.localCandidateId];
+ f && (f.ip || f.address) ? (this.localAddress = f.ip || f.address, this.localPort = Number(f.port)) : f && f.ipAddress ? (this.localAddress = f.ipAddress, this.localPort = Number(f.portNumber)) : typeof u.googLocalAddress == "string" && (f = u.googLocalAddress.split(":"), this.localAddress = f[0], this.localPort = Number(f[1])), this.localAddress && (this.localFamily = this.localAddress.includes(":") ? "IPv6" : "IPv4");
+ let b = o[u.remoteCandidateId];
+ b && (b.ip || b.address) ? (this.remoteAddress = b.ip || b.address, this.remotePort = Number(b.port)) : b && b.ipAddress ? (this.remoteAddress = b.ipAddress, this.remotePort = Number(b.portNumber)) : typeof u.googRemoteAddress == "string" && (b = u.googRemoteAddress.split(":"), this.remoteAddress = b[0], this.remotePort = Number(b[1])), this.remoteAddress && (this.remoteFamily = this.remoteAddress.includes(":") ? "IPv6" : "IPv4"), this._debug("connect local: %s:%s remote: %s:%s", this.localAddress, this.localPort, this.remoteAddress, this.remotePort);
+ };
+ if (s.forEach((u) => {
+ u.type === "transport" && u.selectedCandidatePairId && S(a[u.selectedCandidatePairId]), (u.type === "googCandidatePair" && u.googActiveConnection === "true" || (u.type === "candidatepair" || u.type === "candidate-pair") && u.selected) && S(u);
+ }), g || Object.keys(a).length && !Object.keys(h).length) {
+ if (this._connecting = !1, this._connected = !0, this._chunk) {
+ try {
+ this.send(this._chunk);
+ } catch (f) {
+ return this.__destroy(P(f, "ERR_DATA_CHANNEL"));
+ }
+ this._chunk = null, this._debug('sent chunk from "write before connect"');
+ const u = this._cb;
+ this._cb = null, u(null);
+ }
+ typeof this._channel.bufferedAmountLowThreshold != "number" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect");
+ } else setTimeout(e, 100);
+ });
+ };
+ e();
+ }
+ _onInterval() {
+ !this._cb || !this._channel || this._channel.bufferedAmount > ee || this._onChannelBufferedAmountLow();
+ }
+ _onSignalingStateChange() {
+ this.destroyed || (this._pc.signalingState === "stable" && (this._isNegotiating = !1, this._debug("flushing sender queue", this._sendersAwaitingStable), this._sendersAwaitingStable.forEach((e) => {
+ this._pc.removeTrack(e), this._queuedNegotiation = !0;
+ }), this._sendersAwaitingStable = [], this._queuedNegotiation ? (this._debug("flushing negotiation queue"), this._queuedNegotiation = !1, this._needsNegotiation()) : (this._debug("negotiated"), this.emit("negotiated"))), this._debug("signalingStateChange %s", this._pc.signalingState), 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 n = e.data;
+ n instanceof ArrayBuffer ? n = new Uint8Array(n) : this.__objectMode === !1 && (n = Se(n)), this.push(n);
+ }
+ _onChannelBufferedAmountLow() {
+ if (this.destroyed || !this._cb) return;
+ this._debug("ending backpressure: bufferedAmount %d", this._channel.bufferedAmount);
+ const e = this._cb;
+ this._cb = null, e(null);
+ }
+ _onChannelOpen() {
+ this._connected || this.destroyed || (this._debug("on channel open"), this._channelReady = !0, this._maybeReady());
+ }
+ _onChannelClose() {
+ this.destroyed || (this._debug("on channel close"), this.__destroy());
+ }
+ _debug() {
+ const e = [].slice.call(arguments);
+ e[0] = "[" + this._id + "] " + e[0], xs.apply(null, e);
+ }
+};
+kt.WEBRTC_SUPPORT = !!de, kt.config = { iceServers: [{ urls: ["stun:stun.l.google.com:19302", "stun:global.stun.twilio.com:3478"] }], sdpSemantics: "unified-plan" }, kt.channelConfig = {};
+const ge = ot(In()), U = {}, me = { DEFAULT_ANNOUNCE_PEERS: 50, MAX_ANNOUNCE_PEERS: 82, parseUrl: (r) => {
+ const t = new URL(r.replace(/^udp:/, "http:"));
+ return r.match(/^udp:/) && Object.defineProperties(t, { href: { value: t.href.replace(/^http/, "udp") }, protocol: { value: t.protocol.replace(/^http/, "udp") }, origin: { value: t.origin.replace(/^http/, "udp") } }), t;
+}, ...Object.freeze(Object.defineProperty({ __proto__: null, default: U }, Symbol.toStringTag, { value: "Module" })) }, As = H("simple-websocket"), bt = typeof U != "function" ? WebSocket : U;
+class qn extends En.Duplex {
+ constructor(t = {}) {
+ if (typeof t == "string" && (t = { url: t }), super(t = Object.assign({ allowHalfOpen: !1 }, t)), this.__objectMode = !!t.objectMode, t.objectMode != null && delete t.objectMode, t.url == null && t.socket == null) throw new Error("Missing required `url` or `socket` option");
+ if (t.url != null && t.socket != null) throw new Error("Must specify either `url` or `socket` option, not both");
+ if (this._id = gt(Ut(4)).slice(0, 7), this._debug("new websocket: %o", t), this.connected = !1, this._chunk = null, this._cb = null, this._interval = null, t.socket) this.url = t.socket.url, this._ws = t.socket, this.connected = t.socket.readyState === bt.OPEN;
+ else {
+ this.url = t.url;
+ try {
+ this._ws = typeof U == "function" ? new bt(t.url, { ...t, encoding: void 0 }) : new bt(t.url);
+ } catch (e) {
+ return void ge(() => this.destroy(e));
+ }
+ }
+ this._ws.binaryType = "arraybuffer", t.socket && this.connected ? ge(() => this._handleOpen()) : this._ws.onopen = () => this._handleOpen(), this._ws.onmessage = (e) => this._handleMessage(e), this._ws.onclose = () => this._handleClose(), this._ws.onerror = (e) => this._handleError(e), this._handleFinishBound = () => this._handleFinish(), this.once("finish", this._handleFinishBound);
+ }
+ send(t) {
+ this._ws.send(t);
+ }
+ _final(t) {
+ this._readableState.ended || this.push(null), t(null);
+ }
+ _destroy(t) {
+ if (!this.destroyed) {
+ if (this._writableState.ended || this.end(), this.connected = !1, clearInterval(this._interval), this._interval = null, this._chunk = null, this._cb = null, this._handleFinishBound && this.removeListener("finish", this._handleFinishBound), this._handleFinishBound = null, this._ws) {
+ const e = this._ws, n = () => {
+ e.onclose = null;
+ };
+ if (e.readyState === bt.CLOSED) n();
+ else try {
+ e.onclose = n, e.close();
+ } catch {
+ n();
+ }
+ e.onopen = null, e.onmessage = null, e.onerror = () => {
+ };
+ }
+ this._ws = null, t();
+ }
+ }
+ _write(t, e) {
+ if (this.destroyed) return e(new Error("cannot write after socket is destroyed"));
+ if (this.connected) {
+ try {
+ this.send(t);
+ } catch (n) {
+ return this.destroy(n);
+ }
+ typeof U != "function" && this._ws.bufferedAmount > 65536 ? (this._debug("start backpressure: bufferedAmount %d", this._ws.bufferedAmount), this._cb = e) : e(null);
+ } else this._debug("write before connect"), this._chunk = t, this._cb = e;
+ }
+ _handleOpen() {
+ if (!this.connected && !this.destroyed) {
+ if (this.connected = !0, this._chunk) {
+ try {
+ this.send(this._chunk);
+ } catch (e) {
+ return this.destroy(e);
+ }
+ this._chunk = null, this._debug('sent chunk from "write before connect"');
+ const t = this._cb;
+ this._cb = null, t(null);
+ }
+ typeof U != "function" && (this._interval = setInterval(() => this._onInterval(), 150), this._interval.unref && this._interval.unref()), this._debug("connect"), this.emit("connect");
+ }
+ }
+ _handleMessage(t) {
+ if (this.destroyed) return;
+ let e = t.data;
+ e instanceof ArrayBuffer && (e = new Uint8Array(e)), this.__objectMode === !1 && (e = Se(e)), this.push(e);
+ }
+ _handleClose() {
+ this.destroyed || (this._debug("on close"), this.destroy());
+ }
+ _handleError(t) {
+ this.destroy(new Error(`Error connecting to ${this.url}`));
+ }
+ _handleFinish() {
+ if (this.destroyed) return;
+ const t = () => {
+ setTimeout(() => this.destroy(), 1e3);
+ };
+ this.connected ? t() : this.once("connect", t);
+ }
+ _onInterval() {
+ if (!this._cb || !this._ws || this._ws.bufferedAmount > 65536) return;
+ this._debug("ending backpressure: bufferedAmount %d", this._ws.bufferedAmount);
+ const t = this._cb;
+ this._cb = null, t(null);
+ }
+ _debug() {
+ const t = [].slice.call(arguments);
+ t[0] = "[" + this._id + "] " + t[0], As.apply(null, t);
+ }
+}
+qn.WEBSOCKET_SUPPORT = !!bt;
+class Ls extends Ln {
+ constructor(t, e) {
+ super(), this.client = t, this.announceUrl = e, this.interval = null, this.destroyed = !1;
+ }
+ setInterval(t) {
+ t == null && (t = this.DEFAULT_ANNOUNCE_INTERVAL), clearInterval(this.interval), t && (this.interval = setInterval(() => {
+ this.announce(this.client._defaultAnnounceOpts());
+ }, t), this.interval.unref && this.interval.unref());
+ }
+}
+const M = H("bittorrent-tracker:websocket-tracker"), z = {};
+class pe extends Ls {
+ constructor(t, e) {
+ super(t, e), M("new websocket tracker %s", e), this.peers = {}, this.socket = null, this.reconnecting = !1, this.retries = 0, this.reconnectTimer = null, this.expectingResponse = !1, this._openSocket();
+ }
+ announce(t) {
+ if (this.destroyed || this.reconnecting) return;
+ if (!this.socket.connected) return void this.socket.once("connect", () => {
+ this.announce(t);
+ });
+ const e = Object.assign({}, t, { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary });
+ if (this._trackerId && (e.trackerid = this._trackerId), t.event === "stopped" || t.event === "completed") this._send(e);
+ else {
+ const n = Math.min(t.numwant, 5);
+ this._generateOffers(n, (s) => {
+ e.numwant = n, e.offers = s, this._send(e);
+ });
+ }
+ }
+ scrape(t) {
+ if (this.destroyed || this.reconnecting) return;
+ if (!this.socket.connected) return void this.socket.once("connect", () => {
+ this.scrape(t);
+ });
+ const e = { action: "scrape", info_hash: Array.isArray(t.infoHash) && t.infoHash.length > 0 ? t.infoHash.map((n) => vt(n)) : t.infoHash && vt(t.infoHash) || this.client._infoHashBinary };
+ this._send(e);
+ }
+ destroy(t = ln) {
+ if (this.destroyed) return t(null);
+ this.destroyed = !0, clearInterval(this.interval), clearTimeout(this.reconnectTimer);
+ for (const o in this.peers) {
+ const h = this.peers[o];
+ clearTimeout(h.trackerTimeout), h.destroy();
+ }
+ if (this.peers = null, this.socket && (this.socket.removeListener("connect", this._onSocketConnectBound), this.socket.removeListener("data", this._onSocketDataBound), this.socket.removeListener("close", this._onSocketCloseBound), this.socket.removeListener("error", this._onSocketErrorBound), this.socket = null), this._onSocketConnectBound = null, this._onSocketErrorBound = null, this._onSocketDataBound = null, this._onSocketCloseBound = null, z[this.announceUrl] && (z[this.announceUrl].consumers -= 1), z[this.announceUrl].consumers > 0) return t();
+ let e, n = z[this.announceUrl];
+ if (delete z[this.announceUrl], n.on("error", ln), n.once("close", t), !this.expectingResponse) return s();
+ function s() {
+ e && (clearTimeout(e), e = null), n.removeListener("data", s), n.destroy(), n = null;
+ }
+ e = setTimeout(s, me.DESTROY_TIMEOUT), n.once("data", s);
+ }
+ _openSocket() {
+ if (this.destroyed = !1, this.peers || (this.peers = {}), this._onSocketConnectBound = () => {
+ this._onSocketConnect();
+ }, this._onSocketErrorBound = (t) => {
+ this._onSocketError(t);
+ }, this._onSocketDataBound = (t) => {
+ this._onSocketData(t);
+ }, this._onSocketCloseBound = () => {
+ this._onSocketClose();
+ }, this.socket = z[this.announceUrl], this.socket) z[this.announceUrl].consumers += 1, this.socket.connected && this._onSocketConnectBound();
+ else {
+ const t = new URL(this.announceUrl);
+ let e;
+ this.client._proxyOpts && (e = t.protocol === "wss:" ? this.client._proxyOpts.httpsAgent : this.client._proxyOpts.httpAgent, !e && this.client._proxyOpts.socksProxy && (e = this.client._proxyOpts.socksProxy)), this.socket = z[this.announceUrl] = new qn({ url: this.announceUrl, agent: e }), this.socket.consumers = 1, this.socket.once("connect", this._onSocketConnectBound);
+ }
+ this.socket.on("data", this._onSocketDataBound), this.socket.once("close", this._onSocketCloseBound), this.socket.once("error", this._onSocketErrorBound);
+ }
+ _onSocketConnect() {
+ this.destroyed || this.reconnecting && (this.reconnecting = !1, this.retries = 0, this.announce(this.client._defaultAnnounceOpts()));
+ }
+ _onSocketData(t) {
+ if (!this.destroyed) {
+ this.expectingResponse = !1;
+ try {
+ t = JSON.parse(Pn(t));
+ } catch {
+ return void this.client.emit("warning", new Error("Invalid tracker response"));
+ }
+ t.action === "announce" ? this._onAnnounceResponse(t) : t.action === "scrape" ? this._onScrapeResponse(t) : this._onSocketError(new Error(`invalid action in WS response: ${t.action}`));
+ }
+ }
+ _onAnnounceResponse(t) {
+ if (t.info_hash !== this.client._infoHashBinary) return void M("ignoring websocket data from %s for %s (looking for %s: reused socket)", this.announceUrl, dt(t.info_hash), this.client.infoHash);
+ if (t.peer_id && t.peer_id === this.client._peerIdBinary) return;
+ M("received %s from %s for %s", JSON.stringify(t), this.announceUrl, this.client.infoHash);
+ const e = t["failure reason"];
+ if (e) return this.client.emit("warning", new Error(e));
+ const n = t["warning message"];
+ n && this.client.emit("warning", new Error(n));
+ const s = t.interval || t["min interval"];
+ s && this.setInterval(1e3 * s);
+ const o = t["tracker id"];
+ if (o && (this._trackerId = o), t.complete != null) {
+ const a = Object.assign({}, t, { announce: this.announceUrl, infoHash: dt(t.info_hash) });
+ this.client.emit("update", a);
+ }
+ let h;
+ if (t.offer && t.peer_id && (M("creating peer (from remote offer)"), h = this._createPeer(), h.id = dt(t.peer_id), h.once("signal", (a) => {
+ const g = { action: "announce", info_hash: this.client._infoHashBinary, peer_id: this.client._peerIdBinary, to_peer_id: t.peer_id, answer: a, offer_id: t.offer_id };
+ this._trackerId && (g.trackerid = this._trackerId), this._send(g);
+ }), this.client.emit("peer", h), h.signal(t.offer)), t.answer && t.peer_id) {
+ const a = dt(t.offer_id);
+ h = this.peers[a], h ? (h.id = dt(t.peer_id), this.client.emit("peer", h), h.signal(t.answer), clearTimeout(h.trackerTimeout), h.trackerTimeout = null, delete this.peers[a]) : M(`got unexpected answer: ${JSON.stringify(t.answer)}`);
+ }
+ }
+ _onScrapeResponse(t) {
+ t = t.files || {};
+ const e = Object.keys(t);
+ e.length !== 0 ? e.forEach((n) => {
+ const s = Object.assign(t[n], { announce: this.announceUrl, infoHash: dt(n) });
+ this.client.emit("scrape", s);
+ }) : this.client.emit("warning", new Error("invalid scrape response"));
+ }
+ _onSocketClose() {
+ this.destroyed || (this.destroy(), this._startReconnectTimer());
+ }
+ _onSocketError(t) {
+ this.destroyed || (this.destroy(), this.client.emit("warning", t), this._startReconnectTimer());
+ }
+ _startReconnectTimer() {
+ const t = Math.floor(3e5 * Math.random()) + Math.min(1e4 * Math.pow(2, this.retries), 36e5);
+ this.reconnecting = !0, clearTimeout(this.reconnectTimer), this.reconnectTimer = setTimeout(() => {
+ this.retries++, this._openSocket();
+ }, t), this.reconnectTimer.unref && this.reconnectTimer.unref(), M("reconnecting socket in %s ms", t);
+ }
+ _send(t) {
+ if (this.destroyed) return;
+ this.expectingResponse = !0;
+ const e = JSON.stringify(t);
+ M("send %s", e), this.socket.send(e);
+ }
+ _generateOffers(t, e) {
+ const n = this, s = [];
+ M("generating %s offers", t);
+ for (let a = 0; a < t; ++a) o();
+ function o() {
+ const a = gt(Ut(20));
+ M("creating peer (from _generateOffers)");
+ const g = n.peers[a] = n._createPeer({ initiator: !0 });
+ g.once("signal", (S) => {
+ s.push({ offer: S, offer_id: vt(a) }), h();
+ }), g.trackerTimeout = setTimeout(() => {
+ M("tracker timeout: destroying peer"), g.trackerTimeout = null, delete n.peers[a], g.destroy();
+ }, 5e4), g.trackerTimeout.unref && g.trackerTimeout.unref();
+ }
+ function h() {
+ s.length === t && (M("generated %s offers", t), e(s));
+ }
+ h();
+ }
+ _createPeer(t) {
+ const e = this;
+ t = Object.assign({ trickle: !1, config: e.client._rtcConfig, wrtc: e.client._wrtc }, t);
+ const n = new kt(t);
+ return n.once("error", s), n.once("connect", function o() {
+ n.removeListener("error", s), n.removeListener("connect", o);
+ }), n;
+ function s(o) {
+ e.client.emit("warning", new Error(`Connection error: ${o.message}`)), n.destroy();
+ }
+ }
+}
+function ln() {
+}
+pe.prototype.DEFAULT_ANNOUNCE_INTERVAL = 3e4, pe._socketPool = z;
+const X = H("bittorrent-tracker:client");
+class fe extends Ln {
+ constructor(t = {}) {
+ if (super(), !t.peerId) throw new Error("Option `peerId` is required");
+ if (!t.infoHash) throw new Error("Option `infoHash` is required");
+ if (!t.announce) throw new Error("Option `announce` is required");
+ if (!Nt.browser && !t.port) throw new Error("Option `port` is required");
+ this.peerId = typeof t.peerId == "string" ? t.peerId : gt(t.peerId), this._peerIdBuffer = ce(this.peerId), this._peerIdBinary = vt(this.peerId), this.infoHash = typeof t.infoHash == "string" ? t.infoHash.toLowerCase() : gt(t.infoHash), this._infoHashBuffer = ce(this.infoHash), this._infoHashBinary = vt(this.infoHash), X("new client %s", this.infoHash), this.destroyed = !1, this._port = t.port, this._getAnnounceOpts = t.getAnnounceOpts, this._rtcConfig = t.rtcConfig, this._userAgent = t.userAgent, this._proxyOpts = t.proxyOpts, this._wrtc = typeof t.wrtc == "function" ? t.wrtc() : t.wrtc;
+ let e = typeof t.announce == "string" ? [t.announce] : t.announce == null ? [] : t.announce;
+ e = e.map((o) => (ArrayBuffer.isView(o) && (o = Pn(o)), o[o.length - 1] === "/" && (o = o.substring(0, o.length - 1)), o)), e = Array.from(new Set(e));
+ const n = this._wrtc !== !1 && (!!this._wrtc || kt.WEBRTC_SUPPORT), s = (o) => {
+ ge(() => {
+ this.emit("warning", o);
+ });
+ };
+ this._trackers = e.map((o) => {
+ let h;
+ try {
+ h = me.parseUrl(o);
+ } catch {
+ return s(new Error(`Invalid tracker URL: ${o}`)), null;
+ }
+ const a = h.port;
+ if (a < 0 || a > 65535) return s(new Error(`Invalid tracker port: ${o}`)), null;
+ const g = h.protocol;
+ return g !== "http:" && g !== "https:" || typeof U != "function" ? g === "udp:" && typeof U == "function" ? new U(this, o) : g !== "ws:" && g !== "wss:" || !n || g === "ws:" && typeof window < "u" && window.location.protocol === "https:" ? (s(new Error(`Unsupported tracker protocol: ${o}`)), null) : new pe(this, o) : new U(this, o);
+ }).filter(Boolean);
+ }
+ start(t) {
+ (t = this._defaultAnnounceOpts(t)).event = "started", X("send `start` %o", t), this._announce(t), this._trackers.forEach((e) => {
+ e.setInterval();
+ });
+ }
+ stop(t) {
+ (t = this._defaultAnnounceOpts(t)).event = "stopped", X("send `stop` %o", t), this._announce(t);
+ }
+ complete(t) {
+ t || (t = {}), (t = this._defaultAnnounceOpts(t)).event = "completed", X("send `complete` %o", t), this._announce(t);
+ }
+ update(t) {
+ (t = this._defaultAnnounceOpts(t)).event && delete t.event, X("send `update` %o", t), this._announce(t);
+ }
+ _announce(t) {
+ this._trackers.forEach((e) => {
+ e.announce(t);
+ });
+ }
+ scrape(t) {
+ X("send `scrape`"), t || (t = {}), this._trackers.forEach((e) => {
+ e.scrape(t);
+ });
+ }
+ setInterval(t) {
+ X("setInterval %d", t), this._trackers.forEach((e) => {
+ e.setInterval(t);
+ });
+ }
+ destroy(t) {
+ if (this.destroyed) return;
+ this.destroyed = !0, X("destroy");
+ const e = this._trackers.map((n) => (s) => {
+ n.destroy(s);
+ });
+ _s(e, t), this._trackers = [], this._getAnnounceOpts = null;
+ }
+ _defaultAnnounceOpts(t = {}) {
+ return t.numwant == null && (t.numwant = me.DEFAULT_ANNOUNCE_PEERS), t.uploaded == null && (t.uploaded = 0), t.downloaded == null && (t.downloaded = 0), this._getAnnounceOpts && (t = Object.assign({}, t, this._getAnnounceOpts())), t;
+ }
+}
+fe.scrape = (r, t) => {
+ if (t = ps(t), !r.infoHash) throw new Error("Option `infoHash` is required");
+ if (!r.announce) throw new Error("Option `announce` is required");
+ const e = Object.assign({}, r, { infoHash: Array.isArray(r.infoHash) ? r.infoHash[0] : r.infoHash, peerId: Se("01234567890123456789"), port: 6881 }), n = new fe(e);
+ n.once("error", t), n.once("warning", t);
+ let s = Array.isArray(r.infoHash) ? r.infoHash.length : 1;
+ const o = {};
+ return n.on("scrape", (h) => {
+ if (s -= 1, o[h.infoHash] = h, s === 0) {
+ n.destroy();
+ const a = Object.keys(o);
+ a.length === 1 ? t(null, o[a[0]]) : t(null, o);
+ }
+ }), n.scrape({ infoHash: r.infoHash }), n;
+};
+var gn, ne = { exports: {} }, Is = function() {
+ if (gn) return ne.exports;
+ function r(C, d, l, c, m, p, _) {
+ var T = C + (d & l | ~d & c) + (m >>> 0) + _;
+ return (T << p | T >>> 32 - p) + d;
+ }
+ function t(C, d, l, c, m, p, _) {
+ var T = C + (d & c | l & ~c) + (m >>> 0) + _;
+ return (T << p | T >>> 32 - p) + d;
+ }
+ function e(C, d, l, c, m, p, _) {
+ var T = C + (d ^ l ^ c) + (m >>> 0) + _;
+ return (T << p | T >>> 32 - p) + d;
+ }
+ function n(C, d, l, c, m, p, _) {
+ var T = C + (l ^ (d | ~c)) + (m >>> 0) + _;
+ return (T << p | T >>> 32 - p) + d;
+ }
+ function s(C) {
+ return String.fromCharCode(255 & C);
+ }
+ function o(C) {
+ return s(C) + s(C >>> 8) + s(C >>> 16) + s(C >>> 24);
+ }
+ gn = 1;
+ var h = function(C) {
+ return unescape(encodeURIComponent(C));
+ }, a = ne.exports = function(C) {
+ return S(C).toHex();
+ }, g = a.fromBytes = function(C) {
+ for (var d = function(j) {
+ for (var F = j.length, ht = F << 3, Z = new Uint32Array(F + 72 >>> 6 << 4), W = 0, pt = j.length; W < pt; ++W) Z[W >>> 2] |= j.charCodeAt(W) << ((3 & W) << 3);
+ return Z[F >> 2] |= 128 << (31 & ht), Z[Z.length - 2] = ht, Z;
+ }(C), l = 1732584193, c = 4023233417, m = 2562383102, p = 271733878, _ = 0, T = d.length; _ < T; _ += 16) {
+ var I = l, B = c, at = m, zt = p;
+ l = r(l, c, m, p, d[_ + 0], 7, 3614090360), p = r(p, l, c, m, d[_ + 1], 12, 3905402710), m = r(m, p, l, c, d[_ + 2], 17, 606105819), c = r(c, m, p, l, d[_ + 3], 22, 3250441966), l = r(l, c, m, p, d[_ + 4], 7, 4118548399), p = r(p, l, c, m, d[_ + 5], 12, 1200080426), m = r(m, p, l, c, d[_ + 6], 17, 2821735955), c = r(c, m, p, l, d[_ + 7], 22, 4249261313), l = r(l, c, m, p, d[_ + 8], 7, 1770035416), p = r(p, l, c, m, d[_ + 9], 12, 2336552879), m = r(m, p, l, c, d[_ + 10], 17, 4294925233), c = r(c, m, p, l, d[_ + 11], 22, 2304563134), l = r(l, c, m, p, d[_ + 12], 7, 1804603682), p = r(p, l, c, m, d[_ + 13], 12, 4254626195), m = r(m, p, l, c, d[_ + 14], 17, 2792965006), l = t(l, c = r(c, m, p, l, d[_ + 15], 22, 1236535329), m, p, d[_ + 1], 5, 4129170786), p = t(p, l, c, m, d[_ + 6], 9, 3225465664), m = t(m, p, l, c, d[_ + 11], 14, 643717713), c = t(c, m, p, l, d[_ + 0], 20, 3921069994), l = t(l, c, m, p, d[_ + 5], 5, 3593408605), p = t(p, l, c, m, d[_ + 10], 9, 38016083), m = t(m, p, l, c, d[_ + 15], 14, 3634488961), c = t(c, m, p, l, d[_ + 4], 20, 3889429448), l = t(l, c, m, p, d[_ + 9], 5, 568446438), p = t(p, l, c, m, d[_ + 14], 9, 3275163606), m = t(m, p, l, c, d[_ + 3], 14, 4107603335), c = t(c, m, p, l, d[_ + 8], 20, 1163531501), l = t(l, c, m, p, d[_ + 13], 5, 2850285829), p = t(p, l, c, m, d[_ + 2], 9, 4243563512), m = t(m, p, l, c, d[_ + 7], 14, 1735328473), l = e(l, c = t(c, m, p, l, d[_ + 12], 20, 2368359562), m, p, d[_ + 5], 4, 4294588738), p = e(p, l, c, m, d[_ + 8], 11, 2272392833), m = e(m, p, l, c, d[_ + 11], 16, 1839030562), c = e(c, m, p, l, d[_ + 14], 23, 4259657740), l = e(l, c, m, p, d[_ + 1], 4, 2763975236), p = e(p, l, c, m, d[_ + 4], 11, 1272893353), m = e(m, p, l, c, d[_ + 7], 16, 4139469664), c = e(c, m, p, l, d[_ + 10], 23, 3200236656), l = e(l, c, m, p, d[_ + 13], 4, 681279174), p = e(p, l, c, m, d[_ + 0], 11, 3936430074), m = e(m, p, l, c, d[_ + 3], 16, 3572445317), c = e(c, m, p, l, d[_ + 6], 23, 76029189), l = e(l, c, m, p, d[_ + 9], 4, 3654602809), p = e(p, l, c, m, d[_ + 12], 11, 3873151461), m = e(m, p, l, c, d[_ + 15], 16, 530742520), l = n(l, c = e(c, m, p, l, d[_ + 2], 23, 3299628645), m, p, d[_ + 0], 6, 4096336452), p = n(p, l, c, m, d[_ + 7], 10, 1126891415), m = n(m, p, l, c, d[_ + 14], 15, 2878612391), c = n(c, m, p, l, d[_ + 5], 21, 4237533241), l = n(l, c, m, p, d[_ + 12], 6, 1700485571), p = n(p, l, c, m, d[_ + 3], 10, 2399980690), m = n(m, p, l, c, d[_ + 10], 15, 4293915773), c = n(c, m, p, l, d[_ + 1], 21, 2240044497), l = n(l, c, m, p, d[_ + 8], 6, 1873313359), p = n(p, l, c, m, d[_ + 15], 10, 4264355552), m = n(m, p, l, c, d[_ + 6], 15, 2734768916), c = n(c, m, p, l, d[_ + 13], 21, 1309151649), l = n(l, c, m, p, d[_ + 4], 6, 4149444226), p = n(p, l, c, m, d[_ + 11], 10, 3174756917), m = n(m, p, l, c, d[_ + 2], 15, 718787259), c = n(c, m, p, l, d[_ + 9], 21, 3951481745), l = l + I >>> 0, c = c + B >>> 0, m = m + at >>> 0, p = p + zt >>> 0;
+ }
+ var $ = new String(o(l) + o(c) + o(m) + o(p));
+ return $.toHex = function() {
+ for (var j = "", F = 0, ht = $.length; F < ht; ++F) j += (256 + (255 & $.charCodeAt(F))).toString(16).substr(-2);
+ return j;
+ }, $;
+ }, S = a.fromUtf8 = function(C) {
+ return g(h(C));
+ }, u = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ function f(C, d) {
+ for (var l = ""; --d >= 0; C >>>= 6) l += u.charAt(63 & C);
+ return l;
+ }
+ var b = [0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5, 11], x = a.salt = function(C) {
+ var d = "";
+ C || (C = 8);
+ do
+ d += u.charAt(64 * Math.random() >>> 0);
+ while (--C);
+ return d;
+ };
+ return a.crypt = function(C, d) {
+ if (C.length > 64) throw Error("too long key");
+ d || (d = "$1$" + x()), C = h(C);
+ for (var l = h(d.replace(/^\$1\$([^$]+)(?:\$.*)?$/, "$1")), c = g(C + l + C), m = C + "$1$" + l, p = C.length; p > 16; p -= 16) m += c;
+ for (m += c.slice(0, p), p = C.length; p; p >>= 1) m += 1 & p ? "\0" : C.charAt(0);
+ c = g(m);
+ for (var _ = 0; _ < 1e3; ++_) c = g((1 & _ ? C : c) + (_ % 3 ? l : "") + (_ % 7 ? C : "") + (1 & _ ? c : C));
+ var T = "$1$" + l + "$";
+ for (_ = 0; _ < 15; _ += 3) T += f(c.charCodeAt(b[_ + 0]) << 16 | c.charCodeAt(b[_ + 1]) << 8 | c.charCodeAt(b[_ + 2]), 4);
+ return T + f(c.charCodeAt(b[15]), 2);
+ }, ne.exports;
+}();
+const Es = ot(Is), Rs = `-PM${function(r) {
+ const t = r.split(".");
+ return `${t[0].padStart(2, "0")}${t[1].padStart(2, "0")}`;
+}("2.2.0")}-`, Ps = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+function nt(r) {
+ return `${r.type}-${r.index}`;
+}
+function mn(r) {
+ const { externalId: t } = r;
+ return `(${nt(r.stream)} | ${t})`;
+}
+function Bn(r, t) {
+ t === void 0 && (t = r.reduce((s, o) => s + o.byteLength, 0));
+ const e = new Uint8Array(t);
+ let n = 0;
+ for (const s of r) e.set(s, n), n += s.byteLength;
+ return e;
+}
+function pn(r) {
+ const t = new TextEncoder(), e = new Uint8Array(r.length);
+ return t.encodeInto(r, e), e;
+}
+function* fn(r) {
+ for (let t = r.length - 1; t >= 0; t--) yield r[t];
+}
+function On(r) {
+ return !!r && typeof r == "object" && !Array.isArray(r);
+}
+function et(r) {
+ if (function(t) {
+ return Array.isArray(t);
+ }(r)) return r.map((t) => et(t));
+ if (On(r)) {
+ const t = {};
+ for (const e of Object.keys(r)) t[e] = et(r[e]);
+ return t;
+ }
+ return r;
+}
+function wt(r, t, e = {}) {
+ return typeof r != "object" || r === null || typeof t != "object" || t === null || Object.keys(t).forEach((n) => {
+ if (n === "__proto__" || n === "constructor" || n === "prototype") throw new Error(`Attempt to modify restricted property '${String(n)}'`);
+ const s = t[n], o = e[n];
+ n in r && (r[n] = s === void 0 ? o === void 0 ? void 0 : o : s);
+ }), r;
+}
+function se(r) {
+ const { defaultConfig: t, baseConfig: e = {}, specificStreamConfig: n = {} } = r, s = et({ ...t, ...e, ...n }), o = Object.keys(t), h = {};
+ return o.forEach((a) => {
+ a in s && (h[a] = s[a]);
+ }), h;
+}
+var tt = ((r) => (r[r.SegmentsAnnouncement = 0] = "SegmentsAnnouncement", r[r.SegmentRequest = 1] = "SegmentRequest", r[r.SegmentData = 2] = "SegmentData", r[r.SegmentDataSendingCompleted = 3] = "SegmentDataSendingCompleted", r[r.SegmentAbsent = 4] = "SegmentAbsent", r[r.CancelSegmentRequest = 5] = "CancelSegmentRequest", r))(tt || {}), lt = ((r) => (r[r.Min = -1] = "Min", r[r.Int = 0] = "Int", r[r.SimilarIntArray = 1] = "SimilarIntArray", r[r.String = 2] = "String", r[r.Max = 3] = "Max", r))(lt || {});
+function qs(r) {
+ const t = r < 0, e = function(o) {
+ const h = o.toString(2), a = o < 0 ? h.length : h.length + 1;
+ return Math.ceil(a / 8);
+ }(r), n = new Uint8Array(e), s = BigInt(e);
+ r = function(o) {
+ return o < 0 ? -o : o;
+ }(r);
+ for (let o = 0; o < e; o++) {
+ const h = r >> 8n * (s - 1n - BigInt(o)) & 0xffn;
+ n[o] = Number(h);
+ }
+ return t && (n[0] = 128 | n[0]), n;
+}
+function Bs(r) {
+ const t = BigInt(r.length), e = (s, o) => {
+ const h = 8n * (t - 1n - BigInt(o));
+ return BigInt(s) << h;
+ };
+ let n = e(127 & r[0], 0);
+ for (let s = 1; s < t; s++) n = e(r[s], s) | n;
+ return (128 & r[0]) >> 7 && (n = -n), n;
+}
+function _n(r) {
+ const t = qs(r), e = 0 | t.length;
+ return new Uint8Array([e, ...t]);
+}
+function Dn(r) {
+ const t = r[0];
+ if (t >> 4) throw new Error("Trying to deserialize integer with invalid serialized item code");
+ const e = 15 & t, n = 1 + e;
+ return { number: Bs(r.slice(1, n)), byteLength: e + 1 };
+}
+function Os(r) {
+ const [t, e] = r;
+ if (t >> 4 !== 1) throw new Error("Trying to deserialize similar int array with invalid serialized item code");
+ let n = 2;
+ const s = [];
+ for (let o = 0; o < e; o++) {
+ const { number: h, byteLength: a } = Dn(r.slice(n));
+ n += a;
+ const g = 0xffn & h, S = -256n & h;
+ for (let u = 0; u < g; u++) {
+ const f = BigInt(r[n]);
+ s.push(S | f), n++;
+ }
+ }
+ return { numbers: s, byteLength: n };
+}
+function Ds(r) {
+ const [t, e] = r;
+ if (t >> 4 !== 2) throw new Error("Trying to deserialize bytes (sting) with invalid serialized item code.");
+ const n = (15 & t) << 8 | e, s = r.slice(2, n + 2);
+ return { string: new TextDecoder("utf8").decode(s), byteLength: n + 2 };
+}
+class Ct {
+ constructor() {
+ y(this, "bytes", []);
+ y(this, "_length", 0);
+ }
+ push(t) {
+ this.addBytes(t, "end");
+ }
+ unshift(t) {
+ this.addBytes(t, "start");
+ }
+ addBytes(t, e) {
+ let n;
+ n = t instanceof Uint8Array ? t : Array.isArray(t) ? new Uint8Array(t) : new Uint8Array([t]), this._length += n.length, this.bytes[e === "start" ? "unshift" : "push"](n);
+ }
+ getBytesChunks() {
+ return this.bytes;
+ }
+ getBuffer() {
+ return Bn(this.bytes, this._length);
+ }
+ get length() {
+ return this._length;
+ }
+}
+const mt = Qt("cstr", 4), Tt = Qt("cend", 4), _e = Qt("dstr", 4), ye = Qt("dend", 4), Ns = [mt, _e], Ms = [Tt, ye], yn = mt.length + Tt.length;
+function Nn(r) {
+ const { length: t } = mt, e = r.slice(-t);
+ return Ns.some((n) => $t(r, n, 4)) && Ms.some((n) => $t(e, n, 4));
+}
+class Ht extends Error {
+ constructor(t) {
+ super(), this.type = t;
+ }
+}
+class Mn {
+ constructor(t) {
+ y(this, "chunks", new Ct());
+ y(this, "status", "joining");
+ this.onComplete = t;
+ }
+ addCommandChunk(t) {
+ if (this.status === "completed") return;
+ const e = $t(t, mt, 4);
+ if (!this.chunks.length && !e) throw new Ht("no-first-chunk");
+ if (this.chunks.length && e) throw new Ht("incomplete-joining");
+ this.chunks.push(this.unframeCommandChunk(t)), function(n) {
+ return $t(n.slice(-4), Tt, 4);
+ }(t) && (this.status = "completed", this.onComplete(this.chunks.getBuffer()));
+ }
+ unframeCommandChunk(t) {
+ return t.slice(4, t.length - 4);
+ }
+}
+class Rt {
+ constructor(t, e) {
+ y(this, "bytes", new Ct());
+ y(this, "resultBuffers", []);
+ y(this, "status", "creating");
+ this.maxChunkLength = e, this.bytes.push(t);
+ }
+ addInteger(t, e) {
+ this.bytes.push(t.charCodeAt(0));
+ const n = _n(BigInt(e));
+ this.bytes.push(n);
+ }
+ addSimilarIntArr(t, e) {
+ this.bytes.push(t.charCodeAt(0));
+ const n = function(s) {
+ const o = /* @__PURE__ */ new Map();
+ for (const a of s) {
+ const g = -256n & a, S = 0xffn & a, u = o.get(g) ?? new Ct();
+ u.length || o.set(g, u), u.push(Number(S));
+ }
+ const h = new Ct();
+ h.push([16, o.size]);
+ for (const [a, g] of o) {
+ const { length: S } = g.getBytesChunks(), u = a | 0xffn & BigInt(S);
+ g.unshift(_n(u)), h.push(g.getBuffer());
+ }
+ return h.getBuffer();
+ }(e.map((s) => BigInt(s)));
+ this.bytes.push(n);
+ }
+ addString(t, e) {
+ this.bytes.push(t.charCodeAt(0));
+ const n = function(s) {
+ const { length: o } = s, h = new Ct();
+ return h.push([32 | o >> 8 & 15, 255 & o]), h.push(new TextEncoder().encode(s)), h.getBuffer();
+ }(e);
+ this.bytes.push(n);
+ }
+ complete() {
+ if (!this.bytes.length) throw new Error("Buffer is empty");
+ if (this.status === "completed") return;
+ this.status = "completed";
+ const t = this.bytes.getBuffer();
+ if (t.length + yn <= this.maxChunkLength) return void this.resultBuffers.push(Pt(t, mt, Tt));
+ let e = Math.ceil(t.length / this.maxChunkLength);
+ Math.ceil(t.length / e) + yn > this.maxChunkLength && e++;
+ for (const [n, s] of function* (o, h) {
+ const a = Math.ceil(o.length / h);
+ for (let g = 0; g < h; g++) yield [g, o.slice(g * a, (g + 1) * a)];
+ }(t, e)) n === 0 ? this.resultBuffers.push(Pt(s, mt, ye)) : n === e - 1 ? this.resultBuffers.push(Pt(s, _e, Tt)) : this.resultBuffers.push(Pt(s, _e, ye));
+ }
+ getResultBuffers() {
+ if (this.status === "creating" || !this.resultBuffers.length) throw new Error("Command is not complete.");
+ return this.resultBuffers;
+ }
+}
+function Fn(r) {
+ const [t] = r, e = { c: t };
+ let n = 1;
+ for (; n < r.length; ) {
+ const s = String.fromCharCode(r[n]);
+ switch (n++, Fs(r[n])) {
+ case lt.Int:
+ {
+ const { number: o, byteLength: h } = Dn(r.slice(n));
+ e[s] = Number(o), n += h;
+ }
+ break;
+ case lt.SimilarIntArray:
+ {
+ const { numbers: o, byteLength: h } = Os(r.slice(n));
+ e[s] = o.map((a) => Number(a)), n += h;
+ }
+ break;
+ case lt.String: {
+ const { string: o, byteLength: h } = Ds(r.slice(n));
+ e[s] = o, n += h;
+ }
+ }
+ }
+ return e;
+}
+function Fs(r) {
+ const t = r >> 4;
+ if (t <= lt.Min || t >= lt.Max) throw new Error("Not existing type");
+ return t;
+}
+function Qt(r, t) {
+ if (r.length !== t) throw new Error("Wrong string length");
+ const e = new Uint8Array(t);
+ for (let n = 0; n < r.length; n++) e[n] = r.charCodeAt(n);
+ return e;
+}
+function Pt(r, t, e) {
+ const n = new Uint8Array(r.length + t.length + e.length);
+ return n.set(t), n.set(r, t.length), n.set(e, t.length + r.length), n;
+}
+function $t(r, t, e) {
+ for (let n = 0; n < e; n++) if (r[n] !== t[n]) return !1;
+ return !0;
+}
+function Un(r, t) {
+ switch (r.c) {
+ case tt.CancelSegmentRequest:
+ case tt.SegmentAbsent:
+ case tt.SegmentDataSendingCompleted:
+ return function(e, n) {
+ const s = new Rt(e.c, n);
+ return s.addInteger("i", e.i), s.addInteger("r", e.r), s.complete(), s.getResultBuffers();
+ }(r, t);
+ case tt.SegmentRequest:
+ return function(e, n) {
+ const s = new Rt(e.c, n);
+ return s.addInteger("i", e.i), s.addInteger("r", e.r), e.b && s.addInteger("b", e.b), s.complete(), s.getResultBuffers();
+ }(r, t);
+ case tt.SegmentsAnnouncement:
+ return function(e, n) {
+ const { c: s, p: o, l: h } = e, a = new Rt(s, n);
+ return h != null && h.length && a.addSimilarIntArr("l", h), o != null && o.length && a.addSimilarIntArr("p", o), a.complete(), a.getResultBuffers();
+ }(r, t);
+ case tt.SegmentData:
+ return function(e, n) {
+ const s = new Rt(e.c, n);
+ return s.addInteger("i", e.i), s.addInteger("s", e.s), s.addInteger("r", e.r), s.complete(), s.getResultBuffers();
+ }(r, t);
+ }
+}
+const Us = Object.freeze(Object.defineProperty({ __proto__: null, BinaryCommandChunksJoiner: Mn, BinaryCommandJoiningError: Ht, PeerCommandType: tt, deserializeCommand: Fn, isCommandChunk: Nn, serializePeerCommand: Un }, Symbol.toStringTag, { value: "Module" }));
+class Hs {
+ constructor(t, e, n, s) {
+ y(this, "commandChunks");
+ y(this, "uploadingContext");
+ y(this, "onChunkDownloaded");
+ y(this, "onChunkUploaded");
+ y(this, "onDataReceived", (t) => {
+ Nn(t) ? this.receivingCommandBytes(t) : (this.eventHandlers.onSegmentChunkReceived(t), this.onChunkDownloaded(t.byteLength, "p2p", this.connection.idUtf8));
+ });
+ this.connection = t, this.peerConfig = e, this.eventHandlers = n, this.onChunkDownloaded = s.getEventDispatcher("onChunkDownloaded"), this.onChunkUploaded = s.getEventDispatcher("onChunkUploaded"), t.on("data", this.onDataReceived);
+ }
+ sendCommand(t) {
+ const e = Un(t, this.peerConfig.webRtcMaxMessageSize);
+ for (const n of e) this.connection.write(n);
+ }
+ stopUploadingSegmentData() {
+ var t;
+ (t = this.uploadingContext) == null || t.stopUploading(), this.uploadingContext = void 0;
+ }
+ getUploadingRequestId() {
+ var t;
+ return (t = this.uploadingContext) == null ? void 0 : t.requestId;
+ }
+ async splitSegmentDataToChunksAndUploadAsync(t, e) {
+ if (this.uploadingContext) throw new Error("Some segment data is already uploading.");
+ const n = function* (u, f) {
+ let b = u.byteLength;
+ for (; b > 0; ) {
+ const x = b >= f ? f : b, C = u.byteLength - b, d = u.slice(C, C + x);
+ b -= x, yield d;
+ }
+ }(t, this.peerConfig.webRtcMaxMessageSize), { promise: s, resolve: o, reject: h } = function() {
+ let u, f;
+ return { promise: new Promise((b, x) => {
+ u = b, f = x;
+ }), resolve: u, reject: f };
+ }();
+ let a = !1;
+ const g = { stopUploading: () => {
+ a = !1;
+ }, requestId: e };
+ this.uploadingContext = g;
+ const S = () => {
+ if (a) for (; ; ) {
+ const u = n.next().value;
+ if (!u) {
+ o();
+ break;
+ }
+ const f = this.connection.write(u);
+ if (this.onChunkUploaded(u.byteLength, this.connection.idUtf8), !f) break;
+ }
+ else h();
+ };
+ try {
+ this.connection.on("drain", S), a = !0, S(), await s;
+ } finally {
+ this.connection.off("drain", S), this.uploadingContext === g && (this.uploadingContext = void 0);
+ }
+ }
+ receivingCommandBytes(t) {
+ this.commandChunks || (this.commandChunks = new Mn((e) => {
+ this.commandChunks = void 0;
+ const n = Fn(e);
+ this.eventHandlers.onCommandReceived(n);
+ }));
+ try {
+ this.commandChunks.addCommandChunk(t);
+ } catch (e) {
+ if (!(e instanceof Ht)) return;
+ this.commandChunks = void 0;
+ }
+ }
+}
+const { PeerCommandType: D } = Us;
+class jt {
+ constructor(t, e, n, s, o) {
+ y(this, "id");
+ y(this, "peerProtocol");
+ y(this, "downloadingContext");
+ y(this, "loadedSegments", /* @__PURE__ */ new Set());
+ y(this, "httpLoadingSegments", /* @__PURE__ */ new Set());
+ y(this, "downloadingErrors", []);
+ y(this, "logger", H("p2pml-core:peer"));
+ y(this, "onPeerClosed");
+ y(this, "onCommandReceived", async (t) => {
+ var e, n, s;
+ switch (t.c) {
+ case D.SegmentsAnnouncement:
+ this.loadedSegments = new Set(t.l), this.httpLoadingSegments = new Set(t.p), this.eventHandlers.onSegmentsAnnouncement();
+ break;
+ case D.SegmentRequest:
+ this.peerProtocol.stopUploadingSegmentData(), this.eventHandlers.onSegmentRequested(this, t.i, t.r, t.b);
+ break;
+ case D.SegmentData:
+ {
+ if (!this.downloadingContext || this.downloadingContext.isSegmentDataCommandReceived) break;
+ const { request: o, controls: h, requestId: a } = this.downloadingContext;
+ if (o.segment.externalId !== t.i || a !== t.r) break;
+ this.downloadingContext.isSegmentDataCommandReceived = !0, h.firstBytesReceived(), o.totalBytes === void 0 ? o.setTotalBytes(t.s) : o.totalBytes - o.loadedBytes !== t.s && (o.clearLoadedBytes(), this.sendCancelSegmentRequestCommand(o.segment, a), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), this.destroy());
+ }
+ break;
+ case D.SegmentDataSendingCompleted: {
+ const { downloadingContext: o } = this;
+ if (!(o != null && o.isSegmentDataCommandReceived)) return;
+ const { request: h, controls: a } = o;
+ if (o.request.segment.externalId !== t.i || o.requestId !== t.r) return h.clearLoadedBytes(), this.cancelSegmentDownloading("peer-protocol-violation"), void this.destroy();
+ if (h.loadedBytes !== h.totalBytes) return h.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy();
+ const g = await ((n = (e = this.peerConfig).validateP2PSegment) == null ? void 0 : n.call(e, h.segment.url, h.segment.byteRange, h.data)) ?? !0;
+ if (this.downloadingContext !== o) return;
+ if (!g) return h.clearLoadedBytes(), this.cancelSegmentDownloading("p2p-segment-validation-failed"), void this.destroy();
+ this.downloadingErrors = [], a.completeOnSuccess(), this.downloadingContext = void 0;
+ break;
+ }
+ case D.SegmentAbsent:
+ ((s = this.downloadingContext) == null ? void 0 : s.request.segment.externalId) === t.i && this.downloadingContext.requestId === t.r && (this.cancelSegmentDownloading("peer-segment-absent"), this.loadedSegments.delete(t.i));
+ break;
+ case D.CancelSegmentRequest:
+ if (this.peerProtocol.getUploadingRequestId() !== t.r) break;
+ this.peerProtocol.stopUploadingSegmentData();
+ break;
+ }
+ });
+ y(this, "onSegmentChunkReceived", (t) => {
+ var s;
+ if (!((s = this.downloadingContext) != null && s.isSegmentDataCommandReceived)) return;
+ const { request: e, controls: n } = this.downloadingContext;
+ if (e.totalBytes !== void 0 && e.loadedBytes + t.byteLength > e.totalBytes) return e.clearLoadedBytes(), this.cancelSegmentDownloading("peer-response-bytes-length-mismatch"), void this.destroy();
+ n.addLoadedChunk(t);
+ });
+ y(this, "onPeerConnectionClosed", () => {
+ this.destroy();
+ });
+ y(this, "onConnectionError", (t) => {
+ this.logger(`peer connection error ${this.id} %O`, t), this.eventTarget.getEventDispatcher("onPeerError")({ peerId: this.id, streamType: this.streamType, error: t });
+ const { code: e } = t;
+ (e === "ERR_DATA_CHANNEL" || e === "ERR_CONNECTION_FAILURE") && this.destroy();
+ });
+ y(this, "destroy", () => {
+ this.cancelSegmentDownloading("peer-closed"), this.connection.destroy(), this.eventHandlers.onPeerClosed(this), this.onPeerClosed({ peerId: this.id, streamType: this.streamType }), this.logger(`peer closed ${this.id}`);
+ });
+ this.connection = t, this.eventHandlers = e, this.peerConfig = n, this.streamType = s, this.eventTarget = o, this.onPeerClosed = o.getEventDispatcher("onPeerClose"), this.id = jt.getPeerIdFromConnection(t), this.peerProtocol = new Hs(t, n, { onSegmentChunkReceived: this.onSegmentChunkReceived, onCommandReceived: this.onCommandReceived }, o), o.getEventDispatcher("onPeerConnect")({ peerId: this.id, streamType: s }), t.on("error", this.onConnectionError), t.on("close", this.onPeerConnectionClosed), t.on("end", this.onPeerConnectionClosed), t.on("finish", this.onPeerConnectionClosed);
+ }
+ get downloadingSegment() {
+ var t;
+ return (t = this.downloadingContext) == null ? void 0 : t.request.segment;
+ }
+ getSegmentStatus(t) {
+ const { externalId: e } = t;
+ return this.loadedSegments.has(e) ? "loaded" : this.httpLoadingSegments.has(e) ? "http-loading" : void 0;
+ }
+ downloadSegment(t) {
+ if (this.downloadingContext) throw new Error("Some segment already is downloading");
+ this.downloadingContext = { request: t, requestId: Math.floor(1e3 * Math.random()), isSegmentDataCommandReceived: !1, controls: t.start({ downloadSource: "p2p", peerId: this.id }, { notReceivingBytesTimeoutMs: this.peerConfig.p2pNotReceivingBytesTimeoutMs, abort: (n) => {
+ if (!this.downloadingContext) return;
+ const { request: s, requestId: o } = this.downloadingContext;
+ this.sendCancelSegmentRequestCommand(s.segment, o), this.downloadingErrors.push(n), this.downloadingContext = void 0, this.downloadingErrors.filter((h) => h.type === "bytes-receiving-timeout").length >= this.peerConfig.p2pErrorRetries && this.destroy();
+ } }) };
+ const e = { c: D.SegmentRequest, r: this.downloadingContext.requestId, i: t.segment.externalId };
+ t.loadedBytes && (e.b = t.loadedBytes), this.peerProtocol.sendCommand(e);
+ }
+ async uploadSegmentData(t, e, n) {
+ const { externalId: s } = t;
+ this.logger(`send segment ${t.externalId} to ${this.id}`);
+ const o = { c: D.SegmentData, i: s, r: e, s: n.byteLength };
+ this.peerProtocol.sendCommand(o);
+ try {
+ await this.peerProtocol.splitSegmentDataToChunksAndUploadAsync(n, e), this.sendSegmentDataSendingCompletedCommand(t, e), this.logger(`segment ${s} has been sent to ${this.id}`);
+ } catch {
+ this.logger(`cancel segment uploading ${s}`);
+ }
+ }
+ cancelSegmentDownloading(t) {
+ if (!this.downloadingContext) return;
+ const { request: e, controls: n } = this.downloadingContext, { segment: s } = e;
+ this.logger(`cancel segment request ${s.externalId} (${t})`);
+ const o = new N(t);
+ n.abortOnError(o), this.downloadingContext = void 0, this.downloadingErrors.push(o);
+ }
+ sendSegmentsAnnouncementCommand(t, e) {
+ const n = { c: D.SegmentsAnnouncement, p: e, l: t };
+ this.peerProtocol.sendCommand(n);
+ }
+ sendSegmentAbsentCommand(t, e) {
+ this.peerProtocol.sendCommand({ c: D.SegmentAbsent, i: t, r: e });
+ }
+ sendCancelSegmentRequestCommand(t, e) {
+ this.peerProtocol.sendCommand({ c: D.CancelSegmentRequest, i: t.externalId, r: e });
+ }
+ sendSegmentDataSendingCompletedCommand(t, e) {
+ this.peerProtocol.sendCommand({ c: D.SegmentDataSendingCompleted, r: e, i: t.externalId });
+ }
+ static getPeerIdFromConnection(t) {
+ return function(e) {
+ const n = new Uint8Array(e.length / 2);
+ for (let s = 0; s < e.length; s += 2) n[s / 2] = parseInt(e.slice(s, s + 2), 16);
+ return new TextDecoder().decode(n);
+ }(t.id);
+ }
+}
+function $s() {
+ const r = /^((?!chrome|android).)*safari/i.test(navigator.userAgent), t = /\b(iPad|iPhone|Macintosh).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
+ return r || t;
+}
+const ct = class ct {
+ constructor(t, e, n, s, o) {
+ y(this, "streamShortId");
+ y(this, "client");
+ y(this, "_peers", /* @__PURE__ */ new Map());
+ y(this, "logger", H("p2pml-core:p2p-tracker-client"));
+ y(this, "onReceivePeerConnection", (t) => {
+ const e = jt.getPeerIdFromConnection(t);
+ let n = this._peers.get(e);
+ n != null && n.peer ? t.destroy() : (n || (n = { potentialConnections: /* @__PURE__ */ new Set() }, t.idUtf8 = e, this._peers.set(e, n)), n.potentialConnections.add(t), t.on("connect", () => {
+ if (!n.peer) {
+ for (const s of n.potentialConnections) s !== t && s.destroy();
+ n.potentialConnections.clear(), n.peer = new jt(t, { onPeerClosed: this.onPeerClosed, onSegmentRequested: this.eventHandlers.onSegmentRequested, onSegmentsAnnouncement: this.eventHandlers.onSegmentsAnnouncement }, this.config, this.stream.type, this.eventTarget), this.logger(`connected with peer: ${n.peer.id} ${this.streamShortId}`), this.eventHandlers.onPeerConnected(n.peer);
+ }
+ }));
+ });
+ y(this, "onTrackerClientWarning", (t) => {
+ this.logger(`tracker warning (${this.streamShortId}: ${t})`), this.eventTarget.getEventDispatcher("onTrackerWarning")({ streamType: this.stream.type, warning: t });
+ });
+ y(this, "onTrackerClientError", (t) => {
+ this.logger(`tracker error (${this.streamShortId}: ${t})`), this.eventTarget.getEventDispatcher("onTrackerError")({ streamType: this.stream.type, error: t });
+ });
+ y(this, "onPeerClosed", (t) => {
+ this.logger(`peer closed: ${t.id}`), this._peers.delete(t.id);
+ });
+ this.stream = e, this.eventHandlers = n, this.config = s, this.eventTarget = o;
+ const h = function(g) {
+ const S = Es.fromUtf8(g).slice(1);
+ return btoa(S);
+ }(t);
+ this.streamShortId = nt(e);
+ let a = ct.PEER_ID_BY_INFO_HASH.get(h);
+ a || (a = function(g) {
+ const S = [g], u = 20 - g.length;
+ for (let f = 0; f < u; f++) S.push(Ps[Math.floor(62 * Math.random())]);
+ return S.join("");
+ }(s.trackerClientVersionPrefix), ct.PEER_ID_BY_INFO_HASH.set(h, a)), this.client = new fe({ infoHash: pn(h), peerId: pn(a), announce: $s() ? s.announceTrackers.slice(0, 1) : s.announceTrackers, rtcConfig: this.config.rtcConfig }), this.client.on("peer", this.onReceivePeerConnection), this.client.on("warning", this.onTrackerClientWarning), this.client.on("error", this.onTrackerClientError), this.logger(`create new client;
+stream: ${this.streamShortId}; hash: ${h}
+peerId: ${a}`);
+ }
+ start() {
+ this.client.start();
+ }
+ destroy() {
+ this.client.destroy();
+ for (const { peer: t, potentialConnections: e } of this._peers.values()) {
+ t == null || t.destroy();
+ for (const n of e) n.destroy();
+ }
+ this._peers.clear(), this.logger(`destroy client; stream: ${this.streamShortId}`);
+ }
+ *peers() {
+ for (const t of this._peers.values()) t.peer && (yield t.peer);
+ }
+ static clearPeerIdCache() {
+ ct.PEER_ID_BY_INFO_HASH.clear();
+ }
+};
+y(ct, "PEER_ID_BY_INFO_HASH", /* @__PURE__ */ new Map());
+let Wt = ct;
+function V(r, t) {
+ return `v2-${r}-${function(e) {
+ return `${e.type}-${e.index}`;
+ }(t)}`;
+}
+function Sn(r, t) {
+ for (const e of r.values()) {
+ const n = e.segments.get(t);
+ if (n) return n;
+ }
+}
+function re(r, t, e, n, s) {
+ const { highDemandTimeWindow: o, httpDownloadTimeWindow: h, p2pDownloadTimeWindow: a } = function(g, S) {
+ const { highDemandTimeWindow: u, httpDownloadTimeWindow: f, p2pDownloadTimeWindow: b } = g, x = { highDemandTimeWindow: u, httpDownloadTimeWindow: f, p2pDownloadTimeWindow: b };
+ return S <= 5 ? (x.httpDownloadTimeWindow = 0, x.p2pDownloadTimeWindow = 0) : S <= 10 && (x.p2pDownloadTimeWindow = x.httpDownloadTimeWindow), x;
+ }(e, s);
+ return { isHighDemand: ie(r, t, o), isHttpDownloadable: ie(r, t, h), isP2PDownloadable: ie(r, t, a) && n.isSegmentLoadingOrLoadedBySomeone(r) };
+}
+function ie(r, t, e) {
+ const { startTime: n, endTime: s } = r, { position: o, rate: h } = t;
+ return !(o + e * h < n || o > s);
+}
+class js {
+ constructor(t, e, n, s, o, h, a) {
+ y(this, "trackerClient");
+ y(this, "isAnnounceMicrotaskCreated", !1);
+ y(this, "onPeerConnected", (t) => {
+ if (this.config.isP2PUploadDisabled) return;
+ const { httpLoading: e, loaded: n } = this.getSegmentsAnnouncement();
+ t.sendSegmentsAnnouncementCommand(n, e);
+ });
+ y(this, "broadcastAnnouncement", (t = !1) => {
+ if (t) return void this.sendSegmentsAnnouncement([], []);
+ if (this.isAnnounceMicrotaskCreated || this.config.isP2PUploadDisabled) return;
+ const { loaded: e, httpLoading: n } = this.getSegmentsAnnouncement();
+ this.sendSegmentsAnnouncement(e, n);
+ });
+ y(this, "sendSegmentsAnnouncement", (t, e) => {
+ this.isAnnounceMicrotaskCreated = !0, queueMicrotask(() => {
+ for (const n of this.trackerClient.peers()) n.sendSegmentsAnnouncementCommand(t, e);
+ this.isAnnounceMicrotaskCreated = !1;
+ });
+ });
+ y(this, "onSegmentRequested", async (t, e, n, s) => {
+ const o = function(S, u) {
+ for (const f of S.segments.values()) if (f.externalId === u) return f;
+ }(this.stream, e);
+ if (!o) return;
+ if (this.config.isP2PUploadDisabled) return void t.sendSegmentAbsentCommand(e, n);
+ const h = this.config.swarmId ?? this.streamManifestUrl, a = V(h, this.stream), g = await this.segmentStorage.getSegmentData(h, a, o.externalId);
+ g ? await t.uploadSegmentData(o, n, s !== void 0 ? g.slice(s) : g) : t.sendSegmentAbsentCommand(e, n);
+ });
+ this.streamManifestUrl = t, this.stream = e, this.requests = n, this.segmentStorage = s, this.config = o, this.eventTarget = h, this.onSegmentAnnouncement = a;
+ const g = V(this.config.swarmId ?? this.streamManifestUrl, this.stream);
+ this.trackerClient = new Wt(g, this.stream, { onPeerConnected: this.onPeerConnected, onSegmentRequested: this.onSegmentRequested, onSegmentsAnnouncement: this.onSegmentAnnouncement }, this.config, this.eventTarget), this.eventTarget.addEventListener(`onStorageUpdated-${g}`, this.broadcastAnnouncement), this.segmentStorage.setSegmentChangeCallback((S) => {
+ this.eventTarget.dispatchEvent(`onStorageUpdated-${S}`);
+ }), this.trackerClient.start();
+ }
+ downloadSegment(t) {
+ const e = [];
+ for (const h of this.trackerClient.peers()) h.downloadingSegment || h.getSegmentStatus(t) !== "loaded" || e.push(h);
+ if (e.length === 0) return;
+ const n = (s = e)[Math.floor(Math.random() * s.length)];
+ var s;
+ const o = this.requests.getOrCreateRequest(t);
+ n.downloadSegment(o);
+ }
+ isSegmentLoadingOrLoadedBySomeone(t) {
+ for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t)) return !0;
+ return !1;
+ }
+ isSegmentLoadedBySomeone(t) {
+ for (const e of this.trackerClient.peers()) if (e.getSegmentStatus(t) === "loaded") return !0;
+ return !1;
+ }
+ get connectedPeerCount() {
+ let t = 0;
+ for (const e of this.trackerClient.peers()) t++;
+ return t;
+ }
+ getSegmentsAnnouncement() {
+ const t = this.config.swarmId ?? this.streamManifestUrl, e = V(t, this.stream), n = this.segmentStorage.getStoredSegmentIds(t, e), s = [];
+ for (const o of this.requests.httpRequests()) {
+ const h = this.stream.segments.get(o.segment.runtimeId);
+ h && s.push(h.externalId);
+ }
+ return { loaded: n, httpLoading: s };
+ }
+ destroy() {
+ const t = V(this.config.swarmId ?? this.streamManifestUrl, this.stream);
+ this.eventTarget.removeEventListener(`onStorageUpdated-${t}`, this.broadcastAnnouncement), this.trackerClient.destroy();
+ }
+}
+class Ws {
+ constructor(t, e, n, s, o, h, a) {
+ y(this, "loaders", /* @__PURE__ */ new Map());
+ y(this, "_currentLoaderItem");
+ y(this, "logger", H("p2pml-core:p2p-loaders-container"));
+ this.streamManifestUrl = t, this.requests = n, this.segmentStorage = s, this.config = o, this.eventTarget = h, this.onSegmentAnnouncement = a, this._currentLoaderItem = this.findOrCreateLoaderForStream(e), this.logger(`set current p2p loader: ${nt(e)}`);
+ }
+ createLoader(t) {
+ if (this.loaders.has(t.runtimeId)) throw new Error("Loader for this stream already exists");
+ const e = new js(this.streamManifestUrl, t, this.requests, this.segmentStorage, this.config, this.eventTarget, () => {
+ this._currentLoaderItem.loader === e && this.onSegmentAnnouncement();
+ }), n = nt(t);
+ return this.logger(`created new loader: ${n}`), { loader: e, stream: t, loggerInfo: nt(t) };
+ }
+ findOrCreateLoaderForStream(t) {
+ const e = this.loaders.get(t.runtimeId);
+ if (e) return clearTimeout(e.destroyTimeoutId), e.destroyTimeoutId = void 0, e;
+ {
+ const n = this.createLoader(t);
+ return this.loaders.set(t.runtimeId, n), n;
+ }
+ }
+ changeCurrentLoader(t) {
+ const e = this.config.swarmId ?? this.streamManifestUrl, n = V(e, this._currentLoaderItem.stream);
+ this.segmentStorage.getStoredSegmentIds(e, n).length ? this.setLoaderDestroyTimeout(this._currentLoaderItem) : this.destroyAndRemoveLoader(this._currentLoaderItem), this._currentLoaderItem = this.findOrCreateLoaderForStream(t), this.logger(`change current p2p loader: ${nt(t)}`);
+ }
+ setLoaderDestroyTimeout(t) {
+ t.destroyTimeoutId = window.setTimeout(() => this.destroyAndRemoveLoader(t), this.config.p2pInactiveLoaderDestroyTimeoutMs);
+ }
+ destroyAndRemoveLoader(t) {
+ t.loader.destroy(), this.loaders.delete(t.stream.runtimeId), this.logger("destroy p2p loader: ", t.loggerInfo);
+ }
+ get currentLoader() {
+ return this._currentLoaderItem.loader;
+ }
+ destroy() {
+ for (const { loader: t, destroyTimeoutId: e } of this.loaders.values()) t.destroy(), clearTimeout(e);
+ this.loaders.clear();
+ }
+}
+function qt(r) {
+ return { runtimeId: r.runtimeId, externalId: r.externalId, url: r.url, byteRange: r.byteRange, startTime: r.startTime, endTime: r.endTime };
+}
+let Qs = class {
+ constructor(r, t, e, n, s, o) {
+ y(this, "currentAttempt");
+ y(this, "_failedAttempts", new zs());
+ y(this, "finalData");
+ y(this, "bytes", []);
+ y(this, "_loadedBytes", 0);
+ y(this, "_totalBytes");
+ y(this, "_status", "not-started");
+ y(this, "progress");
+ y(this, "notReceivingBytesTimeout");
+ y(this, "_abortRequestCallback");
+ y(this, "_logger");
+ y(this, "_isHandledByProcessQueue", !1);
+ y(this, "onSegmentError");
+ y(this, "onSegmentAbort");
+ y(this, "onSegmentStart");
+ y(this, "onSegmentLoaded");
+ y(this, "abortOnTimeout", () => {
+ var t;
+ if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt) return;
+ this.setStatus("failed");
+ const r = new N("bytes-receiving-timeout");
+ (t = this._abortRequestCallback) == null || t.call(this, r), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${r.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: r }), this.onSegmentError({ segment: qt(this.segment), error: r, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback();
+ });
+ y(this, "abortOnError", (r) => {
+ this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.setStatus("failed"), this.logger(`${this.downloadSource} ${this.segment.externalId} failed ${r.type}`), this._failedAttempts.add({ ...this.currentAttempt, error: r }), this.onSegmentError({ segment: qt(this.segment), error: r, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.notReceivingBytesTimeout.clear(), this.manageBandwidthCalculatorsState("stop"), this.requestProcessQueueCallback());
+ });
+ y(this, "completeOnSuccess", () => {
+ this.throwErrorIfNotLoadingStatus(), this.currentAttempt && (this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear(), this.setStatus("succeed"), this._totalBytes = this._loadedBytes, this.onSegmentLoaded({ segmentUrl: this.segment.url, bytesLength: this.data.byteLength, downloadSource: this.currentAttempt.downloadSource, peerId: this.currentAttempt.downloadSource === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this.logger(`${this.currentAttempt.downloadSource} ${this.segment.externalId} succeed`), this.requestProcessQueueCallback());
+ });
+ y(this, "addLoadedChunk", (r) => {
+ if (this.throwErrorIfNotLoadingStatus(), !this.currentAttempt || !this.progress) return;
+ this.notReceivingBytesTimeout.restart();
+ const { byteLength: t } = r, { all: e, http: n } = this.bandwidthCalculators;
+ e.addBytes(t), this.currentAttempt.downloadSource === "http" && n.addBytes(t), this.bytes.push(r), this.progress.lastLoadedChunkTimestamp = performance.now(), this.progress.loadedBytes += t, this._loadedBytes += t;
+ });
+ y(this, "firstBytesReceived", () => {
+ this.throwErrorIfNotLoadingStatus(), this.notReceivingBytesTimeout.restart();
+ });
+ this.segment = r, this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.playbackConfig = s, this.onSegmentError = o.getEventDispatcher("onSegmentError"), this.onSegmentAbort = o.getEventDispatcher("onSegmentAbort"), this.onSegmentStart = o.getEventDispatcher("onSegmentStart"), this.onSegmentLoaded = o.getEventDispatcher("onSegmentLoaded");
+ const { byteRange: h } = this.segment;
+ if (h) {
+ const { end: g, start: S } = h;
+ this._totalBytes = g - S + 1;
+ }
+ this.notReceivingBytesTimeout = new Gs(this.abortOnTimeout);
+ const { type: a } = this.segment.stream;
+ this._logger = H(`p2pml-core:request-${a}`);
+ }
+ clearLoadedBytes() {
+ this._loadedBytes = 0, this.bytes = [], this._totalBytes = void 0, this.finalData = void 0;
+ }
+ get status() {
+ return this._status;
+ }
+ setStatus(r) {
+ this._status = r, this._isHandledByProcessQueue = !1;
+ }
+ get downloadSource() {
+ var r;
+ return (r = this.currentAttempt) == null ? void 0 : r.downloadSource;
+ }
+ get loadedBytes() {
+ return this._loadedBytes;
+ }
+ get totalBytes() {
+ return this._totalBytes;
+ }
+ get data() {
+ return this.finalData || (this.finalData = Bn(this.bytes)), this.finalData;
+ }
+ get failedAttempts() {
+ return this._failedAttempts;
+ }
+ get isHandledByProcessQueue() {
+ return this._isHandledByProcessQueue;
+ }
+ markHandledByProcessQueue() {
+ this._isHandledByProcessQueue = !0;
+ }
+ setTotalBytes(r) {
+ if (this._totalBytes !== void 0) throw new Error("Request total bytes value is already set");
+ this._totalBytes = r;
+ }
+ start(r, t) {
+ if (this._status === "succeed") throw new Error(`Request ${this.segment.externalId} has been already succeed.`);
+ if (this._status === "loading") throw new Error(`Request ${this.segment.externalId} has been already started.`);
+ this.setStatus("loading"), this.currentAttempt = { ...r }, this.progress = { startFromByte: this._loadedBytes, loadedBytes: 0, startTimestamp: performance.now() }, this.manageBandwidthCalculatorsState("start");
+ const { notReceivingBytesTimeoutMs: e, abort: n } = t;
+ return this._abortRequestCallback = n, e !== void 0 && this.notReceivingBytesTimeout.start(e), this.logger(`${r.downloadSource} ${this.segment.externalId} started`), this.onSegmentStart({ segment: qt(this.segment), downloadSource: r.downloadSource, peerId: r.downloadSource === "p2p" ? r.peerId : void 0 }), { firstBytesReceived: this.firstBytesReceived, addLoadedChunk: this.addLoadedChunk, completeOnSuccess: this.completeOnSuccess, abortOnError: this.abortOnError };
+ }
+ abortFromProcessQueue() {
+ var r, t, e, n;
+ this.throwErrorIfNotLoadingStatus(), this.setStatus("aborted"), this.logger(`${(r = this.currentAttempt) == null ? void 0 : r.downloadSource} ${this.segment.externalId} aborted`), (t = this._abortRequestCallback) == null || t.call(this, new N("abort")), this.onSegmentAbort({ segment: qt(this.segment), downloadSource: (e = this.currentAttempt) == null ? void 0 : e.downloadSource, peerId: ((n = this.currentAttempt) == null ? void 0 : n.downloadSource) === "p2p" ? this.currentAttempt.peerId : void 0, streamType: this.segment.stream.type }), this._abortRequestCallback = void 0, this.manageBandwidthCalculatorsState("stop"), this.notReceivingBytesTimeout.clear();
+ }
+ throwErrorIfNotLoadingStatus() {
+ if (this._status !== "loading") throw new Error(`Request has been already ${this.status}.`);
+ }
+ logger(r) {
+ var t;
+ this._logger.color = ((t = this.currentAttempt) == null ? void 0 : t.downloadSource) === "http" ? "green" : "red", this._logger(r), this._logger.color = "";
+ }
+ manageBandwidthCalculatorsState(r) {
+ var s;
+ const { all: t, http: e } = this.bandwidthCalculators, n = r === "start" ? "startLoading" : "stopLoading";
+ ((s = this.currentAttempt) == null ? void 0 : s.downloadSource) === "http" && e[n](), t[n]();
+ }
+};
+class zs {
+ constructor() {
+ y(this, "attempts", []);
+ }
+ add(t) {
+ this.attempts.push(t);
+ }
+ get httpAttemptsCount() {
+ return this.attempts.reduce((t, e) => e.downloadSource === "http" ? t + 1 : t, 0);
+ }
+ get lastAttempt() {
+ return this.attempts[this.attempts.length - 1];
+ }
+ clear() {
+ this.attempts = [];
+ }
+}
+class Gs {
+ constructor(t) {
+ y(this, "timeoutId");
+ y(this, "ms");
+ this.action = t;
+ }
+ start(t) {
+ if (this.timeoutId) throw new Error("Timeout is already started.");
+ this.ms = t, this.timeoutId = window.setTimeout(this.action, this.ms);
+ }
+ restart(t) {
+ this.timeoutId && clearTimeout(this.timeoutId), t && (this.ms = t), this.ms && (this.timeoutId = window.setTimeout(this.action, this.ms));
+ }
+ clear() {
+ clearTimeout(this.timeoutId), this.timeoutId = void 0;
+ }
+}
+class Ys {
+ constructor(t, e, n, s, o) {
+ y(this, "requests", /* @__PURE__ */ new Map());
+ this.requestProcessQueueCallback = t, this.bandwidthCalculators = e, this.playback = n, this.config = s, this.eventTarget = o;
+ }
+ get executingHttpCount() {
+ let t = 0;
+ for (const e of this.httpRequests()) e.status === "loading" && t++;
+ return t;
+ }
+ get executingP2PCount() {
+ let t = 0;
+ for (const e of this.p2pRequests()) e.status === "loading" && t++;
+ return t;
+ }
+ get(t) {
+ return this.requests.get(t);
+ }
+ getOrCreateRequest(t) {
+ let e = this.requests.get(t);
+ return e || (e = new Qs(t, this.requestProcessQueueCallback, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), this.requests.set(t, e)), e;
+ }
+ remove(t) {
+ this.requests.delete(t.segment);
+ }
+ items() {
+ return this.requests.values();
+ }
+ *httpRequests() {
+ for (const t of this.requests.values()) t.downloadSource === "http" && (yield t);
+ }
+ *p2pRequests() {
+ for (const t of this.requests.values()) t.downloadSource === "p2p" && (yield t);
+ }
+ destroy() {
+ for (const t of this.requests.values()) t.status === "loading" && t.abortFromProcessQueue();
+ this.requests.clear();
+ }
+}
+class Js {
+ constructor(t, e) {
+ y(this, "_status", "pending");
+ y(this, "_shouldBeStartedImmediately", !1);
+ this.segment = t, this.engineCallbacks = e;
+ }
+ get status() {
+ return this._status;
+ }
+ get shouldBeStartedImmediately() {
+ return this._shouldBeStartedImmediately;
+ }
+ resolve(t, e) {
+ this._status === "pending" && (this._status = "succeed", this.engineCallbacks.onSuccess({ data: t, bandwidth: e }));
+ }
+ reject() {
+ this._status === "pending" && (this._status = "failed", this.engineCallbacks.onError(new De("failed")));
+ }
+ abort() {
+ this._status === "pending" && (this._status = "aborted", this.engineCallbacks.onError(new De("aborted")));
+ }
+ markAsShouldBeStartedImmediately() {
+ this._shouldBeStartedImmediately = !0;
+ }
+}
+function* wn(r, t, e, n, s) {
+ const { runtimeId: o, stream: h } = r, a = h.segments.get(o);
+ if (!a) return;
+ const g = h.segments.values();
+ let S;
+ do {
+ const f = g.next();
+ if (f.done) return;
+ S = f.value;
+ } while (S !== a);
+ const u = re(S, t, e, n, s);
+ if (oe(u)) {
+ const f = g.next();
+ if (f.done) return;
+ const b = f.value, x = re(b, t, e, n, s);
+ if (oe(x)) return;
+ u.isHighDemand = !0, yield { segment: S, statuses: u }, yield { segment: b, statuses: x };
+ } else yield { segment: S, statuses: u };
+ for (const f of g) {
+ const b = re(f, t, e, n, s);
+ if (oe(b)) break;
+ yield { segment: f, statuses: b };
+ }
+}
+function oe(r) {
+ const { isHighDemand: t = !1, isHttpDownloadable: e = !1, isP2PDownloadable: n = !1 } = r;
+ return !t && !e && !n;
+}
+class Vs {
+ constructor(t, e, n, s, o, h, a) {
+ y(this, "requests");
+ y(this, "engineRequest");
+ y(this, "p2pLoaders");
+ y(this, "playback");
+ y(this, "segmentAvgDuration");
+ y(this, "logger");
+ y(this, "storageCleanUpIntervalId");
+ y(this, "levelChangedTimestamp");
+ y(this, "lastQueueProcessingTimeStamp");
+ y(this, "randomHttpDownloadInterval");
+ y(this, "isProcessQueueMicrotaskCreated", !1);
+ y(this, "requestProcessQueueMicrotask", (t = !0) => {
+ const e = performance.now();
+ !t && this.lastQueueProcessingTimeStamp !== void 0 && e - this.lastQueueProcessingTimeStamp <= 1e3 || this.isProcessQueueMicrotaskCreated || (this.isProcessQueueMicrotaskCreated = !0, queueMicrotask(() => {
+ try {
+ this.processQueue(), this.lastQueueProcessingTimeStamp = e;
+ } finally {
+ this.isProcessQueueMicrotaskCreated = !1;
+ }
+ }));
+ });
+ this.streamManifestUrl = t, this.lastRequestedSegment = e, this.streamDetails = n, this.config = s, this.bandwidthCalculators = o, this.segmentStorage = h, this.eventTarget = a;
+ const g = this.lastRequestedSegment.stream;
+ this.playback = { position: this.lastRequestedSegment.startTime, rate: 1 }, this.segmentAvgDuration = function(S) {
+ const { segments: u } = S;
+ let f = 0;
+ const { size: b } = u;
+ for (const x of u.values()) f += x.endTime - x.startTime;
+ return f / b;
+ }(g), this.requests = new Ys(this.requestProcessQueueMicrotask, this.bandwidthCalculators, this.playback, this.config, this.eventTarget), this.p2pLoaders = new Ws(this.streamManifestUrl, this.lastRequestedSegment.stream, this.requests, this.segmentStorage, this.config, this.eventTarget, this.requestProcessQueueMicrotask), this.logger = H(`p2pml-core:hybrid-loader-${g.type}`), this.logger.color = "coral", this.setIntervalLoading();
+ }
+ setIntervalLoading() {
+ const t = this.p2pLoaders.currentLoader.connectedPeerCount, e = 1e3 * Math.random() * t + 1e3;
+ this.randomHttpDownloadInterval = window.setTimeout(() => {
+ this.loadRandomThroughHttp(), this.setIntervalLoading();
+ }, e);
+ }
+ async loadSegment(t, e) {
+ var a;
+ this.logger(`requests: ${mn(t)}`);
+ const { stream: n } = t;
+ n !== this.lastRequestedSegment.stream && (this.logger(`stream changed to ${nt(n)}`), this.p2pLoaders.changeCurrentLoader(n)), this.lastRequestedSegment = t;
+ const s = this.config.swarmId ?? this.streamManifestUrl, o = V(s, n);
+ this.segmentStorage.onSegmentRequested(s, o, t.externalId, t.startTime, t.endTime, n.type, this.streamDetails.isLive);
+ const h = new Js(t, e);
+ try {
+ if (this.segmentStorage.hasSegment(s, o, t.externalId)) {
+ const g = await this.segmentStorage.getSegmentData(s, o, t.externalId);
+ if (g) {
+ const { queueDownloadRatio: S } = this.generateQueue();
+ return void h.resolve(g, this.getBandwidth(S));
+ }
+ }
+ (a = this.engineRequest) == null || a.abort(), this.engineRequest = h;
+ } catch {
+ h.reject();
+ } finally {
+ this.requestProcessQueueMicrotask();
+ }
+ }
+ processRequests(t, e) {
+ var h;
+ const { stream: n } = this.lastRequestedSegment, { httpErrorRetries: s } = this.config, o = performance.now();
+ for (const a of this.requests.items()) {
+ const { downloadSource: g, status: S, segment: u, isHandledByProcessQueue: f } = a, b = ((h = this.engineRequest) == null ? void 0 : h.segment) === u ? this.engineRequest : void 0;
+ switch (S) {
+ case "loading":
+ t.has(u.runtimeId) || b || (a.abortFromProcessQueue(), this.requests.remove(a));
+ break;
+ case "succeed": {
+ if (!g) break;
+ g === "http" && this.p2pLoaders.currentLoader.broadcastAnnouncement(), b && (b.resolve(a.data, this.getBandwidth(e)), this.engineRequest = void 0), this.requests.remove(a);
+ const C = this.config.swarmId ?? this.streamManifestUrl, d = V(C, n);
+ this.segmentStorage.storeSegment(C, d, u.externalId, a.data, u.startTime, u.endTime, u.stream.type, this.streamDetails.isLive);
+ break;
+ }
+ case "failed":
+ g !== "http" || f || this.p2pLoaders.currentLoader.broadcastAnnouncement(), b || n.segments.has(a.segment.runtimeId) || this.requests.remove(a), a.failedAttempts.httpAttemptsCount >= s && b && (this.engineRequest = void 0, b.reject());
+ break;
+ case "not-started":
+ case "aborted":
+ this.requests.remove(a);
+ }
+ a.markHandledByProcessQueue();
+ const { lastAttempt: x } = a.failedAttempts;
+ x && o - x.error.timestamp > 6e4 && a.failedAttempts.clear();
+ }
+ }
+ processQueue() {
+ var a;
+ const { queue: t, queueSegmentIds: e, queueDownloadRatio: n } = this.generateQueue();
+ this.processRequests(e, n);
+ const { simultaneousHttpDownloads: s, simultaneousP2PDownloads: o, httpErrorRetries: h } = this.config;
+ if ((a = this.engineRequest) != null && a.shouldBeStartedImmediately && this.engineRequest.status === "pending" && this.requests.executingHttpCount < s) {
+ const { segment: g } = this.engineRequest, S = this.requests.get(g);
+ (!S || S.status === "not-started" || S.status === "failed" && S.failedAttempts.httpAttemptsCount < this.config.httpErrorRetries) && this.loadThroughHttp(g);
+ }
+ for (const g of t) {
+ const { statuses: S, segment: u } = g, f = this.requests.get(u);
+ if (S.isHighDemand) {
+ if ((f == null ? void 0 : f.downloadSource) === "http" && f.status === "loading" || (f == null ? void 0 : f.downloadSource) === "http" && f.status === "failed" && f.failedAttempts.httpAttemptsCount >= h) continue;
+ const b = (f == null ? void 0 : f.status) === "loading" && f.downloadSource === "p2p";
+ if (this.requests.executingHttpCount < s) {
+ b && f.abortFromProcessQueue(), this.loadThroughHttp(u);
+ continue;
+ }
+ if (this.abortLastHttpLoadingInQueueAfterItem(t, u) && this.requests.executingHttpCount < s) {
+ b && f.abortFromProcessQueue(), this.loadThroughHttp(u);
+ continue;
+ }
+ if (b) continue;
+ if (this.requests.executingP2PCount < o) {
+ this.loadThroughP2P(u);
+ continue;
+ }
+ if (this.abortLastP2PLoadingInQueueAfterItem(t, u) && this.requests.executingP2PCount < o) {
+ this.loadThroughP2P(u);
+ continue;
+ }
+ } else if (S.isP2PDownloadable) {
+ if ((f == null ? void 0 : f.status) === "loading") continue;
+ (this.requests.executingP2PCount < o || this.p2pLoaders.currentLoader.isSegmentLoadedBySomeone(u) && this.abortLastP2PLoadingInQueueAfterItem(t, u) && this.requests.executingP2PCount < o) && this.loadThroughP2P(u);
+ }
+ }
+ }
+ abortSegmentRequest(t) {
+ var e;
+ ((e = this.engineRequest) == null ? void 0 : e.segment.runtimeId) === t && (this.engineRequest.abort(), this.logger("abort: ", mn(this.engineRequest.segment)), this.engineRequest = void 0, this.requestProcessQueueMicrotask());
+ }
+ loadThroughHttp(t) {
+ const e = this.requests.getOrCreateRequest(t);
+ new hs(e, this.config, this.eventTarget), this.p2pLoaders.currentLoader.broadcastAnnouncement();
+ }
+ loadThroughP2P(t) {
+ this.p2pLoaders.currentLoader.downloadSegment(t);
+ }
+ loadRandomThroughHttp() {
+ const t = this.getAvailableStorageCapacityPercent();
+ if (t <= 10) return;
+ const { simultaneousHttpDownloads: e, httpErrorRetries: n } = this.config, s = this.p2pLoaders.currentLoader;
+ if (this.requests.executingHttpCount >= e || !s.connectedPeerCount) return;
+ const o = [];
+ for (const { segment: u, statuses: f } of wn(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader, t)) {
+ const b = this.config.swarmId ?? this.streamManifestUrl, x = V(b, u.stream);
+ if (!f.isHttpDownloadable || f.isP2PDownloadable || this.segmentStorage.hasSegment(b, x, u.externalId)) continue;
+ const C = this.requests.get(u);
+ C && (C.status === "loading" || C.status === "succeed" || C.failedAttempts.httpAttemptsCount >= n) || o.push(u);
+ }
+ if (!o.length || e - this.requests.executingHttpCount === 0) return;
+ const h = s.connectedPeerCount + 1, a = Math.min(o.length, e * h), g = function(u) {
+ for (let f = u.length - 1; f > 0; f--) {
+ const b = Math.floor(Math.random() * (f + 1));
+ [u[f], u[b]] = [u[b], u[f]];
+ }
+ return u;
+ }(Array.from({ length: a }, (u, f) => f));
+ let S = a / h;
+ for (const u of g) {
+ if (this.requests.executingHttpCount >= e) break;
+ if (S >= 1 || Math.random() <= S) {
+ const f = o[u];
+ this.loadThroughHttp(f);
+ }
+ if (S--, S <= 0) break;
+ }
+ }
+ abortLastHttpLoadingInQueueAfterItem(t, e) {
+ for (const { segment: n } of fn(t)) {
+ if (n === e) break;
+ const s = this.requests.get(n);
+ if ((s == null ? void 0 : s.downloadSource) === "http" && s.status === "loading") return s.abortFromProcessQueue(), !0;
+ }
+ return !1;
+ }
+ abortLastP2PLoadingInQueueAfterItem(t, e) {
+ for (const { segment: n } of fn(t)) {
+ if (n === e) break;
+ const s = this.requests.get(n);
+ if ((s == null ? void 0 : s.downloadSource) === "p2p" && s.status === "loading") return s.abortFromProcessQueue(), !0;
+ }
+ return !1;
+ }
+ getAvailableStorageCapacityPercent() {
+ const { totalCapacity: t, usedCapacity: e } = this.segmentStorage.getUsage();
+ return 100 - e / t * 100;
+ }
+ generateQueue() {
+ var h;
+ const t = [], e = /* @__PURE__ */ new Set();
+ let n = 0, s = 0;
+ const o = this.getAvailableStorageCapacityPercent();
+ for (const a of wn(this.lastRequestedSegment, this.playback, this.config, this.p2pLoaders.currentLoader, o)) {
+ n++;
+ const { segment: g } = a, S = this.config.swarmId ?? this.streamManifestUrl, u = V(S, g.stream);
+ this.segmentStorage.hasSegment(S, u, g.externalId) || ((h = this.requests.get(g)) == null ? void 0 : h.status) === "succeed" ? s++ : (t.push(a), e.add(g.runtimeId));
+ }
+ return { queue: t, queueSegmentIds: e, maxPossibleLength: n, alreadyLoadedCount: s, queueDownloadRatio: n !== 0 ? s / n : 0 };
+ }
+ getBandwidth(t) {
+ const { http: e, all: n } = this.bandwidthCalculators, { activeLevelBitrate: s } = this.streamDetails;
+ if (this.streamDetails.activeLevelBitrate === 0) return n.getBandwidthLoadingOnly(3);
+ const o = Math.max(n.getBandwidth(30, this.levelChangedTimestamp), n.getBandwidth(60, this.levelChangedTimestamp), n.getBandwidth(90, this.levelChangedTimestamp));
+ if (t >= 0.8 || o >= 0.9 * s) return Math.max(n.getBandwidthLoadingOnly(1), n.getBandwidthLoadingOnly(3), n.getBandwidthLoadingOnly(5));
+ const h = Math.max(e.getBandwidthLoadingOnly(1), e.getBandwidthLoadingOnly(3), e.getBandwidthLoadingOnly(5));
+ return Math.max(o, h);
+ }
+ notifyLevelChanged() {
+ this.levelChangedTimestamp = performance.now();
+ }
+ sendBroadcastAnnouncement(t = !1) {
+ this.p2pLoaders.currentLoader.broadcastAnnouncement(t);
+ }
+ updatePlayback(t, e) {
+ var h;
+ const n = this.playback.rate !== e, s = this.playback.position !== t;
+ if (!n && !s) return;
+ const o = Math.abs(t - this.playback.position) / this.segmentAvgDuration > 0.5;
+ s && (this.playback.position = t), n && e !== 0 && (this.playback.rate = e), o && (this.logger("position significantly changed"), (h = this.engineRequest) == null || h.markAsShouldBeStartedImmediately()), this.segmentStorage.onPlaybackUpdated(t, e), this.requestProcessQueueMicrotask(o);
+ }
+ updateStream(t) {
+ t === this.lastRequestedSegment.stream && (this.logger(`update stream: ${nt(t)}`), this.requestProcessQueueMicrotask());
+ }
+ destroy() {
+ var t;
+ clearInterval(this.storageCleanUpIntervalId), clearInterval(this.randomHttpDownloadInterval), this.storageCleanUpIntervalId = void 0, (t = this.engineRequest) == null || t.abort(), this.requests.destroy(), this.p2pLoaders.destroy();
+ }
+}
+class bn {
+ constructor(t = 2e4) {
+ y(this, "loadingsCount", 0);
+ y(this, "bytes", []);
+ y(this, "loadingOnlyTimestamps", []);
+ y(this, "timestamps", []);
+ y(this, "noLoadingsTime", 0);
+ y(this, "loadingsStoppedAt", 0);
+ this.clearThresholdMs = t;
+ }
+ addBytes(t, e = performance.now()) {
+ this.bytes.push(t), this.loadingOnlyTimestamps.push(e - this.noLoadingsTime), this.timestamps.push(e);
+ }
+ startLoading(t = performance.now()) {
+ this.clearStale(), this.loadingsCount === 0 && this.loadingsStoppedAt !== 0 && (this.noLoadingsTime += t - this.loadingsStoppedAt), this.loadingsCount++;
+ }
+ stopLoading(t = performance.now()) {
+ this.loadingsCount > 0 && (this.loadingsCount--, this.loadingsCount === 0 && (this.loadingsStoppedAt = t));
+ }
+ getBandwidthLoadingOnly(t, e = Number.NEGATIVE_INFINITY) {
+ if (!this.loadingOnlyTimestamps.length) return 0;
+ const n = 1e3 * t, s = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1];
+ let o = s;
+ const h = s - n;
+ let a = 0;
+ for (let g = this.bytes.length - 1; g >= 0; g--) {
+ const S = this.loadingOnlyTimestamps[g];
+ if (S < h || this.timestamps[g] < e) break;
+ o = S, a += this.bytes[g];
+ }
+ return 8e3 * a / (s - o);
+ }
+ getBandwidth(t, e = Number.NEGATIVE_INFINITY, n = performance.now()) {
+ if (!this.timestamps.length) return 0;
+ const s = n - 1e3 * t;
+ let o = n, h = 0;
+ for (let a = this.bytes.length - 1; a >= 0; a--) {
+ const g = this.timestamps[a];
+ if (g < s || g < e) break;
+ o = g, h += this.bytes[a];
+ }
+ return 8e3 * h / (n - o);
+ }
+ clearStale() {
+ if (!this.loadingOnlyTimestamps.length) return;
+ const t = this.loadingOnlyTimestamps[this.loadingOnlyTimestamps.length - 1] - this.clearThresholdMs;
+ let e = 0;
+ for (const n of this.loadingOnlyTimestamps) {
+ if (n > t) break;
+ e++;
+ }
+ this.bytes.splice(0, e), this.loadingOnlyTimestamps.splice(0, e), this.timestamps.splice(0, e);
+ }
+}
+const Bt = (r, t) => `${r}|${t}`, Ot = 1048576;
+class Ks {
+ constructor() {
+ y(this, "userAgent", navigator.userAgent);
+ y(this, "segmentMemoryStorageLimit", 4096);
+ y(this, "currentStorageUsage", 0);
+ y(this, "cache", /* @__PURE__ */ new Map());
+ y(this, "logger");
+ y(this, "coreConfig");
+ y(this, "mainStreamConfig");
+ y(this, "secondaryStreamConfig");
+ y(this, "currentPlayback");
+ y(this, "lastRequestedSegment");
+ y(this, "segmentChangeCallback");
+ this.logger = H("p2pml-core:segment-memory-storage"), this.logger.color = "RebeccaPurple";
+ }
+ async initialize(t, e, n) {
+ this.coreConfig = t, this.mainStreamConfig = e, this.secondaryStreamConfig = n, this.setMemoryStorageLimit(), this.logger("initialized");
+ }
+ onPlaybackUpdated(t, e) {
+ this.currentPlayback = { position: t, rate: e };
+ }
+ onSegmentRequested(t, e, n, s, o, h, a) {
+ this.lastRequestedSegment = { streamId: e, segmentId: n, startTime: s, endTime: o, swarmId: t, streamType: h, isLiveStream: a };
+ }
+ async storeSegment(t, e, n, s, o, h, a, g) {
+ this.clear(g, s.byteLength);
+ const S = Bt(e, n);
+ if (this.cache.set(S, { data: s, segmentId: n, streamId: e, startTime: o, endTime: h, streamType: a }), this.increaseStorageUsage(s.byteLength), this.logger(`add segment: ${n} to ${e}`), !this.segmentChangeCallback) throw new Error("dispatchStorageUpdatedEvent is not set");
+ this.segmentChangeCallback(e);
+ }
+ async getSegmentData(t, e, n) {
+ const s = Bt(e, n), o = this.cache.get(s);
+ if (o !== void 0) return o.data;
+ }
+ getUsage() {
+ if (!this.lastRequestedSegment || !this.currentPlayback) return { totalCapacity: this.segmentMemoryStorageLimit, usedCapacity: this.currentStorageUsage };
+ const t = this.currentPlayback.position;
+ let e = 0;
+ for (const { endTime: n, data: s } of this.cache.values()) t > n || (e += s.byteLength);
+ return { totalCapacity: this.segmentMemoryStorageLimit, usedCapacity: e / Ot };
+ }
+ hasSegment(t, e, n) {
+ const s = Bt(e, n);
+ return this.cache.get(s) !== void 0;
+ }
+ getStoredSegmentIds(t, e) {
+ const n = [];
+ for (const { segmentId: s, streamId: o } of this.cache.values()) o === e && n.push(s);
+ return n;
+ }
+ clear(t, e) {
+ if (!(this.currentPlayback && this.mainStreamConfig && this.secondaryStreamConfig && this.coreConfig) || !this.isMemoryLimitReached(e) && !t) return;
+ const n = /* @__PURE__ */ new Set(), s = Array.from(this.cache.values()).sort((o, h) => o.startTime - h.startTime);
+ for (const o of s) {
+ const { streamId: h, segmentId: a, data: g } = o, S = Bt(h, a);
+ if (this.shouldRemoveSegment(o, t, this.currentPlayback.position) && (this.cache.delete(S), n.add(h), this.decreaseStorageUsage(g.byteLength), this.logger(`Removed segment ${a} from stream ${h}`), !this.isMemoryLimitReached(e) && !t)) break;
+ }
+ this.sendUpdatesToAffectedStreams(n);
+ }
+ isMemoryLimitReached(t) {
+ return this.currentStorageUsage + t / Ot > this.segmentMemoryStorageLimit;
+ }
+ setSegmentChangeCallback(t) {
+ this.segmentChangeCallback = t;
+ }
+ sendUpdatesToAffectedStreams(t) {
+ t.size !== 0 && t.forEach((e) => {
+ if (!this.segmentChangeCallback) throw new Error("dispatchStorageUpdatedEvent is not set");
+ this.segmentChangeCallback(e);
+ });
+ }
+ shouldRemoveSegment(t, e, n) {
+ const { endTime: s, streamType: o } = t, h = this.getStreamTimeWindow(o, "highDemandTimeWindow");
+ return !(n <= s) && (!e || n > h + s);
+ }
+ increaseStorageUsage(t) {
+ this.currentStorageUsage += t / Ot;
+ }
+ decreaseStorageUsage(t) {
+ this.currentStorageUsage -= t / Ot;
+ }
+ setMemoryStorageLimit() {
+ var e;
+ var t;
+ (e = this.coreConfig) != null && e.segmentMemoryStorageLimit ? this.segmentMemoryStorageLimit = this.coreConfig.segmentMemoryStorageLimit : (t = this.userAgent, /Android/i.test(t) && !/Chrome|Firefox/i.test(t) || ((n) => /iPad|iPhone/i.test(n))(this.userAgent) ? this.segmentMemoryStorageLimit = 1024 : ((n) => /Android/i.test(n))(this.userAgent) && (this.segmentMemoryStorageLimit = 2048));
+ }
+ getStreamTimeWindow(t, e) {
+ const n = t === "main" ? this.mainStreamConfig : this.secondaryStreamConfig;
+ return (n == null ? void 0 : n[e]) ?? 0;
+ }
+ destroy() {
+ this.cache.clear();
+ }
+}
+class Zs {
+ constructor() {
+ y(this, "events", /* @__PURE__ */ new Map());
+ }
+ dispatchEvent(t, ...e) {
+ const n = this.events.get(t);
+ if (n) for (const s of n) s(...e);
+ }
+ getEventDispatcher(t) {
+ let e = this.events.get(t);
+ e || (e = [], this.events.set(t, e));
+ const n = e;
+ return (...s) => {
+ for (const o of n) o(...s);
+ };
+ }
+ addEventListener(t, e) {
+ const n = this.events.get(t);
+ n ? n.push(e) : this.events.set(t, [e]);
+ }
+ removeEventListener(t, e) {
+ const n = this.events.get(t);
+ if (n) {
+ const s = n.indexOf(e);
+ s !== -1 && n.splice(s, 1);
+ }
+ }
+}
+const rt = class rt {
+ constructor(t) {
+ y(this, "eventTarget", new Zs());
+ y(this, "manifestResponseUrl");
+ y(this, "streams", /* @__PURE__ */ new Map());
+ y(this, "mainStreamConfig");
+ y(this, "secondaryStreamConfig");
+ y(this, "commonCoreConfig");
+ y(this, "bandwidthCalculators", { all: new bn(), http: new bn() });
+ y(this, "segmentStorage");
+ y(this, "mainStreamLoader");
+ y(this, "secondaryStreamLoader");
+ y(this, "streamDetails", { isLive: !1, activeLevelBitrate: 0 });
+ const e = function n(s) {
+ if (On(s)) {
+ const o = {};
+ return Object.keys(s).forEach((h) => {
+ if (s[h] !== void 0) {
+ const a = n(s[h]);
+ a !== void 0 && (o[h] = a);
+ }
+ }), o;
+ }
+ return s;
+ }(t ?? {});
+ this.commonCoreConfig = se({ defaultConfig: rt.DEFAULT_COMMON_CORE_CONFIG, baseConfig: e }), this.mainStreamConfig = se({ defaultConfig: rt.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e.mainStream }), this.secondaryStreamConfig = se({ defaultConfig: rt.DEFAULT_STREAM_CONFIG, baseConfig: e, specificStreamConfig: e.secondaryStream });
+ }
+ getConfig() {
+ return { ...et(this.commonCoreConfig), mainStream: et(this.mainStreamConfig), secondaryStream: et(this.secondaryStreamConfig) };
+ }
+ applyDynamicConfig(t) {
+ const { mainStream: e, secondaryStream: n } = t, s = et(this.mainStreamConfig), o = et(this.secondaryStreamConfig);
+ this.overrideAllConfigs(t, e, n), this.processSpecificDynamicConfigParams(s, t, "main"), this.processSpecificDynamicConfigParams(o, t, "secondary");
+ }
+ processSpecificDynamicConfigParams(t, e, n) {
+ const s = this.getUpdatedStreamProperty("isP2PDisabled", e, n);
+ s && t.isP2PDisabled !== s && this.destroyStreamLoader(n);
+ const o = this.getUpdatedStreamProperty("isP2PUploadDisabled", e, n);
+ if (o !== void 0 && t.isP2PUploadDisabled !== o) {
+ const h = n === "main" ? this.mainStreamLoader : this.secondaryStreamLoader;
+ h == null || h.sendBroadcastAnnouncement(o);
+ }
+ }
+ getUpdatedStreamProperty(t, e, n) {
+ const s = n === "main" ? e.mainStream : e.secondaryStream;
+ return (s == null ? void 0 : s[t]) ?? e[t];
+ }
+ addEventListener(t, e) {
+ this.eventTarget.addEventListener(t, e);
+ }
+ removeEventListener(t, e) {
+ this.eventTarget.removeEventListener(t, e);
+ }
+ setManifestResponseUrl(t) {
+ this.manifestResponseUrl = t.split("?")[0];
+ }
+ hasSegment(t) {
+ return !!Sn(this.streams, t);
+ }
+ getStream(t) {
+ return this.streams.get(t);
+ }
+ addStreamIfNoneExists(t) {
+ this.streams.has(t.runtimeId) || this.streams.set(t.runtimeId, { ...t, segments: /* @__PURE__ */ new Map() });
+ }
+ updateStream(t, e, n) {
+ var o, h;
+ const s = this.streams.get(t);
+ if (s) {
+ if (e) for (const a of e) s.segments.has(a.runtimeId) || s.segments.set(a.runtimeId, { ...a, stream: s });
+ if (n) for (const a of n) s.segments.delete(a);
+ (o = this.mainStreamLoader) == null || o.updateStream(s), (h = this.secondaryStreamLoader) == null || h.updateStream(s);
+ }
+ }
+ async loadSegment(t, e) {
+ if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined");
+ await this.initializeSegmentStorage();
+ const n = this.identifySegment(t);
+ this.getStreamHybridLoader(n).loadSegment(n, e);
+ }
+ abortSegmentLoading(t) {
+ var e, n;
+ (e = this.mainStreamLoader) == null || e.abortSegmentRequest(t), (n = this.secondaryStreamLoader) == null || n.abortSegmentRequest(t);
+ }
+ updatePlayback(t, e) {
+ var n, s;
+ (n = this.mainStreamLoader) == null || n.updatePlayback(t, e), (s = this.secondaryStreamLoader) == null || s.updatePlayback(t, e);
+ }
+ setActiveLevelBitrate(t) {
+ var e, n;
+ t !== this.streamDetails.activeLevelBitrate && (this.streamDetails.activeLevelBitrate = t, (e = this.mainStreamLoader) == null || e.notifyLevelChanged(), (n = this.secondaryStreamLoader) == null || n.notifyLevelChanged());
+ }
+ setIsLive(t) {
+ this.streamDetails.isLive = t;
+ }
+ isSegmentLoadable(t) {
+ try {
+ const e = this.identifySegment(t);
+ return (e.stream.type !== "main" || !this.mainStreamConfig.isP2PDisabled) && (e.stream.type !== "secondary" || !this.secondaryStreamConfig.isP2PDisabled);
+ } catch {
+ return !1;
+ }
+ }
+ destroy() {
+ var t, e, n;
+ this.streams.clear(), (t = this.mainStreamLoader) == null || t.destroy(), (e = this.secondaryStreamLoader) == null || e.destroy(), (n = this.segmentStorage) == null || n.destroy(), this.mainStreamLoader = void 0, this.secondaryStreamLoader = void 0, this.segmentStorage = void 0, this.manifestResponseUrl = void 0, this.streamDetails = { isLive: !1, activeLevelBitrate: 0 }, Wt.clearPeerIdCache();
+ }
+ async initializeSegmentStorage() {
+ if (this.segmentStorage) return;
+ const { isLive: t } = this.streamDetails, e = this.commonCoreConfig.customSegmentStorageFactory;
+ if (e && typeof e != "function") throw new Error("Storage configuration is invalid");
+ const n = e ? e(t) : new Ks();
+ await n.initialize(this.commonCoreConfig, this.mainStreamConfig, this.secondaryStreamConfig), this.segmentStorage = n;
+ }
+ identifySegment(t) {
+ if (!this.manifestResponseUrl) throw new Error("Manifest response url is undefined");
+ const e = Sn(this.streams, t);
+ if (!e) throw new Error(`Not found segment with id: ${t}`);
+ return e;
+ }
+ overrideAllConfigs(t, e, n) {
+ wt(this.commonCoreConfig, t), wt(this.mainStreamConfig, t), wt(this.secondaryStreamConfig, t), e && wt(this.mainStreamConfig, e), n && wt(this.secondaryStreamConfig, n);
+ }
+ destroyStreamLoader(t) {
+ var e, n;
+ t === "main" ? ((e = this.mainStreamLoader) == null || e.destroy(), this.mainStreamLoader = void 0) : ((n = this.secondaryStreamLoader) == null || n.destroy(), this.secondaryStreamLoader = void 0);
+ }
+ getStreamHybridLoader(t) {
+ return t.stream.type === "main" ? (this.mainStreamLoader ?? (this.mainStreamLoader = this.createNewHybridLoader(t)), this.mainStreamLoader) : (this.secondaryStreamLoader ?? (this.secondaryStreamLoader = this.createNewHybridLoader(t)), this.secondaryStreamLoader);
+ }
+ createNewHybridLoader(t) {
+ if (!this.manifestResponseUrl) throw new Error("Manifest response url is not defined");
+ if (!this.segmentStorage) throw new Error("Segment storage is not initialized");
+ const e = t.stream.type === "main" ? this.mainStreamConfig : this.secondaryStreamConfig;
+ return new Vs(this.manifestResponseUrl, t, this.streamDetails, e, this.bandwidthCalculators, this.segmentStorage, this.eventTarget);
+ }
+};
+y(rt, "DEFAULT_COMMON_CORE_CONFIG", { segmentMemoryStorageLimit: void 0, customSegmentStorageFactory: void 0 }), y(rt, "DEFAULT_STREAM_CONFIG", { isP2PUploadDisabled: !1, isP2PDisabled: !1, simultaneousHttpDownloads: 2, simultaneousP2PDownloads: 3, highDemandTimeWindow: 15, httpDownloadTimeWindow: 3e3, p2pDownloadTimeWindow: 6e3, webRtcMaxMessageSize: 65535, p2pNotReceivingBytesTimeoutMs: 2e3, p2pInactiveLoaderDestroyTimeoutMs: 3e4, httpNotReceivingBytesTimeoutMs: 3e3, httpErrorRetries: 3, p2pErrorRetries: 3, trackerClientVersionPrefix: Rs, announceTrackers: ["wss://tracker.novage.com.ua", "wss://tracker.webtorrent.dev", "wss://tracker.openwebtorrent.com"], rtcConfig: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }, { urls: "stun:global.stun.twilio.com:3478" }] }, validateP2PSegment: void 0, validateHTTPSegment: void 0, httpRequestSetup: void 0, swarmId: void 0 });
+let Cn = rt;
+const tr = xn.debug;
+export {
+ Cn as Core,
+ De as CoreRequestError,
+ N as RequestError,
+ tr as debug
+};
+//# sourceMappingURL=p2p-media-loader-core.es.min.js.map
diff --git a/resources/p2p-media-loader-hlsjs/2.1.0/p2p-media-loader-hlsjs.min.jsm b/resources/p2p-media-loader-hlsjs/2.2.0/p2p-media-loader-hlsjs.min.jsm
similarity index 56%
rename from resources/p2p-media-loader-hlsjs/2.1.0/p2p-media-loader-hlsjs.min.jsm
rename to resources/p2p-media-loader-hlsjs/2.2.0/p2p-media-loader-hlsjs.min.jsm
index b7bb713f..a05af5aa 100644
--- a/resources/p2p-media-loader-hlsjs/2.1.0/p2p-media-loader-hlsjs.min.jsm
+++ b/resources/p2p-media-loader-hlsjs/2.2.0/p2p-media-loader-hlsjs.min.jsm
@@ -3,8 +3,8 @@ var R = (n) => {
throw TypeError(n);
};
var q = (n, t, e) => t in n ? j(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
-var r = (n, t, e) => q(n, typeof t != "symbol" ? t + "" : t, e), D = (n, t, e) => t.has(n) || R("Cannot " + e);
-var i = (n, t, e) => (D(n, t, "read from private field"), e ? e.call(n) : t.get(n)), l = (n, t, e) => t.has(n) ? R("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(n) : t.set(n, e), u = (n, t, e, s) => (D(n, t, "write to private field"), s ? s.call(n, e) : t.set(n, e), e), x = (n, t, e) => (D(n, t, "access private method"), e);
+var a = (n, t, e) => q(n, typeof t != "symbol" ? t + "" : t, e), k = (n, t, e) => t.has(n) || R("Cannot " + e);
+var i = (n, t, e) => (k(n, t, "read from private field"), e ? e.call(n) : t.get(n)), l = (n, t, e) => t.has(n) ? R("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(n) : t.set(n, e), u = (n, t, e, s) => (k(n, t, "write to private field"), s ? s.call(n, e) : t.set(n, e), e), x = (n, t, e) => (k(n, t, "access private method"), e);
import { CoreRequestError as T, debug as N, Core as z } from "p2p-media-loader-core";
function F(n, t) {
return t ? `${n}|${t.start}-${t.end}` : n;
@@ -12,154 +12,154 @@ function F(n, t) {
function J(n, t) {
if (n !== void 0 && t !== void 0 && n <= t) return { start: n, end: t };
}
-var H, M, g, y, p, m, b, G, A;
+var H, M, g, m, p, v, L, $, A;
class B {
constructor(t, e) {
- l(this, b);
- r(this, "context");
- r(this, "config");
- r(this, "stats");
+ l(this, L);
+ a(this, "context");
+ a(this, "config");
+ a(this, "stats");
l(this, H);
l(this, M);
l(this, g);
- l(this, y);
- l(this, p);
l(this, m);
- u(this, y, e), u(this, M, () => new t.loader(t)), this.stats = { aborted: !1, chunkCount: 0, loading: { start: 0, first: 0, end: 0 }, buffering: { start: 0, first: 0, end: 0 }, parsing: { start: 0, end: 0 }, total: 1, loaded: 1, bwEstimate: 0, retry: 0 };
+ l(this, p);
+ l(this, v);
+ u(this, m, e), u(this, M, () => new t.loader(t)), this.stats = { aborted: !1, chunkCount: 0, loading: { start: 0, first: 0, end: 0 }, buffering: { start: 0, first: 0, end: 0 }, parsing: { start: 0, end: 0 }, total: 1, loaded: 1, bwEstimate: 0, retry: 0 };
}
load(t, e, s) {
this.context = t, this.config = e, u(this, H, s);
- const { stats: o } = this, { rangeStart: d, rangeEnd: a } = t, E = J(d, a !== void 0 ? a - 1 : void 0);
- u(this, m, F(t.url, E));
- const h = i(this, y).isSegmentLoadable(i(this, m));
- if (!i(this, y).hasSegment(i(this, m)) || !h) return u(this, g, i(this, M).call(this)), i(this, g).stats = this.stats, void i(this, g).load(t, e, s);
- i(this, y).loadSegment(i(this, m), { onSuccess: (f) => {
+ const { stats: r } = this, { rangeStart: d, rangeEnd: o } = t, E = J(d, o !== void 0 ? o - 1 : void 0);
+ u(this, v, F(t.url, E));
+ const h = i(this, m).isSegmentLoadable(i(this, v));
+ if (!i(this, m).hasSegment(i(this, v)) || !h) return u(this, g, i(this, M).call(this)), i(this, g).stats = this.stats, void i(this, g).load(t, e, s);
+ i(this, m).loadSegment(i(this, v), { onSuccess: (f) => {
u(this, p, f);
const c = i(this, p).data.byteLength;
- o.loading = function(L, C, I) {
- const w = 8e3 * C / L, S = I - w;
- return { start: S - 10, first: S, end: I };
- }(i(this, p).bandwidth, c, performance.now()), o.total = c, o.loaded = c, s.onProgress && s.onProgress(this.stats, t, i(this, p).data, void 0), s.onSuccess({ data: i(this, p).data, url: t.url }, this.stats, t, void 0);
+ r.loading = function(b, C, S) {
+ const D = 8e3 * C / b, I = S - D;
+ return { start: I - 10, first: I, end: S };
+ }(i(this, p).bandwidth, c, performance.now()), r.total = c, r.loaded = c, s.onProgress && s.onProgress(this.stats, t, i(this, p).data, void 0), s.onSuccess({ data: i(this, p).data, url: t.url }, this.stats, t, void 0);
}, onError: (f) => {
- f instanceof T && f.type === "aborted" && this.stats.aborted || x(this, b, G).call(this, f);
+ f instanceof T && f.type === "aborted" && this.stats.aborted || x(this, L, $).call(this, f);
} });
}
abort() {
var t, e;
- i(this, g) ? i(this, g).abort() : (x(this, b, A).call(this), (e = (t = i(this, H)) == null ? void 0 : t.onAbort) == null || e.call(t, this.stats, this.context, {}));
+ i(this, g) ? i(this, g).abort() : (x(this, L, A).call(this), (e = (t = i(this, H)) == null ? void 0 : t.onAbort) == null || e.call(t, this.stats, this.context, {}));
}
destroy() {
- i(this, g) ? i(this, g).destroy() : (this.stats.aborted || x(this, b, A).call(this), u(this, H, null), this.config = null);
+ i(this, g) ? i(this, g).destroy() : (this.stats.aborted || x(this, L, A).call(this), u(this, H, null), this.config = null);
}
}
-H = new WeakMap(), M = new WeakMap(), g = new WeakMap(), y = new WeakMap(), p = new WeakMap(), m = new WeakMap(), b = new WeakSet(), G = function(t) {
+H = new WeakMap(), M = new WeakMap(), g = new WeakMap(), m = new WeakMap(), p = new WeakMap(), v = new WeakMap(), L = new WeakSet(), $ = function(t) {
var s;
const e = { code: 0, text: "" };
(t instanceof T && t.type === "failed" || t instanceof Error) && (e.text = t.message), (s = i(this, H)) == null || s.onError(e, this.context, null, this.stats);
}, A = function() {
- !i(this, p) && i(this, m) && (this.stats.aborted = !0, i(this, y).abortSegmentLoading(i(this, m)));
+ !i(this, p) && i(this, v) && (this.stats.aborted = !0, i(this, m).abortSegmentLoading(i(this, v)));
};
-var v;
+var y;
class X {
constructor(t) {
- l(this, v);
- r(this, "context");
- r(this, "stats");
- u(this, v, new t.loader(t)), this.stats = i(this, v).stats, this.context = i(this, v).context;
+ l(this, y);
+ a(this, "context");
+ a(this, "stats");
+ u(this, y, new t.loader(t)), this.stats = i(this, y).stats, this.context = i(this, y).context;
}
load(t, e, s) {
- i(this, v).load(t, e, s);
+ i(this, y).load(t, e, s);
}
abort() {
- i(this, v).abort();
+ i(this, y).abort();
}
destroy() {
- i(this, v).destroy();
+ i(this, y).destroy();
}
}
-v = new WeakMap();
+y = new WeakMap();
class K {
constructor(t) {
- r(this, "core");
+ a(this, "core");
this.core = t;
}
processMainManifest(t) {
const { levels: e, audioTracks: s } = t;
- for (const [o, d] of e.entries()) {
- const { url: a } = d;
- this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(a) ? a[0] : a, type: "main", index: o });
+ for (const [r, d] of e.entries()) {
+ const { url: o } = d;
+ this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(o) ? o[0] : o, type: "main", index: r });
}
- for (const [o, d] of s.entries()) {
- const { url: a } = d;
- this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(a) ? a[0] : a, type: "secondary", index: o });
+ for (const [r, d] of s.entries()) {
+ const { url: o } = d;
+ this.core.addStreamIfNoneExists({ runtimeId: Array.isArray(o) ? o[0] : o, type: "secondary", index: r });
}
}
updatePlaylist(t) {
- const { details: { url: e, fragments: s, live: o } } = t, d = this.core.getStream(e);
+ const { details: { url: e, fragments: s, live: r } } = t, d = this.core.getStream(e);
if (!d) return;
- const a = new Set(d.segments.keys()), E = [];
+ const o = new Set(d.segments.keys()), E = [];
s.forEach((h, f) => {
- const { url: c, byteRange: L, sn: C, start: I, end: w } = h;
+ const { url: c, byteRange: b, sn: C, start: S, end: D } = h;
if (C === "initSegment") return;
- const [S, P] = L, U = J(S, P !== void 0 ? P - 1 : void 0), k = F(c, U);
- a.delete(k), d.segments.has(k) || E.push({ runtimeId: k, url: c, externalId: o ? C : f, byteRange: U, startTime: I, endTime: w });
- }), (E.length || a.size) && this.core.updateStream(e, E, a.values());
+ const [I, w] = b, U = J(I, w !== void 0 ? w - 1 : void 0), P = F(c, U);
+ o.delete(P), d.segments.has(P) || E.push({ runtimeId: P, url: c, externalId: r ? C : f, byteRange: U, startTime: S, endTime: D });
+ }), (E.length || o.size) && this.core.updateStream(e, E, o.values());
}
}
-class $ {
+class G {
constructor(t) {
- r(this, "core");
- r(this, "segmentManager");
- r(this, "hlsInstanceGetter");
- r(this, "currentHlsInstance");
- r(this, "debug", N("p2pml-hlsjs:engine"));
- r(this, "updateMediaElementEventHandlers", (t) => {
- var o;
- const e = (o = this.currentHlsInstance) == null ? void 0 : o.media;
+ a(this, "core");
+ a(this, "segmentManager");
+ a(this, "hlsInstanceGetter");
+ a(this, "currentHlsInstance");
+ a(this, "debug", N("p2pml-hlsjs:engine"));
+ a(this, "updateMediaElementEventHandlers", (t) => {
+ var r;
+ const e = (r = this.currentHlsInstance) == null ? void 0 : r.media;
if (!e) return;
const s = t === "register" ? "addEventListener" : "removeEventListener";
e[s]("timeupdate", this.handlePlaybackUpdate), e[s]("seeking", this.handlePlaybackUpdate), e[s]("ratechange", this.handlePlaybackUpdate);
});
- r(this, "handleManifestLoaded", (t, e) => {
+ a(this, "handleManifestLoaded", (t, e) => {
const s = e.networkDetails;
s instanceof XMLHttpRequest ? this.core.setManifestResponseUrl(s.responseURL) : s instanceof Response && this.core.setManifestResponseUrl(s.url), this.segmentManager.processMainManifest(e);
});
- r(this, "handleLevelSwitching", (t, e) => {
+ a(this, "handleLevelSwitching", (t, e) => {
e.bitrate && this.core.setActiveLevelBitrate(e.bitrate);
});
- r(this, "handleLevelUpdated", (t, e) => {
- this.currentHlsInstance && this.currentHlsInstance.config.liveSyncDurationCount !== e.details.fragments.length - 1 && e.details.live && e.details.fragments[0].type === "main" && !this.currentHlsInstance.userConfig.liveSyncDuration && !this.currentHlsInstance.userConfig.liveSyncDurationCount && e.details.fragments.length > 4 && (this.debug("set liveSyncDurationCount " + (e.details.fragments.length - 1)), this.currentHlsInstance.config.liveSyncDurationCount = e.details.fragments.length - 1), this.core.setIsLive(e.details.live), this.segmentManager.updatePlaylist(e);
+ a(this, "handleLevelUpdated", (t, e) => {
+ this.currentHlsInstance && e.details.live && e.details.fragments[0].type === "main" && !this.currentHlsInstance.userConfig.liveSyncDuration && !this.currentHlsInstance.userConfig.liveSyncDurationCount && e.details.fragments.length > 4 && this.updateLiveSyncDurationCount(e), this.core.setIsLive(e.details.live), this.segmentManager.updatePlaylist(e);
});
- r(this, "handleMediaAttached", () => {
+ a(this, "handleMediaAttached", () => {
this.updateMediaElementEventHandlers("register");
});
- r(this, "handleMediaDetached", () => {
+ a(this, "handleMediaDetached", () => {
this.updateMediaElementEventHandlers("unregister");
});
- r(this, "handlePlaybackUpdate", (t) => {
+ a(this, "handlePlaybackUpdate", (t) => {
const e = t.target;
this.core.updatePlayback(e.currentTime, e.playbackRate);
});
- r(this, "destroyCore", () => this.core.destroy());
- r(this, "destroy", () => {
+ a(this, "destroyCore", () => this.core.destroy());
+ a(this, "destroy", () => {
this.destroyCore(), this.updateHlsEventsHandlers("unregister"), this.updateMediaElementEventHandlers("unregister"), this.currentHlsInstance = void 0;
});
this.core = new z(t == null ? void 0 : t.core), this.segmentManager = new K(this.core);
}
static injectMixin(t) {
- var s, o;
- return e = t, o = class extends e {
- constructor(...a) {
- var L;
- const E = a[0], { p2p: h, ...f } = E ?? {}, c = new $(h);
+ var s, r;
+ return e = t, r = class extends e {
+ constructor(...o) {
+ var b;
+ const E = o[0], { p2p: h, ...f } = E ?? {}, c = new G(h);
super({ ...f, ...c.getConfigForHlsJs() });
l(this, s);
- c.bindHls(this), u(this, s, c), (L = h == null ? void 0 : h.onHlsJsCreated) == null || L.call(h, this);
+ c.bindHls(this), u(this, s, c), (b = h == null ? void 0 : h.onHlsJsCreated) == null || b.call(h, this);
}
get p2pEngine() {
return i(this, s);
}
- }, s = new WeakMap(), o;
+ }, s = new WeakMap(), r;
var e;
}
addEventListener(t, e) {
@@ -191,6 +191,10 @@ class $ {
const s = t === "register" ? "on" : "off";
e[s]("hlsManifestLoaded", this.handleManifestLoaded), e[s]("hlsLevelSwitching", this.handleLevelSwitching), e[s]("hlsLevelUpdated", this.handleLevelUpdated), e[s]("hlsAudioTrackLoaded", this.handleLevelUpdated), e[s]("hlsDestroying", this.destroy), e[s]("hlsMediaAttaching", this.destroyCore), e[s]("hlsManifestLoading", this.destroyCore), e[s]("hlsMediaDetached", this.handleMediaDetached), e[s]("hlsMediaAttached", this.handleMediaAttached);
}
+ updateLiveSyncDurationCount(t) {
+ const e = t.details.targetduration, s = Math.floor(120 / e), r = Math.min(t.details.fragments.length - 1, s);
+ this.currentHlsInstance && this.currentHlsInstance.config.liveSyncDurationCount !== r && (this.debug(`Setting liveSyncDurationCount to ${r}`), this.currentHlsInstance.config.liveSyncDurationCount = r);
+ }
createFragmentLoaderClass() {
const { core: t } = this, e = this;
return class extends B {
@@ -212,6 +216,6 @@ class $ {
}
}
export {
- $ as HlsJsP2PEngine
+ G as HlsJsP2PEngine
};
//# sourceMappingURL=p2p-media-loader-hlsjs.es.min.js.map